-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathreconnectionScheduler.ts
More file actions
88 lines (75 loc) · 2.72 KB
/
reconnectionScheduler.ts
File metadata and controls
88 lines (75 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* @license
* Copyright 2019-2020 CERN and copyright holders of ALICE O2.
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
* All rights not expressly granted are reserved.
*
* This software is distributed under the terms of the GNU General Public
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
*
* In applying this license CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/
export interface ReconnectionOptions {
initialDelay?: number; // Initial delay in ms
maxDelay?: number; // Maximum delay in ms
}
/**
* A scheduler that manages reconnection attempts with an exponential backoff.
*/
export class ReconnectionScheduler {
private reconnectCallback: any;
private initialDelay: number;
private maxDelay: number;
private currentDelay: number;
private attemptCount: number;
private timeoutId: any;
private logger: Logger;
private isResetting: boolean = false;
private isScheduling: boolean = false;
/**
* Creates a new instance of the ReconnectionScheduler.
* @param {any} reconnectCallback - The callback to be called when a reconnection attempt is scheduled.
* @param {ReconnectionOptions} [options] - Options for the reconnection schedule.
* @param {Logger} logger - The logger instance to be used for logging messages.
*/
constructor(reconnectCallback: any, options: ReconnectionOptions = {}, logger: Logger) {
this.reconnectCallback = reconnectCallback;
this.initialDelay = options.initialDelay ?? 1000;
this.maxDelay = options.maxDelay ?? 30000;
this.currentDelay = this.initialDelay;
this.attemptCount = 0;
this.timeoutId = null;
this.logger = logger;
}
/**
* Schedules the next reconnection attempt using exponential backoff.
*/
schedule() {
if (this.isScheduling) return;
this.isScheduling = true;
this.isResetting = false;
this.attemptCount++;
// Exponential backoff calculation
const delay = this.initialDelay * Math.pow(2, this.attemptCount);
this.currentDelay = Math.min(this.maxDelay, delay);
this.logger.infoMessage(`Recconection attempt #${this.attemptCount}: Sleep for ${this.currentDelay.toFixed(0)} ms.`);
// Plan the reconnection attempt
this.timeoutId = setTimeout(() => {
this.isScheduling = false;
this.reconnectCallback();
}, this.currentDelay);
}
/**
* Resets the scheduler to its initial state.
*/
reset() {
if (this.isResetting) return;
this.isScheduling = false;
this.isResetting = true;
clearTimeout(this.timeoutId);
this.attemptCount = 0;
this.currentDelay = this.initialDelay;
}
}