Skip to content

feat(ActiveJob): Un-failing resets execution log - #124

Open
smudge wants to merge 1 commit into
smudge/stack/6from
smudge/stack/7
Open

feat(ActiveJob): Un-failing resets execution log#124
smudge wants to merge 1 commit into
smudge/stack/6from
smudge/stack/7

Conversation

@smudge

@smudge smudge commented Aug 4, 2026

Copy link
Copy Markdown
Member

Previously, when a job's retry_on attempts ran out (resulting in a permanently failed job), un-failing that job would only allow for a single attempt, rather than resetting the attempts counter.

For non-ActiveJobs, we can reset attempts back to 0, but ActiveJobs have no equivalent SQL command and can only be reset via reserializing the job handler in Ruby (making this operation somewhat hostile to bulk operations). This PR aims to address that by checking if an ActiveJob was un-failed, and if so then checking if attempts was set to zero.

ActiveJob has no persisted concept of a terminal failure state (i.e. this gem's failed_at column), so this gem also extends the serialized payload to include a terminated_at key, which survives the round trip as we do not need ActiveJob to reserialize this value when we un-fail jobs.

smudge added a commit that referenced this pull request Aug 4, 2026
Previously, when a job's `retry_on` attempts ran out (resulting in a permanently failed job), un-failing that job would only allow for a single attempt, rather than resetting the attempts counter.

For non-ActiveJobs, we can reset `attempts` back to `0`, but ActiveJobs have no equivalent SQL command and can only be reset via reserializing the job handler in Ruby (making this operation somewhat hostile to bulk operations). This PR aims to address that by checking if an ActiveJob was un-failed, and if so then checking if `attempts` was set to zero.

ActiveJob has no persisted concept of a terminal failure state (i.e. this gem's `failed_at` column), so this gem also extends the serialized payload to include a `terminated_at` key, which survives the round trip as we do not need ActiveJob to reserialize this value when we un-fail jobs.

stack-info: PR: #124, branch: smudge/stack/7
@smudge
smudge marked this pull request as draft August 4, 2026 23:14
@smudge
smudge changed the base branch from smudge/stack/6 to main August 4, 2026 23:14
smudge added a commit that referenced this pull request Aug 4, 2026
Previously, when a job's `retry_on` attempts ran out (resulting in a permanently failed job), un-failing that job would only allow for a single attempt, rather than resetting the attempts counter.

For non-ActiveJobs, we can reset `attempts` back to `0`, but ActiveJobs have no equivalent SQL command and can only be reset via reserializing the job handler in Ruby (making this operation somewhat hostile to bulk operations). This PR aims to address that by checking if an ActiveJob was un-failed, and if so then checking if `attempts` was set to zero.

ActiveJob has no persisted concept of a terminal failure state (i.e. this gem's `failed_at` column), so this gem also extends the serialized payload to include a `terminated_at` key, which survives the round trip as we do not need ActiveJob to reserialize this value when we un-fail jobs.

stack-info: PR: #124, branch: smudge/stack/7
@smudge
smudge changed the base branch from main to smudge/stack/6 August 4, 2026 23:14
@smudge
smudge marked this pull request as ready for review August 4, 2026 23:14
Previously, when a job's `retry_on` attempts ran out (resulting in an error raised to the worker, and eventually a permanently-failed job), un-failing that job would only allow for a single attempt, rather than restoring the job's `retry_on` budget.

For non-ActiveJobs, we can reset `attempts` back to `0`, but ActiveJobs have no equivalent SQL command and can only be reset via reserializing the job handler in Ruby (making this operation somewhat hostile to bulk operations). This PR aims to address that by checking if an ActiveJob was terminated, and if so then checking if `attempts` was set to zero.

ActiveJob has no persisted concept of a terminal failure state (i.e. this gem's `failed_at` column), so this gem extends the serialized payload with a `terminated_at` key. JobWrapper's `error` hook stamps it at the moment an error escapes ActiveJob's own retry machinery (i.e. the job exceeded ActiveJob's execution budget — 1 by default, or as configured by `retry_on`), marking the handoff to the worker's own retry backstop. The wrapper's `before` hook then resets `executions`/`exception_executions` whenever the marker is present and the row's `attempts` is zero, which can only occur via operator intervention.

stack-info: PR: #124, branch: smudge/stack/7
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