@@ -494,11 +494,15 @@ export class CliApiClient {
494494 } ) ;
495495 }
496496
497- private async devPresenceConnection ( ) : Promise < EventSource > {
497+ private devPresenceConnection ( ) : EventSource {
498498 if ( ! this . accessToken ) {
499499 throw new Error ( "connectToPresence: No access token" ) ;
500500 }
501501
502+ let retryCount = 0 ;
503+ const maxRetries = 5 ;
504+ const retryDelay = 1000 ; // Start with 1 second delay
505+
502506 const eventSource = new EventSource ( `${ this . apiURL } /engine/v1/dev/presence` , {
503507 fetch : ( input , init ) =>
504508 fetch ( input , {
@@ -510,26 +514,40 @@ export class CliApiClient {
510514 } ) ,
511515 } ) ;
512516
513- return new Promise ( ( resolve , reject ) => {
514- eventSource . onopen = ( ) => {
515- logger . debug ( "Presence connection established" ) ;
516- resolve ( eventSource ) ;
517- } ;
518-
519- eventSource . onerror = ( error : any ) => {
520- // The connection will automatically try to reconnect
521- logger . debug ( "Presence connection error, will automatically attempt to reconnect" , {
522- error,
523- readyState : eventSource . readyState , // 0 = connecting, 1 = open, 2 = closed
524- } ) ;
525-
526- // If you want to detect when it's permanently failed and not reconnecting
527- if ( eventSource . readyState === EventSource . CLOSED ) {
528- logger . debug ( "Presence connection permanently closed" , { error } ) ;
529- reject ( new Error ( `Failed to connect to ${ this . apiURL } ` ) ) ;
517+ eventSource . onopen = ( ) => {
518+ logger . debug ( "Presence connection established" ) ;
519+ retryCount = 0 ; // Reset retry count on successful connection
520+ } ;
521+
522+ eventSource . onerror = ( error : any ) => {
523+ // The connection will automatically try to reconnect
524+ logger . debug ( "Presence connection error, will automatically attempt to reconnect" , {
525+ error,
526+ readyState : eventSource . readyState ,
527+ } ) ;
528+
529+ if ( eventSource . readyState === EventSource . CLOSED ) {
530+ logger . debug ( "Presence connection permanently closed" , { error, retryCount } ) ;
531+
532+ if ( retryCount < maxRetries ) {
533+ retryCount ++ ;
534+ const backoffDelay = retryDelay * Math . pow ( 2 , retryCount - 1 ) ; // Exponential backoff
535+
536+ logger . debug (
537+ `Attempting reconnection in ${ backoffDelay } ms (attempt ${ retryCount } /${ maxRetries } )`
538+ ) ;
539+ eventSource . close ( ) ;
540+
541+ setTimeout ( ( ) => {
542+ this . devPresenceConnection ( ) ;
543+ } , backoffDelay ) ;
544+ } else {
545+ logger . debug ( "Max retry attempts reached, giving up" ) ;
530546 }
531- } ;
532- } ) ;
547+ }
548+ } ;
549+
550+ return eventSource ;
533551 }
534552
535553 private async devDequeue (
0 commit comments