secure addJob with mutex

This commit is contained in:
Pay Giesselmann 2022-11-24 14:28:19 +01:00
parent e00e3208ca
commit e4a1422e05

View File

@ -57,6 +57,7 @@ type RestApi struct {
Authentication *auth.Authentication Authentication *auth.Authentication
MachineStateDir string MachineStateDir string
OngoingArchivings sync.WaitGroup OngoingArchivings sync.WaitGroup
RepositoryMutex sync.Mutex
} }
func (api *RestApi) MountRoutes(r *mux.Router) { func (api *RestApi) MountRoutes(r *mux.Router) {
@ -362,6 +363,11 @@ func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
return return
} }
// aquire lock to avoid race condition between API calls
var unlockOnce sync.Once
api.RepositoryMutex.Lock()
defer unlockOnce.Do(api.RepositoryMutex.Unlock)
// Check if combination of (job_id, cluster_id, start_time) already exists: // Check if combination of (job_id, cluster_id, start_time) already exists:
jobs, err := api.JobRepository.FindAll(&req.JobID, &req.Cluster, nil) jobs, err := api.JobRepository.FindAll(&req.JobID, &req.Cluster, nil)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
@ -381,6 +387,8 @@ func (api *RestApi) startJob(rw http.ResponseWriter, r *http.Request) {
handleError(fmt.Errorf("insert into database failed: %w", err), http.StatusInternalServerError, rw) handleError(fmt.Errorf("insert into database failed: %w", err), http.StatusInternalServerError, rw)
return return
} }
// unlock here, adding Tags can be async
unlockOnce.Do(api.RepositoryMutex.Unlock)
for _, tag := range req.Tags { for _, tag := range req.Tags {
if _, err := api.JobRepository.AddTagOrCreate(id, tag.Type, tag.Name); err != nil { if _, err := api.JobRepository.AddTagOrCreate(id, tag.Type, tag.Name); err != nil {