Skip to content

feat: edge fan-out for market data — publish once, serve every viewer from Cloudflare#84

Merged
emrebulutlar merged 1 commit into
mainfrom
feat/market-edge-relay
Jul 7, 2026
Merged

feat: edge fan-out for market data — publish once, serve every viewer from Cloudflare#84
emrebulutlar merged 1 commit into
mainfrom
feat/market-edge-relay

Conversation

@emrebulutlar

Copy link
Copy Markdown
Member

The public market WS pushed a full stream copy per viewer through the box's ~5 Mbit/s uplink (saturation around 40-60 viewers). This adds an edge relay: the gateway publishes each broadcast frame ONCE to a Cloudflare Durable Object, which fans out to all viewers at the edge. Origin upload becomes flat in viewer count.

edge/market-relay (Worker + MarketFeed DO, WebSocket Hibernation API): speaks the exact /ws viewer protocol so trading-ui connects unchanged; caches book snapshot / ticker / recent trades / 1m candle history per market for subscribe-time bootstrap; replays buffered deltas so the bookVersion chain is gapless for late joiners; /publish is bearer-gated; /healthz for ops. 12 tests via vitest-pool-workers.

EdgePublisher (opt-in: MARKET_EDGE_URL + MARKET_EDGE_TOKEN(_FILE)): outbound Netty WS client, reconnect backoff, drop-oldest bounded queue (snapshot-recoverable stream, same rationale as writeOrConflate), periodic EDGE_CACHE bundles. Tees at broadcastMarketData (before the local-viewer early-out) and the ClusterStatus broadcasts. Disabled = zero behavior change.

Verified live on the deployed Worker: real gateway publishing with 0 drops, chain-verified viewer E2E (40 deltas, 0 gaps), full trading-ui session over the relay with no console errors.

Cutover plan (separate step): route market.openexch.io/ws* to the Worker; REST stays on the tunnel; rollback = remove the route.

🤖 Generated with Claude Code

… from Cloudflare

The public WS previously pushed a full copy of the market stream per
viewer through the box's ~5 Mbit/s uplink (~40-60 concurrent viewers to
saturation). Now the gateway tees each broadcast frame once to a
Durable Object relay (edge/market-relay) which fans out at the edge:
origin upload is flat in viewer count.

- edge/market-relay: Worker + MarketFeed DO (WebSocket Hibernation API).
  Speaks the exact /ws viewer protocol; caches book snapshot, ticker,
  recent trades, and 1m candle history per market for subscribe-time
  bootstrap; replays buffered deltas so the bookVersion chain stays
  gapless for late joiners; /publish is bearer-token gated; /healthz
  exposes relay stats. 12 vitest-pool-workers tests.
- EdgePublisher (opt-in via MARKET_EDGE_URL + MARKET_EDGE_TOKEN(_FILE)):
  outbound Netty WS client with reconnect backoff and a drop-oldest
  queue, plus periodic EDGE_CACHE bundles from cached gateway state.
- Tee points: broadcastMarketData (before the local-viewer early-out)
  and the ClusterStatus broadcasts.

Verified live: real gateway publishing (0 drops), synthetic + live
viewer E2E chain-verified over the deployed Worker, and the full
trading-ui running against the relay with zero console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@emrebulutlar
emrebulutlar merged commit 042df21 into main Jul 7, 2026
2 checks passed
@emrebulutlar
emrebulutlar deleted the feat/market-edge-relay branch July 7, 2026 12:25
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.

1 participant