@@ -61,7 +61,7 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
61
61
62
62
private readonly updateInterval : number
63
63
64
- private cancelTimeout ? : ( ) => void
64
+ private cancelTimeout : ( ( ) => void ) | null
65
65
66
66
private isStarted : boolean
67
67
@@ -71,10 +71,16 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
71
71
72
72
private timeoutFactory : TimeoutFactory
73
73
74
- private currentRequest ? : AbortableRequest
74
+ private currentRequest : AbortableRequest | null
75
75
76
76
private backoffController : BackoffController
77
77
78
+ // When true, this means the update interval timeout fired before the current
79
+ // sync completed. In that case, we should sync again immediately upon
80
+ // completion of the current request, instead of waiting another update
81
+ // interval.
82
+ private syncOnCurrentRequestComplete : boolean
83
+
78
84
constructor ( config : DatafileManagerConfig ) {
79
85
const configWithDefaultsApplied : DatafileManagerConfig = {
80
86
...this . getConfigDefaults ( ) ,
@@ -117,7 +123,10 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
117
123
logger . warn ( 'Invalid updateInterval %s, defaulting to %s' , updateInterval , DEFAULT_UPDATE_INTERVAL )
118
124
this . updateInterval = DEFAULT_UPDATE_INTERVAL
119
125
}
126
+ this . cancelTimeout = null
127
+ this . currentRequest = null
120
128
this . backoffController = new BackoffController ( )
129
+ this . syncOnCurrentRequestComplete = false
121
130
}
122
131
123
132
get ( ) : object | null {
@@ -138,14 +147,14 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
138
147
this . isStarted = false
139
148
if ( this . cancelTimeout ) {
140
149
this . cancelTimeout ( )
141
- this . cancelTimeout = undefined
150
+ this . cancelTimeout = null
142
151
}
143
152
144
153
this . emitter . removeAllListeners ( )
145
154
146
155
if ( this . currentRequest ) {
147
156
this . currentRequest . abort ( )
148
- this . currentRequest = undefined
157
+ this . currentRequest = null
149
158
}
150
159
151
160
return Promise . resolve ( )
@@ -209,15 +218,17 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
209
218
return
210
219
}
211
220
212
- this . currentRequest = undefined
221
+ this . currentRequest = null
213
222
214
- if ( this . autoUpdate ) {
215
- this . scheduleNextUpdate ( )
216
- }
217
223
if ( ! this . isReadyPromiseSettled && ! this . autoUpdate ) {
218
224
// We will never resolve ready, so reject it
219
225
this . rejectReadyPromise ( new Error ( 'Failed to become ready' ) )
220
226
}
227
+
228
+ if ( this . autoUpdate && this . syncOnCurrentRequestComplete ) {
229
+ this . syncDatafile ( )
230
+ }
231
+ this . syncOnCurrentRequestComplete = false
221
232
}
222
233
223
234
private syncDatafile ( ) : void {
@@ -241,6 +252,10 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
241
252
this . currentRequest . responsePromise
242
253
. then ( onRequestResolved , onRequestRejected )
243
254
. then ( onRequestComplete , onRequestComplete )
255
+
256
+ if ( this . autoUpdate ) {
257
+ this . scheduleNextUpdate ( )
258
+ }
244
259
}
245
260
246
261
private resolveReadyPromise ( ) : void {
@@ -258,7 +273,11 @@ export default abstract class HTTPPollingDatafileManager implements DatafileMana
258
273
const nextUpdateDelay = Math . max ( currentBackoffDelay , this . updateInterval )
259
274
logger . debug ( 'Scheduling sync in %s ms' , nextUpdateDelay )
260
275
this . cancelTimeout = this . timeoutFactory . setTimeout ( ( ) => {
261
- this . syncDatafile ( )
276
+ if ( this . currentRequest ) {
277
+ this . syncOnCurrentRequestComplete = true
278
+ } else {
279
+ this . syncDatafile ( )
280
+ }
262
281
} , nextUpdateDelay )
263
282
}
264
283
0 commit comments