Skip to content

perf(cluster): low-latency event channel for proof status#96

Open
tamirhemo wants to merge 6 commits into
mainfrom
tamir/streaming
Open

perf(cluster): low-latency event channel for proof status#96
tamirhemo wants to merge 6 commits into
mainfrom
tamir/streaming

Conversation

@tamirhemo

@tamirhemo tamirhemo commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

End state: a self-hosted gateway proof finishes within milliseconds of the cluster completing it (vs. up to ~2s before). Replaces the cluster's polling chain with a Postgres LISTEN/NOTIFY push from the api → coordinator + gateway → SDK.

Summary

  • Migration: AFTER INSERT/UPDATE trigger on proof_requests emits pg_notify('proof_event', json).
  • bin/api: new ClusterEventsService.SubscribeProofEvents server-stream, fed by one PgListener + tokio::sync::broadcast. Local proto inside sp1-cluster — no sp1-prover-types change required.
  • bin/coordinator: 500ms ProofRequestList poll → event-driven claim_one(proof_id) (single-row fetch). Safety-net poll keeps a 1s reconcile path for missed NOTIFYs.
  • bin/network-gateway:
    • ProofEventsHub demuxes the stream into per-proof_id broadcast::Senders. Bounded by terminal-publish eviction + RAII drop on idle.
    • get_proof_request_status long-polls (up to 25s) on the hub before returning. No SDK change, no proto change — the SDK's existing wait_proof loop just observes "the call took longer to return," and mainnet's handler still returns immediately so polling clients are 100% unaffected.

Verification

INSERT proof_requests → coordinator dispatch in ~2ms, gateway sees Pending+Failed transitions in ~3.5ms (synthetic test on the running cluster).

End-to-end: cluster pickup ~5ms (was 0–500ms), SDK observes terminal status ~5ms after the cluster commits it (was 0–2000ms).

🤖 Generated with Claude Code

@tamirhemo tamirhemo changed the title perf(cluster): NOTIFY-driven proof event stream (Lever 1+2) perf(cluster): NOTIFY-driven proof event stream Apr 28, 2026
@tamirhemo tamirhemo changed the base branch from tamir/hosted-service to main April 28, 2026 18:45
@tamirhemo tamirhemo changed the title perf(cluster): NOTIFY-driven proof event stream perf(cluster): low-latency event channel + gpu-node parity with sp1-gpu Apr 29, 2026
tamirhemo and others added 6 commits April 29, 2026 06:03
Replaces the coordinator's 500ms ProofRequestList polling with a
Postgres LISTEN/NOTIFY-driven push channel. Cluster-internal pickup
latency drops from 0–500ms to ~5ms. Sets up the gateway-side hub the
SDK long-poll RPC will subscribe to next.

Wiring (api -> coordinator + gateway):
  - migrations/20260427... : AFTER INSERT/UPDATE trigger on
    proof_requests emits pg_notify('proof_event', json_payload).
  - bin/api: ClusterEventsService.SubscribeProofEvents server-streams
    those events, fed by a single PgListener + tokio broadcast.
  - bin/coordinator: claim_one(proof_id) on each Pending event using
    a single-row ProofRequestGet (O(1) per event vs the old O(N)
    full list). Safety-net loop drops to 1s and now only runs the
    full list+reconcile path; event-driven path skips reconcile.
  - bin/network-gateway: ProofEventsHub demuxes the stream into
    per-proof_id broadcast::Senders. Empty today; Lever 3's long-poll
    will subscribe per request_id.

Local proto only — cluster_events.proto lives in sp1-cluster, not
sp1-prover-types, so this ships without a sp1 release.

Verified live on the running cluster: INSERT -> coordinator claim in
~2ms, INSERT -> gateway sees Pending+Failed transitions in ~3.5ms.

Known follow-ups:
  - Gateway hub never garbage-collects per-proof Senders. The forget()
    hook is in place but unused until Lever 3 wires the long-poll.
  - SDK still polls every 2s; that's Lever 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Holds the existing get_proof_request_status RPC open until the proof
transitions out of its current state, or 25s elapses (well under the
SDK's 60s tonic per-RPC deadline at crates/sdk/src/network/grpc.rs:9).
Mainnet is unaffected — only the gateway's server-side handler
changes; the SDK's polling loop, the proto, and request/response
types are all untouched.

Subscribes to ProofEventsHub before fetching the row to close the
race where a transition fires between SELECT and recv. Recovers
cleanly from broadcast lag by re-fetching.

Combined with the cluster-internal NOTIFY chain already on this
branch, the SDK now sees terminal status within ~5ms of the
coordinator updating it, instead of 0–2s on the next polling tick.
For sub-1s proofs this is the difference between a 200ms proof
returning at 200ms and at ~2.2s.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two cleanup paths so the in-process channel map can't grow unbounded:

1. Terminal-publish: when the api-fed event stream broadcasts a
   terminal cluster status (Completed/Failed/Cancelled), drop the
   per-proof entry immediately after the send. No further NOTIFY
   events will fire for that proof_id, so the channel is dead weight.
   Subscribers still attached drain any buffered values and observe
   Closed on the next recv.

2. Drop-on-idle: subscribe() now returns a Subscription RAII guard.
   On drop, it decrements receiver_count and asks the hub to GC the
   entry iff no receivers remain (DashMap::remove_if locks the bucket
   so a concurrent subscribe can't sneak a receiver in between the
   count check and the removal). Catches the case where someone
   subscribes to an already-terminal proof — terminal-publish can't
   fire a second time, so without this the entry would leak.

Tests cover create/drop, multi-subscriber, terminal eviction with
active receiver, non-terminal keep-alive, post-drop subscribe, and
basic recv flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tamirhemo tamirhemo changed the title perf(cluster): low-latency event channel + gpu-node parity with sp1-gpu perf(cluster): low-latency event channel for proof status Apr 29, 2026
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