Reconnect SSE event stream after shutdown

Otherwise we'll never know we have updates
This commit is contained in:
Eli Ribble 2026-04-29 15:02:18 +00:00
parent 2fbceb11e3
commit 4bb37c5ab3
No known key found for this signature in database
2 changed files with 22 additions and 5 deletions

View file

@ -20,10 +20,11 @@ type SSEHandlerStatus = (data: SSEMessageStatus) => void;
interface SSEManagerType {
connect: (url: string) => Promise<EventSource>;
disconnect: () => void;
ready: (callback: (eventSource: EventSource) => void) => void;
reconnect: (delay: number) => void;
subscribe: (handler: SSEHandlerResource) => string;
subscribeStatus: (handler: SSEHandlerStatus) => string;
unsubscribe: (uuid: string) => void;
ready: (callback: (eventSource: EventSource) => void) => void;
}
/*
@ -35,11 +36,12 @@ declare global {
*/
export const SSEManager: SSEManagerType = (function (): SSEManagerType {
let connectionPromise: Promise<EventSource> | null = null;
let isConnected: boolean = false;
let eventSource: EventSource | null = null;
let serverUrl: string = "";
let subscribersResource: Map<string, SSEHandlerResource> = new Map();
let subscribersStatus: Map<string, SSEHandlerStatus> = new Map();
let isConnected: boolean = false;
let connectionPromise: Promise<EventSource> | null = null;
function connect(url: string): Promise<EventSource> {
if (connectionPromise) {
@ -48,6 +50,7 @@ export const SSEManager: SSEManagerType = (function (): SSEManagerType {
connectionPromise = new Promise((resolve, reject) => {
eventSource = new EventSource(url);
serverUrl = url;
eventSource.onopen = function (): void {
isConnected = true;
@ -124,6 +127,12 @@ export const SSEManager: SSEManagerType = (function (): SSEManagerType {
}
}
function reconnect(delay: number) {
disconnect();
setTimeout(() => {
connect(serverUrl);
}, delay);
}
function subscribe(handler: SSEHandlerResource): string {
const uuid = crypto.randomUUID();
subscribersResource.set(uuid.toString(), handler);
@ -148,9 +157,10 @@ export const SSEManager: SSEManagerType = (function (): SSEManagerType {
return {
connect,
disconnect,
ready,
reconnect,
subscribe,
subscribeStatus,
unsubscribe,
ready,
};
})();

View file

@ -36,14 +36,21 @@ const session = useSessionStore();
const updateDate = ref<Date | null>(null);
onMounted(() => {
SSEManager.subscribeStatus((msg: SSEMessageStatus) => {
console.log("status update:", msg);
if (msg.status == "connected") {
if (revision.value == "") {
revision.value = msg.revision;
} else {
updateDate.value = new Date();
}
} else if (msg.status == "shutdown") {
console.log(
"server is shutting down, waiting a bit and re-initiating connection",
);
SSEManager.reconnect(5);
} else {
console.error("unrecognized server status", msg.status);
}
console.log("status update:", msg);
});
session
.get()