dope: SSE wake recovery retries, plus a favicon #29

Merged
pecheny merged 2 commits from sse-wake-retry into main 2026-07-24 23:49:28 +00:00
Owner

Why

A woken iOS tab spun on Переподключение forever: recovery ran once per wake
event, so a tab resumed while the radio was still down failed that attempt with
no further event coming. On an OD viewer the dot never cleared even after the
server returned and the browser's own EventSource had reconnected, because only
a resync clears the status.

Attempts now retry on a 3/6/12/30s backoff until one re-seeds the state, and a
stream that merely looks OPEN no longer ends the chain. One createWakeRecovery
serves both engines, so od/si and EK host/viewer share it.

Also dope's first favicon: the 1080px logo as a 6.7KB multi-size ico.

# Why A woken iOS tab spun on Переподключение forever: recovery ran once per wake event, so a tab resumed while the radio was still down failed that attempt with no further event coming. On an OD viewer the dot never cleared even after the server returned and the browser's own EventSource had reconnected, because only a resync clears the status. Attempts now retry on a 3/6/12/30s backoff until one re-seeds the state, and a stream that merely looks OPEN no longer ends the chain. One createWakeRecovery serves both engines, so od/si and EK host/viewer share it. Also dope's first favicon: the 1080px logo as a 6.7KB multi-size ico.
dope served no icon at all, so every tab wore the browser's blank-page glyph.
The source logo is 1080px of PNG — far more than a tab needs — so it becomes a
multi-size ico (16/32/48) trimmed to the glyphs, transparency kept.

Served at the conventional root path through a new webassets.ServeRoot, so it
inherits the cache policy, the ETag and the disk-mode reload the rest of
/static already has. At 16px the four-letter grid is mush; 32 and up read fine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
iOS freezes a backgrounded tab and silently kills the SSE socket. Recovery ran
exactly once per wake event, so a tab woken while the radio is still down failed
that one attempt with no further event coming — the sync dot spun on
Переподключение until a manual reload. Reproduced on an OD viewer: with the
server down at wake time the dot never cleared, not even after the server
returned and the browser's own EventSource had reconnected, because only a
resync clears the status.

So attempts now retry on a 3/6/12/30s backoff until one actually re-seeds, and
a stream that merely looks OPEN no longer ends the chain — a natively
reconnected socket still leaves the page on state it never refetched. One
createWakeRecovery for both engines, so od/si and EK host/viewer share it
(ADR-0003's single-engine seam), with the tab/network listeners it owns.

The resync fetch also gets a 20s deadline: a frozen tab can leave it hanging
with no reply and no error, and deltas are dropped while a resync is in flight,
so a stuck refetch wedged the page for good.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
pecheny/dopesuite!29
No description provided.