go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/cv/internal/prjmanager/prjpb/triggerdeps.go (about) 1 // Copyright 2023 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 prjpb 16 17 import ( 18 "sort" 19 "time" 20 21 "go.chromium.org/luci/cv/internal/prjmanager/copyonwrite" 22 ) 23 24 // MaxTriggeringCLDepsDuration limits the time that a TQ task has to execute 25 // a given TrigggeringCLDesp task. 26 // 27 // Once the deadline is exceeded, PM will will remove the task from PStat 28 // to retriage the CL and see if it has to reschedule another TriggeringCLDeps 29 // for the CL with its deps. 30 const MaxTriggeringCLDepsDuration = 8 * time.Minute 31 32 // COWTriggeringCLDeps copy-on-write modifies TriggeringCLDeps. 33 func (p *PState) COWTriggeringCLDeps(m func(*TriggeringCLDeps) *TriggeringCLDeps, toAdd []*TriggeringCLDeps) ([]*TriggeringCLDeps, bool) { 34 in := cowTriggeringCLDeps(p.GetTriggeringClDeps()) 35 out, updated := copyonwrite.Update(in, triggerCLDepsModifier(m), cowTriggeringCLDeps(toAdd)) 36 return []*TriggeringCLDeps(out.(cowTriggeringCLDeps)), updated 37 } 38 39 // GetTriggeringCLDeps returns the TriggeringCLDeps of a given origin clid. 40 // 41 // Returns nil, if not found. 42 func (p *PState) GetTriggeringCLDeps(clid int64) *TriggeringCLDeps { 43 items := p.GetTriggeringClDeps() 44 idx := sort.Search(len(items), func(i int) bool { 45 return items[i].GetOriginClid() >= clid 46 }) 47 if idx >= len(items) || items[idx].GetOriginClid() != clid { 48 return nil 49 } 50 return items[idx] 51 } 52 53 func triggerCLDepsModifier(f func(*TriggeringCLDeps) *TriggeringCLDeps) copyonwrite.Modifier { 54 if f == nil { 55 return nil 56 } 57 return func(v any) any { 58 if v := f(v.(*TriggeringCLDeps)); v != nil { 59 return v 60 } 61 return copyonwrite.Deletion 62 } 63 } 64 65 type cowTriggeringCLDeps []*TriggeringCLDeps 66 67 // It's important that TriggeringCLDeps are always sorted. 68 var _ copyonwrite.SortedSlice = cowTriggeringCLDeps(nil) 69 70 func (c cowTriggeringCLDeps) At(index int) any { 71 return c[index] 72 } 73 74 func (c cowTriggeringCLDeps) Append(v any) copyonwrite.Slice { 75 return append(c, v.(*TriggeringCLDeps)) 76 } 77 78 func (c cowTriggeringCLDeps) CloneShallow(length int, capacity int) copyonwrite.Slice { 79 r := make(cowTriggeringCLDeps, length, capacity) 80 copy(r, c[:length]) 81 return r 82 } 83 84 func (c cowTriggeringCLDeps) LessElements(a any, b any) bool { 85 return a.(*TriggeringCLDeps).GetOriginClid() < b.(*TriggeringCLDeps).GetOriginClid() 86 } 87 88 func (c cowTriggeringCLDeps) Len() int { 89 return len(c) 90 } 91 92 func (c cowTriggeringCLDeps) Less(i int, j int) bool { 93 return c[i].GetOriginClid() < c[j].GetOriginClid() 94 } 95 func (c cowTriggeringCLDeps) Swap(i int, j int) { 96 c[i], c[j] = c[j], c[i] 97 }