@@ -15,6 +15,10 @@ import * as logger from "@onflow/util-logger"
15
15
16
16
const WS_OPEN = 1
17
17
18
+ type DeepRequired < T > = Required < {
19
+ [ K in keyof T ] : DeepRequired < T [ K ] >
20
+ } >
21
+
18
22
interface SubscriptionInfo < T extends SdkTransport . SubscriptionTopic > {
19
23
// Internal ID for the subscription
20
24
id : number
@@ -30,35 +34,49 @@ interface SubscriptionInfo<T extends SdkTransport.SubscriptionTopic> {
30
34
onError : ( error : Error ) => void
31
35
}
32
36
33
- interface WsTransportConfig {
37
+ export interface SubscriptionManagerConfig {
34
38
/**
35
39
* The URL of the node to connect to
36
40
*/
37
41
node : string
38
42
/**
39
- * Starting interval for reconnection attempts in milliseconds, exponential backoff is applied
40
- * @default 500
41
- */
42
- reconnectInterval ?: number
43
- /**
44
- * The number of reconnection attempts before giving up
45
- * @default 5
43
+ * Options for reconnecting to the server
46
44
*/
47
- reconnectAttempts ?: number
45
+ reconnectOptions ?: {
46
+ /**
47
+ * The initial delay in milliseconds before reconnecting
48
+ * @default 500
49
+ */
50
+ initialReconnectDelay ?: number
51
+ /**
52
+ * The maximum number of reconnection attempts
53
+ * @default 5
54
+ */
55
+ reconnectAttempts ?: number
56
+ /**
57
+ * The maximum delay in milliseconds between reconnection attempts
58
+ * @default 5000
59
+ */
60
+ maxReconnectDelay ?: number
61
+ }
48
62
}
49
63
50
64
export class SubscriptionManager {
51
65
private counter = 0
52
66
private subscriptions : SubscriptionInfo < SdkTransport . SubscriptionTopic > [ ] = [ ]
53
67
private socket : WebSocket | null = null
54
- private config : Required < WsTransportConfig >
68
+ private config : DeepRequired < SubscriptionManagerConfig >
55
69
private reconnectAttempts = 0
56
70
57
- constructor ( config : WsTransportConfig ) {
71
+ constructor ( config : SubscriptionManagerConfig ) {
58
72
this . config = {
59
- reconnectInterval : 500 ,
60
- reconnectAttempts : 5 ,
61
73
...config ,
74
+ reconnectOptions : {
75
+ initialReconnectDelay : 500 ,
76
+ reconnectAttempts : 5 ,
77
+ maxReconnectDelay : 5000 ,
78
+ ...config . reconnectOptions ,
79
+ } ,
62
80
}
63
81
}
64
82
@@ -129,7 +147,9 @@ export class SubscriptionManager {
129
147
} )
130
148
131
149
// Validate the number of reconnection attempts
132
- if ( this . reconnectAttempts >= this . config . reconnectAttempts ) {
150
+ if (
151
+ this . reconnectAttempts >= this . config . reconnectOptions . reconnectAttempts
152
+ ) {
133
153
logger . log ( {
134
154
level : logger . LEVELS . error ,
135
155
title : "WebSocket Error" ,
@@ -288,6 +308,10 @@ export class SubscriptionManager {
288
308
* @returns The backoff interval in milliseconds
289
309
*/
290
310
private get backoffInterval ( ) {
291
- return this . config . reconnectInterval * ( this . reconnectAttempts ^ 2 )
311
+ return Math . min (
312
+ this . config . reconnectOptions . maxReconnectDelay ,
313
+ this . config . reconnectOptions . initialReconnectDelay *
314
+ 2 ** this . reconnectAttempts
315
+ )
292
316
}
293
317
}
0 commit comments