diff options
author | sillyguodong <33891828+sillyguodong@users.noreply.github.com> | 2023-07-24 14:11:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-24 06:11:27 +0000 |
commit | f5c7d4cfddfe7fc615199a7438749ed79c40361f (patch) | |
tree | 10f29b006b8325519fcfc7b31e3d63ed0b1fee7d /routers | |
parent | 674df05b16f396bf6f2a952923b9c2dfe371415b (diff) | |
download | gitea-f5c7d4cfddfe7fc615199a7438749ed79c40361f.tar.gz gitea-f5c7d4cfddfe7fc615199a7438749ed79c40361f.zip |
Reduce unnecessary DB queries for Actions tasks (#25199)
Close #24544
Changes:
- Create `action_tasks_version` table to store the latest version of
each scope (global, org and repo).
- When a job with the status of `waiting` is created, the tasks version
of the scopes it belongs to will increase.
- When the status of a job already in the database is updated to
`waiting`, the tasks version of the scopes it belongs to will increase.
- On Gitea side, in `FeatchTask()`, will try to query the
`action_tasks_version` record of the scope of the runner that call
`FetchTask()`. If the record does not exist, will insert a row. Then,
Gitea will compare the version passed from runner to Gitea with the
version in database, if inconsistent, try pick task. Gitea always
returns the latest version from database to the runner.
Related:
- Protocol: https://gitea.com/gitea/actions-proto-def/pulls/10
- Runner: https://gitea.com/gitea/act_runner/pulls/219
Diffstat (limited to 'routers')
-rw-r--r-- | routers/api/actions/runner/runner.go | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go index 17801cb322..6de5964cb7 100644 --- a/routers/api/actions/runner/runner.go +++ b/routers/api/actions/runner/runner.go @@ -127,20 +127,39 @@ func (s *Service) Declare( // FetchTask assigns a task to the runner func (s *Service) FetchTask( ctx context.Context, - _ *connect.Request[runnerv1.FetchTaskRequest], + req *connect.Request[runnerv1.FetchTaskRequest], ) (*connect.Response[runnerv1.FetchTaskResponse], error) { runner := GetRunner(ctx) var task *runnerv1.Task - if t, ok, err := pickTask(ctx, runner); err != nil { - log.Error("pick task failed: %v", err) - return nil, status.Errorf(codes.Internal, "pick task: %v", err) - } else if ok { - task = t + tasksVersion := req.Msg.TasksVersion // task version from runner + latestVersion, err := actions_model.GetTasksVersionByScope(ctx, runner.OwnerID, runner.RepoID) + if err != nil { + return nil, status.Errorf(codes.Internal, "query tasks version failed: %v", err) + } else if latestVersion == 0 { + if err := actions_model.IncreaseTaskVersion(ctx, runner.OwnerID, runner.RepoID); err != nil { + return nil, status.Errorf(codes.Internal, "fail to increase task version: %v", err) + } + // if we don't increase the value of `latestVersion` here, + // the response of FetchTask will return tasksVersion as zero. + // and the runner will treat it as an old version of Gitea. + latestVersion++ } + if tasksVersion != latestVersion { + // if the task version in request is not equal to the version in db, + // it means there may still be some tasks not be assgined. + // try to pick a task for the runner that send the request. + if t, ok, err := pickTask(ctx, runner); err != nil { + log.Error("pick task failed: %v", err) + return nil, status.Errorf(codes.Internal, "pick task: %v", err) + } else if ok { + task = t + } + } res := connect.NewResponse(&runnerv1.FetchTaskResponse{ - Task: task, + Task: task, + TasksVersion: latestVersion, }) return res, nil } |