1
Fork 0

Add optimistic lock to ActionRun table (#26563)

Should fix #26559.

How xorm works: https://xorm.io/docs/chapter-06/1.lock/

---------

Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
Jason Song 2023-08-21 22:07:52 +08:00 committed by GitHub
parent 42cbe6005a
commit 8cf3b61fb9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 25 deletions

View file

@ -114,32 +114,41 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
if affected != 0 && util.SliceContains(cols, "status") && job.Status.IsWaiting() {
// if the status of job changes to waiting again, increase tasks version.
if err := IncreaseTaskVersion(ctx, job.OwnerID, job.RepoID); err != nil {
return affected, err
return 0, err
}
}
if job.RunID == 0 {
var err error
if job, err = GetRunJobByID(ctx, job.ID); err != nil {
return affected, err
return 0, err
}
}
jobs, err := GetRunJobsByRunID(ctx, job.RunID)
if err != nil {
return affected, err
{
// Other goroutines may aggregate the status of the run and update it too.
// So we need load the run and its jobs before updating the run.
run, err := GetRunByID(ctx, job.RunID)
if err != nil {
return 0, err
}
jobs, err := GetRunJobsByRunID(ctx, job.RunID)
if err != nil {
return 0, err
}
run.Status = aggregateJobStatus(jobs)
if run.Started.IsZero() && run.Status.IsRunning() {
run.Started = timeutil.TimeStampNow()
}
if run.Stopped.IsZero() && run.Status.IsDone() {
run.Stopped = timeutil.TimeStampNow()
}
if err := UpdateRun(ctx, run, "status", "started", "stopped"); err != nil {
return 0, fmt.Errorf("update run %d: %w", run.ID, err)
}
}
runStatus := aggregateJobStatus(jobs)
run := &ActionRun{
ID: job.RunID,
Status: runStatus,
}
if runStatus.IsDone() {
run.Stopped = timeutil.TimeStampNow()
}
return affected, UpdateRun(ctx, run)
return affected, nil
}
func aggregateJobStatus(jobs []*ActionRunJob) Status {