Skip to content

fix: respawn panicked solver workers instead of losing them - #348

Draft
zizou0x wants to merge 1 commit into
mainfrom
zz/respawn-panicked-workers
Draft

fix: respawn panicked solver workers instead of losing them#348
zizou0x wants to merge 1 commit into
mainfrom
zz/respawn-panicked-workers

Conversation

@zizou0x

@zizou0x zizou0x commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

What

spawn_workers_generic now runs each worker thread as a loop of sessions wrapped in catch_unwind:

  • a panic during a session is logged at ERROR (pool, algorithm, worker_id, panic message) and counted in a new worker_pool_worker_panics_total{pool} counter, then the worker is respawned after a 100ms backoff (prevents a hot loop if initialization panics deterministically)
  • a clean exit (shutdown signal, closed channels) still ends the thread
  • a shutdown sent while a worker is between sessions is not lost: a receiver subscribed before the thread starts buffers it, and the loop checks it before each respawn

Each session gets fresh event/derived/shutdown receivers and rebuilds the worker (including graph initialization), same as the existing lag-recovery path.

Why

Prod incident 2026-07-23: a quote request triggered a div-by-zero panic in pool math. Each occurrence silently killed one solver worker thread — the panic was only logged at shutdown join(), ~100 minutes later. After all workers on both ethereum pods died, every quote returned no_route_found for ~1.5h until the pods were recreated.

Complements #347 (which stops that specific panic from escaping the simulation call); this PR makes the pool survive any panic that still gets through.

Tests

  • worker_respawns_after_panic_and_processes_next_task: a worker that panics on a poison order answers the next task, and the pool still shuts down cleanly

🤖 Generated with Claude Code

A panic while solving previously unwound through the worker thread and
killed it silently; the pool only noticed at shutdown join(). Once every
worker had hit a poison request, the pool answered 100% no_route until
the pod was recreated.

Each worker thread now runs sessions in a catch_unwind loop: a panic is
logged at ERROR with the panic message, counted in the
worker_pool_worker_panics_total metric, and the worker is respawned
after a short backoff. Clean shutdowns still exit the thread, including
shutdown signals arriving while a worker is mid-respawn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@brunoguerios
brunoguerios self-requested a review July 24, 2026 12:49
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