@@ -71,6 +71,9 @@ const MSP = {
71
71
cli_output : [ ] ,
72
72
cli_callback : null ,
73
73
74
+ // Add retry configuration
75
+ MAX_RETRIES : 10 ,
76
+
74
77
read ( readInfo ) {
75
78
if ( CONFIGURATOR . virtualMode ) {
76
79
return ;
@@ -390,12 +393,14 @@ const MSP = {
390
393
callback : callback_msp ,
391
394
callbackOnError : doCallbackOnError ,
392
395
start : performance . now ( ) ,
396
+ attempts : 0 , // Initialize retry counter
393
397
} ;
394
398
395
- // Always set up timeout for all requests to ensure cleanup
396
- this . _setupTimeout ( requestObj , bufferOut ) ;
397
-
398
- this . callbacks . push ( requestObj ) ;
399
+ // Track only the first outstanding request for a given code
400
+ if ( ! isDuplicateRequest ) {
401
+ this . _setupTimeout ( requestObj , bufferOut ) ;
402
+ this . callbacks . push ( requestObj ) ;
403
+ }
399
404
400
405
// Send message if it has data or is a new request
401
406
if ( data || ! isDuplicateRequest ) {
@@ -421,20 +426,44 @@ const MSP = {
421
426
} ,
422
427
423
428
_handleTimeout ( requestObj , bufferOut ) {
429
+ // Increment retry attempts
430
+ requestObj . attempts ++ ;
431
+
424
432
console . warn (
425
433
`MSP: data request timed-out: ${ requestObj . code } ID: ${ serial . connectionId } ` +
426
434
`TAB: ${ GUI . active_tab } TIMEOUT: ${ this . timeout } ` +
427
- `QUEUE: ${ this . callbacks . length } (${ this . callbacks . map ( ( e ) => e . code ) } )` ,
435
+ `QUEUE: ${ this . callbacks . length } (${ this . callbacks . map ( ( e ) => e . code ) } ) ` +
436
+ `ATTEMPTS: ${ requestObj . attempts } /${ this . MAX_RETRIES } ` ,
428
437
) ;
429
438
439
+ // Check if max retries exceeded
440
+ if ( requestObj . attempts >= this . MAX_RETRIES ) {
441
+ console . error ( `MSP: Request ${ requestObj . code } exceeded max retries (${ this . MAX_RETRIES } ), giving up` ) ;
442
+
443
+ // Remove from callbacks to prevent memory leak
444
+ this . _removeRequestFromCallbacks ( requestObj ) ;
445
+
446
+ // Call error callback if available
447
+ if ( requestObj . callbackOnError && requestObj . callback ) {
448
+ requestObj . callback ( ) ;
449
+ }
450
+
451
+ return ; // Stop retrying
452
+ }
453
+
430
454
// Clear the existing timer before retry
431
455
clearTimeout ( requestObj . timer ) ;
432
456
457
+ // Reset start time for this retry attempt
458
+ requestObj . start = performance . now ( ) ;
459
+
433
460
serial . send ( bufferOut , ( sendInfo ) => {
434
461
if ( sendInfo . bytesSent === bufferOut . byteLength ) {
435
462
// Successfully sent retry
436
463
requestObj . stop = performance . now ( ) ;
437
464
const executionTime = Math . round ( requestObj . stop - requestObj . start ) ;
465
+ // Reset baseline for next retry
466
+ requestObj . start = requestObj . stop ;
438
467
this . timeout = Math . max ( this . MIN_TIMEOUT , Math . min ( executionTime , this . MAX_TIMEOUT ) ) ;
439
468
440
469
// Re-arm the timeout for retry attempts
0 commit comments