@@ -188,67 +188,76 @@ export function is_mobile() {
188
188
// put send task to a queue and run it one by one
189
189
export class ReliableSender {
190
190
private seq = 0 ;
191
- private queue : { enable_batch : boolean , param : any } [ ] = [ ] ;
192
- private send_running = false
191
+ private queue : { enable_batch : boolean , task : any } [ ] = [ ] ;
193
192
private _stop = false ;
193
+ private ignore_interval_send = false ;
194
+ private last_send_time = 0 ;
195
+ private interval_send_id = 0 ;
194
196
195
197
constructor (
196
- private readonly sender : ( params : any [ ] , seq : number ) => Promise < void > ,
198
+ private readonly sender : ( tasks : any [ ] , seq : number ) => Promise < void > ,
197
199
private window_size : number = 8 ,
198
- init_seq = 0 , private timeout = 2000
200
+ init_seq = 0 ,
201
+ send_interval = 2000 ,
202
+ private min_send_interval = 1000 ,
199
203
) {
200
204
this . sender = sender ;
201
205
this . window_size = window_size ;
202
- this . timeout = timeout ;
203
206
this . seq = init_seq ;
204
207
this . queue = [ ] ;
208
+ this . ignore_interval_send = false ;
209
+ this . interval_send_id = setInterval ( this . interval_send . bind ( this ) , send_interval ) ;
205
210
}
206
211
207
212
/*
208
- * for continuous batch_send tasks in queue, they will be sent in one sender, the sending will retry when it finished or timeout.
209
- * for non-batch task, each will be sent in a single sender, the sending will retry when it finished.
213
+ * for continuous batch_send tasks in queue, they will be sent in one sender,
214
+ * for non-batch task, each will be sent in a single sender,
215
+ * the sending will retry when there are unfinished task in queue.
210
216
* */
211
- add_send_task ( param : any , allow_batch_send = true ) {
217
+ add_send_task ( task : any , allow_batch_send = true ) {
212
218
if ( this . _stop ) return ;
213
219
this . queue . push ( {
214
220
enable_batch : allow_batch_send ,
215
- param : param
221
+ task : task
216
222
} ) ;
217
- if ( ! this . send_running )
218
- this . start_send ( ) ;
223
+ this . do_send ( ) ;
219
224
}
220
225
221
- private start_send ( ) {
222
- if ( this . _stop || this . queue . length === 0 ) {
223
- this . send_running = false ;
224
- return ;
225
- }
226
- this . send_running = true ;
227
- let params : any [ ] = [ ] ;
226
+ private get_tasks ( ) {
227
+ let tasks : any [ ] = [ ] ;
228
228
for ( let item of this . queue ) {
229
229
if ( ! item . enable_batch )
230
230
break ;
231
- params . push ( item . param ) ;
231
+ tasks . push ( item . task ) ;
232
232
}
233
233
let batch_send = true ;
234
- if ( params . length === 0 && ! this . queue [ 0 ] . enable_batch ) {
234
+ if ( tasks . length === 0 && this . queue . length > 0 && ! this . queue [ 0 ] . enable_batch ) {
235
235
batch_send = false ;
236
- params . push ( this . queue [ 0 ] . param ) ;
236
+ tasks . push ( this . queue [ 0 ] . task ) ;
237
237
}
238
- if ( params . length === 0 ) {
239
- this . send_running = false ;
238
+ return { tasks, batch_send} ;
239
+ }
240
+
241
+ private do_send ( ) {
242
+ const info = this . get_tasks ( ) ;
243
+ const tasks = info . tasks , batch_send = info . batch_send ;
244
+ if ( tasks . length === 0 ) {
240
245
return ;
241
246
}
242
-
243
- let promises = [ this . sender ( params , this . seq ) ] ;
244
- if ( batch_send )
245
- promises . push ( new Promise ( ( resolve ) => setTimeout ( resolve , this . timeout ) ) ) ;
246
-
247
- Promise . race ( promises ) . then ( ( ) => {
248
- this . start_send ( ) ;
247
+ this . last_send_time = Date . now ( ) ;
248
+ if ( ! batch_send ) // for non-batch task, only retry after current request finished
249
+ this . ignore_interval_send = true ;
250
+ this . sender ( tasks , this . seq ) . then ( ( ) => {
251
+ this . ignore_interval_send = false ;
249
252
} ) ;
250
253
}
251
254
255
+ private interval_send ( ) {
256
+ if ( this . _stop || this . ignore_interval_send ) return ;
257
+ if ( Date . now ( ) - this . last_send_time < this . min_send_interval ) return ;
258
+ this . do_send ( ) ;
259
+ }
260
+
252
261
// seq for each ack call must be larger than the previous one, otherwise the ack will be ignored
253
262
ack ( seq : number ) {
254
263
if ( seq < this . seq )
@@ -260,5 +269,6 @@ export class ReliableSender {
260
269
261
270
stop ( ) {
262
271
this . _stop = true ;
272
+ clearInterval ( this . interval_send_id ) ;
263
273
}
264
274
}
0 commit comments