File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -117,6 +117,28 @@ describe('withLeaderLock', () => {
117117 expect ( onFollower . mock . calls . length ) . toBeGreaterThanOrEqual ( 2 )
118118 } )
119119
120+ it ( 'follower does a final read after timeout to catch a just-finished leader' , async ( ) => {
121+ redisConfigMockFns . mockAcquireLock . mockResolvedValueOnce ( false )
122+
123+ let polls = 0
124+ const onFollower = vi . fn ( async ( ) => {
125+ polls += 1
126+ // Return null during the poll loop, value on the post-deadline read.
127+ if ( polls <= 2 ) return null
128+ return 'late-leader'
129+ } )
130+
131+ const result = await withLeaderLock < string > ( {
132+ key : 'k' ,
133+ pollIntervalMs : 5 ,
134+ maxWaitMs : 12 ,
135+ onLeader : async ( ) => 'should-not-run' ,
136+ onFollower,
137+ } )
138+
139+ expect ( result ) . toBe ( 'late-leader' )
140+ } )
141+
120142 it ( 'follower returns null after timeout' , async ( ) => {
121143 redisConfigMockFns . mockAcquireLock . mockResolvedValueOnce ( false )
122144
Original file line number Diff line number Diff line change @@ -64,6 +64,10 @@ export async function withLeaderLock<T>(opts: LeaderLockOptions<T>): Promise<T |
6464 if ( value !== null ) return value
6565 }
6666
67+ // The leader may have persisted between our final poll and now; one last check.
68+ const lastChance = await onFollower ( )
69+ if ( lastChance !== null ) return lastChance
70+
6771 logger . warn ( 'Follower timed out waiting for leader' , { key, maxWaitMs } )
6872 return null
6973}
You can’t perform that action at this time.
0 commit comments