@@ -34,10 +34,11 @@ type ActionRunJob struct {
3434 TaskID int64 // the latest task of the job
3535 Status Status `xorm:"index"`
3636
37- RawConcurrencyGroup string // raw concurrency.group
38- RawConcurrencyCancel string // raw concurrency.cancel-in-progress
39- ConcurrencyGroup string // evaluated concurrency.group
40- ConcurrencyCancel bool // evaluated concurrency.cancel-in-progress
37+ RawConcurrencyGroup string // raw concurrency.group
38+ RawConcurrencyCancel string // raw concurrency.cancel-in-progress
39+ IsConcurrencyEvaluated bool // whether RawConcurrencyGroup have been evaluated, only valid when RawConcurrencyGroup is not empty
40+ ConcurrencyGroup string // evaluated concurrency.group
41+ ConcurrencyCancel bool // evaluated concurrency.cancel-in-progress
4142
4243 Started timeutil.TimeStamp
4344 Stopped timeutil.TimeStamp
@@ -190,3 +191,47 @@ func AggregateJobStatus(jobs []*ActionRunJob) Status {
190191 return StatusUnknown // it shouldn't happen
191192 }
192193}
194+
195+ func ShouldJobBeBlockedByConcurrentJobs (ctx context.Context , actionRunJob * ActionRunJob ) (bool , error ) {
196+ if len (actionRunJob .RawConcurrencyGroup ) == 0 {
197+ return false , nil
198+ }
199+ if ! actionRunJob .IsConcurrencyEvaluated {
200+ return false , fmt .Errorf ("the raw concurrency group has not been evaluated" )
201+ }
202+ if len (actionRunJob .ConcurrencyGroup ) == 0 {
203+ return false , nil
204+ }
205+ if actionRunJob .ConcurrencyCancel {
206+ return false , CancelConcurrentJobs (ctx , actionRunJob )
207+ }
208+
209+ concurrentJobsNum , err := db .Count [ActionRunJob ](ctx , FindRunJobOptions {
210+ RepoID : actionRunJob .RepoID ,
211+ ConcurrencyGroup : actionRunJob .ConcurrencyGroup ,
212+ Statuses : []Status {StatusRunning , StatusWaiting },
213+ })
214+ if err != nil {
215+ return false , fmt .Errorf ("count waiting jobs: %w" , err )
216+ }
217+
218+ return concurrentJobsNum > 0 , nil
219+ }
220+
221+ func CancelConcurrentJobs (ctx context.Context , actionRunJob * ActionRunJob ) error {
222+ // cancel previous jobs in the same concurrency group
223+ previousJobs , err := db .Find [ActionRunJob ](ctx , FindRunJobOptions {
224+ RepoID : actionRunJob .RepoID ,
225+ ConcurrencyGroup : actionRunJob .ConcurrencyGroup ,
226+ Statuses : []Status {
227+ StatusRunning ,
228+ StatusWaiting ,
229+ StatusBlocked ,
230+ },
231+ })
232+ if err != nil {
233+ return fmt .Errorf ("find previous jobs: %w" , err )
234+ }
235+
236+ return CancelJobs (ctx , previousJobs )
237+ }
0 commit comments