go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/prjmanager/triager/triage.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 triager 16 17 import ( 18 "context" 19 "fmt" 20 "time" 21 22 "google.golang.org/protobuf/types/known/timestamppb" 23 24 "go.chromium.org/luci/cv/internal/prjmanager/itriager" 25 "go.chromium.org/luci/cv/internal/prjmanager/prjpb" 26 ) 27 28 // Triage triages a component with 1+ CLs deciding what has to be done now and 29 // when should the next re-Triage happen. 30 // 31 // Meets the `itriager.Triage` requirements. 32 func Triage(ctx context.Context, c *prjpb.Component, s itriager.PMState) (itriager.Result, error) { 33 pm := pmState{s} 34 res := itriager.Result{} 35 var nextPurge, nextRun time.Time 36 var err error 37 38 cls := triageCLs(ctx, c, pm) 39 res.RunsToCreate, nextRun, err = stageNewRuns(ctx, c, cls, pm) 40 if err != nil { 41 return res, err 42 } 43 res.CLsToPurge, nextPurge = stagePurges(ctx, cls, pm) 44 res.CLsToTriggerDeps = stageTriggerCLDeps(ctx, cls, pm) 45 46 if len(res.RunsToCreate) > 0 || len(res.CLsToPurge) > 0 || len(res.CLsToTriggerDeps) > 0 { 47 res.NewValue = c.CloneShallow() 48 res.NewValue.TriageRequired = false 49 // Wait for any of Run creation, CL purging, or CL triggering to finish, 50 // which will result in a re-Triage. 51 res.NewValue.DecisionTime = nil 52 return res, nil 53 } 54 55 next := earliest(nextPurge, nextRun) 56 if c.GetTriageRequired() || !isSameTime(next, c.GetDecisionTime()) { 57 res.NewValue = c.CloneShallow() 58 res.NewValue.TriageRequired = false 59 res.NewValue.DecisionTime = nil 60 if !next.IsZero() { 61 res.NewValue.DecisionTime = timestamppb.New(next) 62 } 63 } 64 return res, nil 65 } 66 67 type pmState struct { 68 itriager.PMState 69 } 70 71 // MustPCL panics if clid doesn't exist. 72 // 73 // Exists primarily for readability. 74 func (pm pmState) MustPCL(clid int64) *prjpb.PCL { 75 if p := pm.PCL(clid); p != nil { 76 return p 77 } 78 panic(fmt.Errorf("MustPCL: clid %d not known", clid)) 79 }