fix(app): reconnect event stream on disconnect
This commit is contained in:
@@ -46,6 +46,7 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
|
|||||||
type Queued = { directory: string; payload: Event }
|
type Queued = { directory: string; payload: Event }
|
||||||
const FLUSH_FRAME_MS = 16
|
const FLUSH_FRAME_MS = 16
|
||||||
const STREAM_YIELD_MS = 8
|
const STREAM_YIELD_MS = 8
|
||||||
|
const RECONNECT_DELAY_MS = 250
|
||||||
|
|
||||||
let queue: Queued[] = []
|
let queue: Queued[] = []
|
||||||
let buffer: Queued[] = []
|
let buffer: Queued[] = []
|
||||||
@@ -91,50 +92,58 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
let streamErrorLogged = false
|
let streamErrorLogged = false
|
||||||
|
const wait = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms))
|
||||||
|
|
||||||
void (async () => {
|
void (async () => {
|
||||||
const events = await eventSdk.global.event({
|
while (!abort.signal.aborted) {
|
||||||
onSseError: (error) => {
|
try {
|
||||||
if (streamErrorLogged) return
|
const events = await eventSdk.global.event({
|
||||||
streamErrorLogged = true
|
onSseError: (error) => {
|
||||||
console.error("[global-sdk] event stream error", {
|
if (streamErrorLogged) return
|
||||||
url: server.url,
|
streamErrorLogged = true
|
||||||
fetch: eventFetch ? "platform" : "webview",
|
console.error("[global-sdk] event stream error", {
|
||||||
error,
|
url: server.url,
|
||||||
|
fetch: eventFetch ? "platform" : "webview",
|
||||||
|
error,
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
},
|
let yielded = Date.now()
|
||||||
})
|
for await (const event of events.stream) {
|
||||||
let yielded = Date.now()
|
streamErrorLogged = false
|
||||||
for await (const event of events.stream) {
|
const directory = event.directory ?? "global"
|
||||||
const directory = event.directory ?? "global"
|
const payload = event.payload
|
||||||
const payload = event.payload
|
const k = key(directory, payload)
|
||||||
const k = key(directory, payload)
|
if (k) {
|
||||||
if (k) {
|
const i = coalesced.get(k)
|
||||||
const i = coalesced.get(k)
|
if (i !== undefined) {
|
||||||
if (i !== undefined) {
|
queue[i] = { directory, payload }
|
||||||
queue[i] = { directory, payload }
|
continue
|
||||||
continue
|
}
|
||||||
}
|
coalesced.set(k, queue.length)
|
||||||
coalesced.set(k, queue.length)
|
}
|
||||||
}
|
queue.push({ directory, payload })
|
||||||
queue.push({ directory, payload })
|
schedule()
|
||||||
schedule()
|
|
||||||
|
|
||||||
if (Date.now() - yielded < STREAM_YIELD_MS) continue
|
if (Date.now() - yielded < STREAM_YIELD_MS) continue
|
||||||
yielded = Date.now()
|
yielded = Date.now()
|
||||||
await new Promise<void>((resolve) => setTimeout(resolve, 0))
|
await wait(0)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (!streamErrorLogged) {
|
||||||
|
streamErrorLogged = true
|
||||||
|
console.error("[global-sdk] event stream failed", {
|
||||||
|
url: server.url,
|
||||||
|
fetch: eventFetch ? "platform" : "webview",
|
||||||
|
error,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abort.signal.aborted) return
|
||||||
|
await wait(RECONNECT_DELAY_MS)
|
||||||
}
|
}
|
||||||
})()
|
})().finally(flush)
|
||||||
.finally(flush)
|
|
||||||
.catch((error) => {
|
|
||||||
if (streamErrorLogged) return
|
|
||||||
streamErrorLogged = true
|
|
||||||
console.error("[global-sdk] event stream failed", {
|
|
||||||
url: server.url,
|
|
||||||
fetch: eventFetch ? "platform" : "webview",
|
|
||||||
error,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
onCleanup(() => {
|
onCleanup(() => {
|
||||||
abort.abort()
|
abort.abort()
|
||||||
|
|||||||
Reference in New Issue
Block a user