Skip to content

Detect and recover from crashed/unresponsive worker processes#283

Merged
knipknap merged 2 commits into
mainfrom
fix/tasker-worker-crash-detection
Jun 8, 2026
Merged

Detect and recover from crashed/unresponsive worker processes#283
knipknap merged 2 commits into
mainfrom
fix/tasker-worker-crash-detection

Conversation

@knipknap

@knipknap knipknap commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Worker pool improvements to detect and recover from crashed or unresponsive worker processes.

Worker crash detection

  • Workers track their active task in a DictProxy (_wpool:{pid}) which survives result queue corruption from crashed peers
  • The listener health check (every ~1s) detects dead workers via is_alive() and emits worker_died signals for orphaned task cleanup
  • Poisoned result queue detection: if no results arrive for 3s while workers have DictProxy entries, all stuck workers are terminated and restarted
  • Per-worker timeout: individual workers running tasks for >30s are terminated (catches cases where one worker crashes silently while others keep the global timer fresh)

Early cancel check

  • Workers check the cancel flag before running user_func, skipping already-cancelled tasks immediately. This prevents stale cancelled tasks from blocking the queue and starving current-generation tasks.

Infrastructure

  • Workers send a "running" message with PID on task start, enabling _worker_start_time tracking
  • _spawn_replacement_worker() / _terminate_stuck_worker() for worker lifecycle management
  • worker_died signal connected to TaskManager for orphan finalization
  • _pid_to_worker / _worker_task_map tracking for health checks

Files

  • rayforge/shared/tasker/pool.py — health checks, stuck worker termination, early cancel, running message
  • rayforge/shared/tasker/manager.py_on_pool_worker_died handler
  • tests/tasker/test_pool.py — updated cancel test to accept pre-emptive skip

knipknap added 2 commits June 8, 2026 22:18
Workers track their active task in a DictProxy (survives result queue
corruption from crashed peers). The listener health check detects:
- Dead workers via is_alive() — emits worker_died for orphan cleanup
- Poisoned result queues (no results for 3s) — restarts all stuck workers
- Per-worker timeouts (30s) — terminates unresponsive workers individually

Workers now send a 'running' message with their PID so per-worker start
times are tracked. Cancelled tasks are skipped early in the worker loop
before running user_func, preventing stale tasks from blocking the queue.
Replacement workers are spawned automatically.
The early cancellation check (workers skip already-cancelled tasks) is
the proper root cause fix: it prevents cancelled tasks from blocking
workers during rapid pipeline invalidations. The poisoned queue and
per-worker timeout detections masked this issue rather than fixing it.
@knipknap
knipknap force-pushed the fix/tasker-worker-crash-detection branch from 9665c18 to 107c686 Compare June 8, 2026 20:20
@knipknap
knipknap merged commit 20c2e8b into main Jun 8, 2026
29 checks passed
@knipknap
knipknap deleted the fix/tasker-worker-crash-detection branch June 12, 2026 11:19
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