go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/run/impl/handler/handler.go (about) 1 // Copyright 2021 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package handler 16 17 import ( 18 "context" 19 "time" 20 21 "go.chromium.org/luci/server/quota/quotapb" 22 23 cfgpb "go.chromium.org/luci/cv/api/config/v2" 24 "go.chromium.org/luci/cv/internal/changelist" 25 "go.chromium.org/luci/cv/internal/common" 26 "go.chromium.org/luci/cv/internal/common/eventbox" 27 "go.chromium.org/luci/cv/internal/common/tree" 28 "go.chromium.org/luci/cv/internal/gerrit" 29 "go.chromium.org/luci/cv/internal/run" 30 "go.chromium.org/luci/cv/internal/run/bq" 31 "go.chromium.org/luci/cv/internal/run/eventpb" 32 "go.chromium.org/luci/cv/internal/run/impl/state" 33 "go.chromium.org/luci/cv/internal/run/pubsub" 34 "go.chromium.org/luci/cv/internal/run/rdb" 35 "go.chromium.org/luci/cv/internal/tryjob" 36 ) 37 38 // Result is the result of handling the events. 39 type Result struct { 40 // State is the new RunState after handling the events. 41 State *state.RunState 42 // SideEffectFn is called in a transaction to atomically transition the 43 // RunState to the new state and perform side effect. 44 SideEffectFn eventbox.SideEffectFn 45 // PreserveEvents, if true, instructs RunManager not to consume the events 46 // during state transition. 47 PreserveEvents bool 48 // PostProcessFn is executed by the eventbox user after event processing 49 // completes. 50 PostProcessFn eventbox.PostProcessFn 51 } 52 53 // Handler is an interface that handles events that RunManager receives. 54 type Handler interface { 55 // Start starts a Run. 56 Start(context.Context, *state.RunState) (*Result, error) 57 58 // Cancel cancels a Run. 59 Cancel(context.Context, *state.RunState, []string) (*Result, error) 60 61 // OnCLsUpdated decides whether to cancel a Run based on changes to the CLs. 62 OnCLsUpdated(context.Context, *state.RunState, common.CLIDs) (*Result, error) 63 64 // UpdateConfig updates Run's config if possible. 65 // 66 // If Run is no longer viable, cancels the Run. 67 UpdateConfig(context.Context, *state.RunState, string) (*Result, error) 68 69 // OnReadyForSubmission acquires a slot in Submit Queue and makes sure this 70 // Run is not currently being submitted by another RM task. If all succeeded, 71 // returns a PostProcessFn for submission. 72 OnReadyForSubmission(context.Context, *state.RunState) (*Result, error) 73 74 // OnCLsSubmitted records provided CLs have been submitted. 75 OnCLsSubmitted(context.Context, *state.RunState, common.CLIDs) (*Result, error) 76 77 // OnSubmissionCompleted acts on the submission result. 78 // 79 // If submission succeeds, mark run as `SUCCEEDED`. Otherwise, decides whether 80 // to retry submission or fail the run depending on the submission result. 81 OnSubmissionCompleted(ctx context.Context, rs *state.RunState, sc *eventpb.SubmissionCompleted) (*Result, error) 82 83 // OnLongOpCompleted processes results of the completed long operation. 84 OnLongOpCompleted(ctx context.Context, rs *state.RunState, result *eventpb.LongOpCompleted) (*Result, error) 85 86 // OnTryjobsUpdated decides the next step for the given tryjobs and the run. 87 OnTryjobsUpdated(context.Context, *state.RunState, common.TryjobIDs) (*Result, error) 88 89 // TryResumeSubmission resumes not-yet-expired submission if the current task 90 // is a retry of the submission task. 91 // 92 // Fail the Run if the submission deadline has been exceeded. 93 TryResumeSubmission(context.Context, *state.RunState) (*Result, error) 94 95 // Poke checks current Run state and takes actions to progress the Run. 96 Poke(context.Context, *state.RunState) (*Result, error) 97 98 // OnParentRunCompleted checks decides how to handle the run based on its completed parent run. 99 OnParentRunCompleted(context.Context, *state.RunState) (*Result, error) 100 } 101 102 // PM encapsulates interaction with Project Manager by the Run events handler. 103 type PM interface { 104 NotifyRunFinished(ctx context.Context, runID common.RunID, status run.Status) error 105 NotifyCLsUpdated(ctx context.Context, luciProject string, cls *changelist.CLUpdatedEvents) error 106 } 107 108 // RM encapsulates interaction with Run Manager by the Run events handler. 109 type RM interface { 110 Invoke(ctx context.Context, runID common.RunID, eta time.Time) error 111 PokeAfter(ctx context.Context, runID common.RunID, after time.Duration) error 112 NotifyReadyForSubmission(ctx context.Context, runID common.RunID, eta time.Time) error 113 NotifyCLsSubmitted(ctx context.Context, runID common.RunID, clids common.CLIDs) error 114 NotifySubmissionCompleted(ctx context.Context, runID common.RunID, sc *eventpb.SubmissionCompleted, invokeRM bool) error 115 Start(ctx context.Context, runID common.RunID) error 116 NotifyParentRunCompleted(ctx context.Context, runID common.RunID) error 117 } 118 119 // QM manages run and tryjob quotas. 120 type QM interface { 121 DebitRunQuota(ctx context.Context, r *run.Run) (*quotapb.OpResult, *cfgpb.UserLimit, error) 122 } 123 124 // CLUpdater encapsulates interaction with CL Updater by the Run events handler. 125 type CLUpdater interface { 126 ScheduleBatch(ctx context.Context, luciProject string, cls []*changelist.CL, requester changelist.UpdateCLTask_Requester) error 127 } 128 129 // TryjobNotifier encapsulates interaction with Tryjob components by the Run 130 // events handler. 131 type TryjobNotifier interface { 132 ScheduleUpdate(ctx context.Context, id common.TryjobID, eid tryjob.ExternalID) error 133 } 134 135 // Impl is a prod implementation of Handler interface. 136 type Impl struct { 137 PM PM 138 RM RM 139 TN TryjobNotifier 140 QM QM 141 GFactory gerrit.Factory 142 CLUpdater CLUpdater 143 CLMutator *changelist.Mutator 144 BQExporter *bq.Exporter 145 RdbNotifier *rdb.Notifier 146 TreeClient tree.Client 147 Publisher *pubsub.Publisher 148 Env *common.Env 149 } 150 151 var _ Handler = (*Impl)(nil)