AI disclosure
I encountered this issue in my deployment. This issue report was prepared with assistance from AI.
Description
The RQ watchdog cleanup path introduced for #106 calls StartedJobRegistry.remove(task_id). In current RQ 2.x, StartedJobRegistry.remove() is intentionally unimplemented and raises NotImplementedError.
With docling-jobkit==3.4.0 and rq==2.11.0, an orphaned worker is detected and the task is published as FAILURE, but cleanup then fails:
Failed to clean up RQ state for task ...
NotImplementedError
The job remains in rq:wip:{queue}, so the watchdog can rediscover it and emit repeated warnings.
Deterministic reproduction
The underlying RQ failure can be reproduced without Redis:
uv run python -c "from rq.registry import StartedJobRegistry; StartedJobRegistry(name='convert', connection=None).remove('repro-task')"
This raises NotImplementedError because StartedJobRegistry.remove() is abstract in RQ 2.x.
Watchdog reproduction
- Run
docling-jobkit 3.4.0 with RQ 2.x.
- Let a
SimpleWorker job lose its heartbeat, or reproduce the watchdog branch with a missing heartbeat key and a started-job registry entry.
- Wait for
_watchdog_task() to process the orphaned task.
- Observe the
StartedJobRegistry.remove() NotImplementedError in the cleanup traceback.
Expected behavior
The watchdog should set the RQ job to FAILED and remove its started execution entry without raising. Missing or already-expired jobs should remain a non-fatal cleanup case.
Proposed fix
Use the RQ execution-aware cleanup API, such as StartedJobRegistry.remove_executions(job), after fetching the job, and add a regression test covering the cleanup path. This is a follow-up to the implementation released for #106.
Environment
- docling-jobkit 3.4.0
- rq 2.11.0
- Python 3.12 or 3.13
AI disclosure
I encountered this issue in my deployment. This issue report was prepared with assistance from AI.
Description
The RQ watchdog cleanup path introduced for #106 calls
StartedJobRegistry.remove(task_id). In current RQ 2.x,StartedJobRegistry.remove()is intentionally unimplemented and raisesNotImplementedError.With
docling-jobkit==3.4.0andrq==2.11.0, an orphaned worker is detected and the task is published asFAILURE, but cleanup then fails:The job remains in
rq:wip:{queue}, so the watchdog can rediscover it and emit repeated warnings.Deterministic reproduction
The underlying RQ failure can be reproduced without Redis:
uv run python -c "from rq.registry import StartedJobRegistry; StartedJobRegistry(name='convert', connection=None).remove('repro-task')"This raises
NotImplementedErrorbecauseStartedJobRegistry.remove()is abstract in RQ 2.x.Watchdog reproduction
docling-jobkit 3.4.0with RQ 2.x.SimpleWorkerjob lose its heartbeat, or reproduce the watchdog branch with a missing heartbeat key and a started-job registry entry._watchdog_task()to process the orphaned task.StartedJobRegistry.remove()NotImplementedErrorin the cleanup traceback.Expected behavior
The watchdog should set the RQ job to
FAILEDand remove its started execution entry without raising. Missing or already-expired jobs should remain a non-fatal cleanup case.Proposed fix
Use the RQ execution-aware cleanup API, such as
StartedJobRegistry.remove_executions(job), after fetching the job, and add a regression test covering the cleanup path. This is a follow-up to the implementation released for #106.Environment