@@ -29,6 +29,7 @@ type ProviderOpts struct {
29
29
StabilizeDuration time.Duration
30
30
TTL time.Duration
31
31
ExpectedRequestCount int
32
+ DelayAssignmentCount int
32
33
ID string
33
34
Clock clock.PassiveClock
34
35
Storage storage.Storage [* ProviderState ]
@@ -46,11 +47,12 @@ const (
46
47
)
47
48
48
49
type Request struct {
49
- HeadSHA string `json:"head_sha"`
50
- HeadRef string `json:"head_ref"`
51
- Priority int `json:"priority"`
52
- Status * string `json:"status,omitempty"`
53
- lastSeenAt * time.Time
50
+ HeadSHA string `json:"head_sha"`
51
+ HeadRef string `json:"head_ref"`
52
+ Priority int `json:"priority"`
53
+ Status * string `json:"status,omitempty"`
54
+ lastSeenAt * time.Time
55
+ acquireCountdown * int
54
56
}
55
57
56
58
type StackedPullRequest struct {
@@ -75,6 +77,7 @@ func (lr *Request) MarshalZerologObject(e *zerolog.Event) {
75
77
e .Str ("lease_request_head_sha" , lr .HeadSHA ).
76
78
Str ("lease_request_head_ref" , lr .HeadRef ).
77
79
Int ("lease_request_priority" , lr .Priority ).
80
+ Int ("lease_request_acquire_countdown" , pointer .IntDeref (lr .acquireCountdown , 0 )).
78
81
Str ("lease_request_status" , status )
79
82
}
80
83
@@ -457,12 +460,27 @@ func (lp *leaseProviderImpl) evaluateRequest(ctx context.Context, req *Request)
457
460
458
461
// Got the max priority, now check if we are the winner
459
462
if req .Priority == maxPriority {
460
- req .Status = pointer .String (StatusAcquired )
461
- lp .state .acquired = req
463
+
464
+ // In order to prevent race conditions, there's the option to delay the lock acquisition
465
+ // This is useful when the lock is acquired by a CI job that is canceled or restarted. There can be a short delay.
466
+ req .acquireCountdown = pointer .Int (pointer .IntDeref (req .acquireCountdown , lp .opts .DelayAssignmentCount + 1 ) - 1 )
467
+ if * req .acquireCountdown > 0 {
468
+ log .Ctx (ctx ).
469
+ Debug ().
470
+ EmbedObject (req ).
471
+ Msg ("Delaying lock acquisition" )
472
+ return req
473
+ }
474
+
462
475
log .Ctx (ctx ).
463
476
Debug ().
464
477
EmbedObject (req ).
465
478
Msg ("Current lease request has the higher priority. It then acquires the lock" )
479
+
480
+ // Acquire lease
481
+ req .Status = pointer .String (StatusAcquired )
482
+ lp .state .acquired = req
483
+
466
484
log .Ctx (ctx ).
467
485
Info ().
468
486
EmbedObject (req ).
0 commit comments