diff --git a/src/Components/Web.JS/src/Boot.Server.ts b/src/Components/Web.JS/src/Boot.Server.ts index 968a65dd45c6..a7b8454eea33 100644 --- a/src/Components/Web.JS/src/Boot.Server.ts +++ b/src/Components/Web.JS/src/Boot.Server.ts @@ -49,6 +49,7 @@ async function boot(userOptions?: Partial): Promise { const reconnection = existingConnection || await initializeConnection(options, logger, circuit); if (!(await circuit.reconnect(reconnection))) { logger.log(LogLevel.Information, 'Reconnection attempt to the circuit was rejected by the server. This may indicate that the associated state is no longer available on the server.'); + options.reconnectionHandler!.onConnectionRejected(options.reconnectionOptions); return false; } diff --git a/src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts b/src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts index 08bbea4c5fc5..c4c16fda2e55 100644 --- a/src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts +++ b/src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts @@ -22,11 +22,13 @@ export interface ReconnectionOptions { maxRetries: number; retryIntervalMilliseconds: number; dialogId: string; + reloadOnCircuitRejected: boolean; } export interface ReconnectionHandler { onConnectionDown(options: ReconnectionOptions, error?: Error): void; onConnectionUp(): void; + onConnectionRejected(options: ReconnectionOptions): void; } const defaultOptions: CircuitStartOptions = { @@ -36,5 +38,6 @@ const defaultOptions: CircuitStartOptions = { maxRetries: 8, retryIntervalMilliseconds: 20000, dialogId: 'components-reconnect-modal', + reloadOnCircuitRejected: true, }, }; diff --git a/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts b/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts index 28415375ba74..aa8eae4fb957 100644 --- a/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts +++ b/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts @@ -35,11 +35,15 @@ export class DefaultReconnectionHandler implements ReconnectionHandler { this._currentReconnectionProcess = null; } } + + onConnectionRejected(options: ReconnectionOptions) { + if (options.reloadOnCircuitRejected) { + location.reload(); + } + } }; class ReconnectionProcess { - static readonly MaximumFirstRetryInterval = 3000; - readonly reconnectDisplay: ReconnectDisplay; isDisposed = false; @@ -57,12 +61,6 @@ class ReconnectionProcess { async attemptPeriodicReconnection(options: ReconnectionOptions) { for (let i = 0; i < options.maxRetries; i++) { this.reconnectDisplay.update(i + 1); - - const delayDuration = i == 0 && options.retryIntervalMilliseconds > ReconnectionProcess.MaximumFirstRetryInterval - ? ReconnectionProcess.MaximumFirstRetryInterval - : options.retryIntervalMilliseconds; - await this.delay(delayDuration); - if (this.isDisposed) { break; } @@ -83,6 +81,7 @@ class ReconnectionProcess { // We got an exception so will try again momentarily this.logger.log(LogLevel.Error, err); } + await this.delay(options.retryIntervalMilliseconds); } this.reconnectDisplay.failed(); diff --git a/src/Components/Web.JS/tests/DefaultReconnectionHandler.test.ts b/src/Components/Web.JS/tests/DefaultReconnectionHandler.test.ts index 4d34c08c79fc..fa0e1624d956 100644 --- a/src/Components/Web.JS/tests/DefaultReconnectionHandler.test.ts +++ b/src/Components/Web.JS/tests/DefaultReconnectionHandler.test.ts @@ -31,7 +31,8 @@ describe('DefaultReconnectionHandler', () => { handler.onConnectionDown({ maxRetries: 1000, retryIntervalMilliseconds: 100, - dialogId: 'ignored' + dialogId: 'ignored', + reloadOnCircuitRejected: true }); handler.onConnectionUp(); @@ -48,7 +49,8 @@ describe('DefaultReconnectionHandler', () => { handler.onConnectionDown({ maxRetries: 1000, retryIntervalMilliseconds: 100, - dialogId: 'ignored' + dialogId: 'ignored', + reloadOnCircuitRejected: true }); expect(testDisplay.show).toHaveBeenCalled(); expect(testDisplay.failed).not.toHaveBeenCalled(); @@ -67,7 +69,8 @@ describe('DefaultReconnectionHandler', () => { handler.onConnectionDown({ maxRetries: 2, retryIntervalMilliseconds: 5, - dialogId: 'ignored' + dialogId: 'ignored', + reloadOnCircuitRejected: true }); await delay(500); @@ -85,7 +88,8 @@ describe('DefaultReconnectionHandler', () => { handler.onConnectionDown({ maxRetries: maxRetries, retryIntervalMilliseconds: 5, - dialogId: 'ignored' + dialogId: 'ignored', + reloadOnCircuitRejected: true }); await delay(500);