Fix race condition

This commit is contained in:
simon987 2019-03-01 22:48:09 -05:00
parent 840a4173bb
commit 13290d3c55
2 changed files with 36 additions and 29 deletions

View File

@ -7,6 +7,7 @@ import (
"github.com/simon987/task_tracker/config" "github.com/simon987/task_tracker/config"
"io/ioutil" "io/ioutil"
"os" "os"
"sync"
) )
type Database struct { type Database struct {
@ -14,12 +15,14 @@ type Database struct {
saveTaskStmt *sql.Stmt saveTaskStmt *sql.Stmt
workerCache map[int64]*Worker workerCache map[int64]*Worker
assignMutex *sync.Mutex
} }
func New() *Database { func New() *Database {
d := Database{} d := Database{}
d.workerCache = make(map[int64]*Worker) d.workerCache = make(map[int64]*Worker)
d.assignMutex = &sync.Mutex{}
d.init() d.init()

View File

@ -106,31 +106,32 @@ func (database *Database) GetTaskFromProject(worker *Worker, projectId int64) *T
db := database.getDB() db := database.getDB()
database.assignMutex.Lock()
row := db.QueryRow(` row := db.QueryRow(`
UPDATE task UPDATE task
SET assignee=$1, assign_time=extract(epoch from now() at time zone 'utc') SET assignee=$1, assign_time=extract(epoch from now() at time zone 'utc')
WHERE id IN WHERE task.id = (
(
SELECT task.id SELECT task.id
FROM task FROM task
INNER JOIN project on task.project = project.id INNER JOIN project on task.project = project.id AND project.id=$2 AND not paused
LEFT JOIN worker_verifies_task wvt on task.id = wvt.task AND wvt.worker=$1 LEFT JOIN worker_verifies_task wvt on task.id = wvt.task AND wvt.worker=$1
WHERE NOT project.paused AND assignee IS NULL AND project.id=$2 AND status=1 LEFT JOIN worker_access wa on project.id = wa.project AND wa.worker=$1
AND (project.public OR ( WHERE
SELECT a.role_assign and not a.request FROM worker_access a WHERE a.worker=$1 AND a.project=$2 assignee IS NULL
)) AND status=1
AND (project.public OR (wa.role_assign AND NOT request))
AND wvt.task IS NULL AND wvt.task IS NULL
ORDER BY task.priority DESC ORDER BY task.priority DESC
LIMIT 1 LIMIT 1
) )
RETURNING id`, worker.Id, projectId) RETURNING task.id`, worker.Id, projectId)
var id int64
var id int64
err := row.Scan(&id) err := row.Scan(&id)
if err != nil { if err != nil {
logrus.WithFields(logrus.Fields{ database.assignMutex.Unlock()
"worker": worker,
}).Trace("No task available")
return nil return nil
} }
@ -142,6 +143,9 @@ func (database *Database) GetTaskFromProject(worker *Worker, projectId int64) *T
FROM task FROM task
INNER JOIN project project ON task.project = project.id INNER JOIN project project ON task.project = project.id
WHERE task.id=$1`, id) WHERE task.id=$1`, id)
database.assignMutex.Unlock()
project := &Project{} project := &Project{}
task := &Task{} task := &Task{}
task.Project = project task.Project = project