mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-23 16:44:41 +02:00
perf(actions): batch per-row queries in run, job and cancellation paths (#39723)
Several Actions code paths issued one or more queries per listed row. They now load in batch, with unchanged output. - API job list: tasks, steps and runners load in batch - API run list: latest attempts and their trigger users load in batch - Repository runs page: the jobs of all active runs load in one query - Cancelling previous runs and replacing concurrency group entries fetch their jobs in one query Per call with 50 rows on SQLite, base vs head: | Path | Queries | Time | | --- | --- | --- | | API job list | 254 → 6 | 12.9 → 1.9 ms | | API run list | 305 → 207 | 11.7 → 6.2 ms | | Runs page job loading | 100 → 1 | 6.5 → 0.47 ms | | `CancelPreviousJobs` | 546 → 496 | ~120 ms, per-job writes dominate | The remaining run list queries come from per-run repository conversion, which this PR doesn't change. --------- Co-authored-by: Zettat123 <zettat123@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
10 files changed
+241
-121
No files matched your search
@@ -90,27 +90,16 @@ func ListJobs(ctx *context.APIContext, ownerID, repoID, runID int64, runAttemptI
|
||||
return
|
||||
}
|
||||
|
||||
res.Entries = make([]*api.ActionWorkflowJob, len(jobs))
|
||||
|
||||
isRepoLevel := repoID != 0 && ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == repoID
|
||||
for i := range jobs {
|
||||
var repository *repo_model.Repository
|
||||
if isRepoLevel {
|
||||
repository = ctx.Repo.Repository
|
||||
} else {
|
||||
if jobs[i].Run == nil || jobs[i].Run.Repo == nil {
|
||||
ctx.APIErrorInternal(fmt.Errorf("job %d is missing its run or repository", jobs[i].ID))
|
||||
return
|
||||
}
|
||||
repository = jobs[i].Run.Repo
|
||||
}
|
||||
|
||||
convertedWorkflowJob, err := convert.ToActionWorkflowJob(ctx, repository, nil, jobs[i])
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
for _, job := range jobs {
|
||||
if job.Run == nil || job.Run.Repo == nil {
|
||||
ctx.APIErrorInternal(fmt.Errorf("job %d is missing its run or repository", job.ID))
|
||||
return
|
||||
}
|
||||
res.Entries[i] = convertedWorkflowJob
|
||||
}
|
||||
res.Entries, err = convert.ToActionWorkflowJobs(ctx, jobs)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.SetLinkHeader(total, listOptions.PageSize)
|
||||
ctx.SetTotalCountHeader(total)
|
||||
@@ -224,6 +213,12 @@ func ListRuns(ctx *context.APIContext, ownerID, repoID int64, workflowID string)
|
||||
return
|
||||
}
|
||||
|
||||
latestAttempts, err := runList.GetLatestAttempts(ctx)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
|
||||
res.Entries = make([]*api.ActionWorkflowRun, 0, len(runs))
|
||||
for _, run := range runs {
|
||||
if run.Repo == nil {
|
||||
@@ -232,8 +227,7 @@ func ListRuns(ctx *context.APIContext, ownerID, repoID int64, workflowID string)
|
||||
total--
|
||||
continue
|
||||
}
|
||||
// TODO: load run attempts in batch
|
||||
convertedRun, err := convert.ToActionWorkflowRun(ctx, run, nil, excludePullRequests)
|
||||
convertedRun, err := convert.ToActionWorkflowRun(ctx, run, latestAttempts[run.LatestAttemptID], excludePullRequests)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
Reference in new issue
Block a user