fix(oauth): follower last-chance read after poll deadline (#4718)

* fix(oauth): follower last-chance read after poll deadline

* test(oauth): exercise last-chance read in follower timeout test
This commit is contained in:
Waleed
2026-05-21 23:07:17 -07:00
committed by GitHub
parent 0c96964f8f
commit 3d9a1c4410
2 changed files with 28 additions and 0 deletions
@@ -117,6 +117,30 @@ describe('withLeaderLock', () => {
expect(onFollower.mock.calls.length).toBeGreaterThanOrEqual(2)
})
it('follower does a final read after timeout to catch a just-finished leader', async () => {
redisConfigMockFns.mockAcquireLock.mockResolvedValueOnce(false)
// pollInterval=5, maxWait=9 → loop exits after 2 in-loop polls (T+5, T+10);
// the third call (polls=3) is the post-deadline last-chance read.
let polls = 0
const onFollower = vi.fn(async () => {
polls += 1
if (polls <= 2) return null
return 'late-leader'
})
const result = await withLeaderLock<string>({
key: 'k',
pollIntervalMs: 5,
maxWaitMs: 9,
onLeader: async () => 'should-not-run',
onFollower,
})
expect(result).toBe('late-leader')
expect(onFollower).toHaveBeenCalledTimes(3)
})
it('follower returns null after timeout', async () => {
redisConfigMockFns.mockAcquireLock.mockResolvedValueOnce(false)
+4
View File
@@ -64,6 +64,10 @@ export async function withLeaderLock<T>(opts: LeaderLockOptions<T>): Promise<T |
if (value !== null) return value
}
// The leader may have persisted between our final poll and now; one last check.
const lastChance = await onFollower()
if (lastChance !== null) return lastChance
logger.warn('Follower timed out waiting for leader', { key, maxWaitMs })
return null
}