Skip to content

Commit 2611ef8

Browse files
committed
The CLI presence connection recovers when the webapp is restarted
1 parent 2db897f commit 2611ef8

File tree

2 files changed

+39
-21
lines changed

2 files changed

+39
-21
lines changed

packages/cli-v3/src/apiClient.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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(

packages/cli-v3/src/dev/devSupervisor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ class DevSupervisor implements WorkerRuntime {
333333

334334
async #startPresenceConnection() {
335335
try {
336-
const eventSource = await this.options.client.dev.presenceConnection();
336+
const eventSource = this.options.client.dev.presenceConnection();
337337

338338
// Regular "ping" messages
339339
eventSource.addEventListener("presence", (event: any) => {

0 commit comments

Comments
 (0)