func (s *Store) Clean(inactive time.Duration) error { locker.Lock("clean") defer locker.Unlock("clean") rows, err := s.Query(` SELECT id, value FROM `+SqlTableName+` WHERE key = $1 `, SessionLastUpdated) if err != nil { return err } defer rows.Close() cutoff := time.Now().UTC().Add(-inactive) for rows.Next() { var id []byte var last string if err := rows.Scan(&id, &last); err != nil { return err } lastUp, err := time.Parse(time.RFC3339Nano, last) if err != nil { return err } if lastUp.Before(cutoff) { _, err = s.Exec( "DELETE FROM "+SqlTableName+" WHERE id = $1", id) if err != nil { return err } } } return rows.Err() }
func manageCollaborators(w *web) { var form struct { ProjectName string Collaborators []string } w.decode(&form) proj := getProject(w.user, w.user.Id, form.ProjectName) // We need to do a delete followed by an insert, which means we need // exclusion for this project to prevent race conditions. lockKey := fmt.Sprintf("%s-%s", proj.Name, proj.Owner.Id) locker.Lock(lockKey) defer locker.Unlock(lockKey) csql.Tx(db, func(tx *sql.Tx) { csql.Exec(tx, ` DELETE FROM collaborator WHERE project_owner = $1 AND project_name = $2 `, proj.Owner.Id, proj.Name) for _, collaborator := range form.Collaborators { u := findUserById(collaborator) csql.Exec(tx, ` INSERT INTO collaborator (project_owner, project_name, userid) VALUES ($1, $2, $3) `, proj.Owner.Id, proj.Name, u.Id) } }) w.json(w.r.PostForm) }
// Set associates the plain text password given with the user that is uniquely // identified by id. The password is hashed with bcrypt. If there is a problem // with hashing or with storing the password, an error is returned. // // This may be called on a new user. func (s *Store) Set(id, password string) (cerr error) { defer csql.Safe(&cerr) hash, err := bcrypt.GenerateFromPassword( []byte(password), bcrypt.DefaultCost) if err != nil { return err } // This lock can be avoided if we use some sort of upsert. // It's possible with Postgres, but this is just way easier. locker.Lock(id) defer locker.Unlock(id) n := csql.Count(s, ` SELECT COUNT(*) FROM `+SqlTableName+` WHERE id = $1 `, id) if n == 0 { csql.Exec(s, ` INSERT INTO `+SqlTableName+` (id, hash) VALUES ($1, $2) `, id, hash) } else { csql.Exec(s, ` UPDATE `+SqlTableName+` SET id = $1, hash = $2 WHERE id = $1 `, id, hash) } return nil }
func Lock(sess *sessions.Session) { locker.Lock(sess.ID) }
func (user *lcmUser) lock() { locker.Lock(user.Id) }