diff --git a/src/main/runtime/relay/relay-auth-coordinator-recovery.test.ts b/src/main/runtime/relay/relay-auth-coordinator-recovery.test.ts index 30f8424bcb3..21e7f9aadec 100644 --- a/src/main/runtime/relay/relay-auth-coordinator-recovery.test.ts +++ b/src/main/runtime/relay/relay-auth-coordinator-recovery.test.ts @@ -39,6 +39,32 @@ describe('RelayAuthCoordinator transient recovery', () => { expect(statuses.at(-1)).toBe('registered') }) + it('retries when cloud-session refresh fails before identity can be read', async () => { + vi.useFakeTimers() + const broker = { closeNow: vi.fn() } + const readContext = vi + .fn() + .mockRejectedValueOnce(new Error('temporary cloud session refresh failure')) + .mockResolvedValueOnce(context) + const openBroker = vi.fn().mockResolvedValue(broker) + const coordinator = new RelayAuthCoordinator({ + readContext, + openBroker, + onStatus: vi.fn(), + random: () => 0.5 + }) + + coordinator.reconcile() + await vi.advanceTimersByTimeAsync(0) + expect(readContext).toHaveBeenCalledOnce() + expect(openBroker).not.toHaveBeenCalled() + + await vi.advanceTimersByTimeAsync(501) + expect(readContext).toHaveBeenCalledTimes(2) + expect(openBroker).toHaveBeenCalledOnce() + expect(coordinator.getActiveBroker()).toBe(broker) + }) + it('backs a sustained outage off to the five-minute jitter cap', async () => { vi.useFakeTimers() const openBroker = vi.fn().mockRejectedValue(new Error('temporary control open failure')) diff --git a/src/main/runtime/relay/relay-auth-coordinator.ts b/src/main/runtime/relay/relay-auth-coordinator.ts index 4754db8d546..7f97e33dc41 100644 --- a/src/main/runtime/relay/relay-auth-coordinator.ts +++ b/src/main/runtime/relay/relay-auth-coordinator.ts @@ -112,7 +112,7 @@ export class RelayAuthCoordinator { } private async reconcileEpoch(epoch: number, expectedIdentityKey?: string): Promise { - let retryIdentityKey: string | null = null + let retryIdentityKey: string | undefined try { const context = await this.options.readContext() if (!this.isEpochCurrent(epoch)) { @@ -182,14 +182,14 @@ export class RelayAuthCoordinator { } catch (error) { if (this.isEpochCurrent(epoch)) { this.options.onStatus('offline') - if (retryIdentityKey && shouldRetryRelayConnectionError(error)) { + if (shouldRetryRelayConnectionError(error)) { this.scheduleRetry(epoch, retryIdentityKey) } } } } - private scheduleRetry(epoch: number, expectedIdentityKey: string): void { + private scheduleRetry(epoch: number, expectedIdentityKey?: string): void { if (this.retryTimer || !this.isEpochCurrent(epoch)) { return }