Skip to content

Claude/great hawking al4kaa - #4

Merged
mikechabot merged 4 commits into
mainfrom
claude/great-hawking-al4kaa
Jul 7, 2026
Merged

Claude/great hawking al4kaa#4
mikechabot merged 4 commits into
mainfrom
claude/great-hawking-al4kaa

Conversation

@mikechabot

Copy link
Copy Markdown
Member

No description provided.

claude and others added 4 commits July 6, 2026 16:30
Next.js monkey-patches the global fetch with caching layers that clone
the response and buffer its entire body — the Data Cache in production,
and an HMR cache in `next dev` that buffers even `cache: 'no-store'`
requests. An SSE body never ends, so the buffered clone grows until the
connection drops (e.g. Cloudflare terminating a long-lived socket), at
which point Next.js logs:

  Failed to set fetch cache <url> TypeError: terminated
    [cause]: SocketError: other side closed (UND_ERR_SOCKET)

Prefer the original, un-patched fetch that Next.js exposes on the
patched function (`_nextOriginalFetch`) when connecting the EventSource.
A background SSE connection should not participate in render caching or
dynamic tracking anyway. Falls back to the global fetch everywhere else.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XHpkNV7Bi4SHg4cjon8HqP
Flag deletes and creates never took effect in a running SDK: the memory
store only spread-merged incoming sets, and the SSE stream only carried
partial updates. This wires the SDK up to the full-set sync the backends
now provide on every sync path:

- memory-manager gains replace(), which drops flags absent from the
  incoming set — the only way deletes can propagate. A new internal
  UPDATE_RECEIVED_FULL event routes full sets to it; UPDATE_RECEIVED
  stays merge-based for legacy partial updates.
- stream-manager listens for the named "flags" SSE event (full ruleset,
  replace semantics) and ignores legacy partial messages once full-set
  support is observed, so a change is not applied twice.
- stream-manager consumes the server's 25s "heartbeat" events to drive
  a staleness watchdog that restarts half-dead connections no error
  event would ever surface.
- On reconnect, the stream manager refetches /sdk/rules and replaces
  the store, recovering updates emitted while disconnected (there is
  no server-side replay).
- ws-manager and poll-manager switch to UPDATE_RECEIVED_FULL: Sunrise
  always pushes the entire ruleset and polling always fetches it, so
  both were already full sets being incorrectly merged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XHpkNV7Bi4SHg4cjon8HqP
kill() only closed the socket when readyState was OPEN and never cleared
a pending reconnect timer. A SIGINT landing while the socket was
reconnecting (or mid-handshake) left the timer alive, which then opened
a fresh connection after shutdown — pinning the event loop and hanging
Ctrl-C until force-killed.

kill() now clears the reconnect timer, guards future reconnects with a
killed flag, and tears the socket down in any state (terminate() during
CONNECTING to avoid a noisy handshake-abort error; close(1000) when
OPEN).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XHpkNV7Bi4SHg4cjon8HqP
@mikechabot
mikechabot merged commit ea540fa into main Jul 7, 2026
3 checks passed
@mikechabot
mikechabot deleted the claude/great-hawking-al4kaa branch July 7, 2026 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants