UNPKG

2.33 kBPlain TextView Raw
1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3import { Observer } from 'zen-observable-ts';
4import { RECONNECT_DELAY, RECONNECT_INTERVAL } from '../Providers/constants';
5
6export enum ReconnectEvent {
7 START_RECONNECT = 'START_RECONNECT',
8 HALT_RECONNECT = 'HALT_RECONNECT',
9}
10
11/**
12 * Captures the reconnect event logic used to determine when to reconnect to PubSub providers.
13 * Reconnnect attempts are delayed by 5 seconds to let the interface settle.
14 * Attempting to reconnect only once creates unrecoverable states when the network state isn't
15 * supported by the browser, so this keeps retrying every minute until halted.
16 */
17export class ReconnectionMonitor {
18 private reconnectObservers: Observer<void>[] = [];
19 private reconnectIntervalId?: ReturnType<typeof setInterval>;
20 private reconnectSetTimeoutId?: ReturnType<typeof setTimeout>;
21
22 /**
23 * Add reconnect observer to the list of observers to alert on reconnect
24 */
25 addObserver(reconnectObserver: Observer<void>) {
26 this.reconnectObservers.push(reconnectObserver);
27 }
28
29 /**
30 * Given a reconnect event, start the appropriate behavior
31 */
32 record(event: ReconnectEvent) {
33 if (event === ReconnectEvent.START_RECONNECT) {
34 // If the reconnection hasn't been started
35 if (
36 this.reconnectSetTimeoutId === undefined &&
37 this.reconnectIntervalId === undefined
38 ) {
39 this.reconnectSetTimeoutId = setTimeout(() => {
40 // Reconnect now
41 this._triggerReconnect();
42 // Retry reconnect every periodically until it works
43 this.reconnectIntervalId = setInterval(() => {
44 this._triggerReconnect();
45 }, RECONNECT_INTERVAL);
46 }, RECONNECT_DELAY);
47 }
48 }
49
50 if (event === ReconnectEvent.HALT_RECONNECT) {
51 if (this.reconnectIntervalId) {
52 clearInterval(this.reconnectIntervalId);
53 this.reconnectIntervalId = undefined;
54 }
55 if (this.reconnectSetTimeoutId) {
56 clearTimeout(this.reconnectSetTimeoutId);
57 this.reconnectSetTimeoutId = undefined;
58 }
59 }
60 }
61
62 /**
63 * Complete all reconnect observers
64 */
65 close() {
66 this.reconnectObservers.forEach(reconnectObserver => {
67 reconnectObserver.complete?.();
68 });
69 }
70
71 private _triggerReconnect() {
72 this.reconnectObservers.forEach(reconnectObserver => {
73 reconnectObserver.next?.();
74 });
75 }
76}