@@ -94,26 +94,40 @@ function readActiveRuns(): string[] {
9494}
9595
9696async function callDisconnect ( runFriendlyIds : string [ ] ) : Promise < void > {
97- try {
98- await fetch ( ` ${ apiUrl } /engine/v1/dev/disconnect` , {
99- method : "POST" ,
100- headers : {
101- "Content-Type" : "application/json" ,
102- Authorization : `Bearer ${ apiKey } ` ,
103- } ,
104- body : JSON . stringify ( { runFriendlyIds } ) ,
105- signal : AbortSignal . timeout ( 10_000 ) ,
106- } ) ;
107- } catch {
108- // Network error — runs will eventually time out via heartbeat
97+ const response = await fetch ( ` ${ apiUrl } /engine/v1/dev/disconnect` , {
98+ method : "POST" ,
99+ headers : {
100+ "Content-Type" : "application/json" ,
101+ Authorization : `Bearer ${ apiKey } ` ,
102+ } ,
103+ body : JSON . stringify ( { runFriendlyIds } ) ,
104+ signal : AbortSignal . timeout ( 10_000 ) ,
105+ } ) ;
106+
107+ if ( ! response . ok ) {
108+ throw new Error ( `Disconnect failed with status ${ response . status } ` ) ;
109109 }
110110}
111111
112+ const MAX_DISCONNECT_ATTEMPTS = 5 ;
113+ const INITIAL_BACKOFF_MS = 500 ;
114+
112115async function onParentDied ( ) : Promise < void > {
113116 const runFriendlyIds = readActiveRuns ( ) ;
114117
115118 if ( runFriendlyIds . length > 0 ) {
116- await callDisconnect ( runFriendlyIds ) ;
119+ for ( let attempt = 0 ; attempt < MAX_DISCONNECT_ATTEMPTS ; attempt ++ ) {
120+ try {
121+ await callDisconnect ( runFriendlyIds ) ;
122+ break ;
123+ } catch {
124+ if ( attempt < MAX_DISCONNECT_ATTEMPTS - 1 ) {
125+ const backoff = INITIAL_BACKOFF_MS * 2 ** attempt ;
126+ await new Promise ( ( resolve ) => setTimeout ( resolve , backoff ) ) ;
127+ }
128+ // Final attempt failed — runs will eventually time out via heartbeat
129+ }
130+ }
117131 }
118132
119133 cleanup ( ) ;
0 commit comments