mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-21 07:41:28 +02:00
Nine bugs found by a cloud review scoped to the celery engine and the stage orchestration (46 files, 7,790 lines). Stuck scans: - run_stage did load_resolved(), the Stage construction and should_run() OUTSIDE the try/except, after committing a RUNNING activity. A raise there — a stage config model that moved under a queued scan, a constructor failure — left the row RUNNING for ever, so aggregate_status kept returning RUNNING and finalize deferred; the link_error calls the same finalize, so it never rescued it. The setup now runs inside the same handler, and the post-run bookkeeping is wrapped too: recording a result must never be what fails a finished stage. - _fail_stage crashed on a missing activity row (a cascade-deleted scan), and its own except-branch called finish() with the same None and raised again. Stage failures that were not failures: - the abort poll opened a session on a path stages hit in tight loops and let any database error propagate, so a pool blip failed a running stage. It now fails open and keeps the last answer, like the Redis guards. Wrong accounts of a run: - finalize picked the scan's error with `next(a for a in activities if a.error)`, ignoring status over an unordered fetch — so a FAILED scan reported "superseded by stage retry" or a PARTIAL warning instead of the failure. Only a FAILED row may explain a failure. - _undispatched compared the activity ROW count to the stage count, so one retried stage (which leaves a superseded row plus a new one) cancelled out one genuinely undispatched stage and the scan reported COMPLETED with a stage missing. It compares stage names now. - endpoint_probe counted static endpoints excluded by skip_static as budget-skipped, so the coverage warning claimed a cap that was never hit. Work done twice, and work undone: - reap_stalled resumed the whole level, re-running stages whose activity was already SUCCESS: a finished hour-long stage ran again because a level-mate stalled, and if the second run failed the whole scan failed. build_canvas takes the set of finished stages and omits them (an emptied level is dropped); the done=None path is byte-identical to before. - run_scan read the scan without a lock and committed status=RUNNING plus a fresh celery_task_ids over whatever was there, so an API cancel landing in that window was silently overwritten and the ids it needed to revoke were lost. finalize already row-locks; run_scan now does too. - _write_temp_file called os.close(fd) after os.fdopen had already closed it, masking the real write error with EBADF and, in the threaded stages, risking a close of another thread's reused descriptor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SAeBy7TBUn3Fd1ckyQp9r6