Lifecycle Callbacks
Three lifecycle callbacks fire when a pipeline reaches a terminal state.
Defining callbacks
Register callbacks as class-level methods that name instance methods to invoke:
class VideoProcessingPipeline < GoodPipeline::Pipeline
on_complete :notify_complete # fires on any terminal state
on_success :notify_success # fires on succeeded
on_failure :notify_failure # fires on failed or halted
def configure(video_id:)
run :download, DownloadJob, with: { video_id: video_id }
end
private
def notify_complete
Rails.logger.info("Pipeline #{id} finished with status: #{status}")
end
def notify_success
Slack.notify("Pipeline #{id} succeeded for video #{params[:video_id]}")
end
def notify_failure
Slack.notify("Pipeline #{id} failed for video #{params[:video_id]}")
end
endWhen each callback fires
| Callback | Fires when pipeline status is |
|---|---|
on_complete | succeeded, failed, halted, or skipped |
on_success | succeeded |
on_failure | failed or halted |
Note: on_failure does not fire for skipped pipelines. Being skipped by a chain is not considered a failure — only on_complete fires in that case.
Asynchronous dispatch
Callbacks are dispatched via PipelineCallbackJob, a GoodJob job enqueued after the terminal state transaction commits. A slow external call (Slack, webhooks) cannot stall the coordinator, callback execution cannot corrupt pipeline state, and callbacks get GoodJob's retry mechanism if they fail.
PipelineCallbackJob runs on the queue configured by callback_queue_name (default: "good_pipeline_callbacks"). This is separate from coordination_queue_name which controls the coordination jobs (StepFinishedJob, PipelineReconciliationJob), so slow callbacks don't block pipeline progression. See Defining Pipelines for configuration options.
Exactly-once guarantee
The callback bundle (on_complete + one of on_success/on_failure) is dispatched as a single unit. A callbacks_dispatched_at timestamp is set atomically inside a FOR UPDATE locked transaction, ensuring the bundle fires exactly once even if recompute_pipeline_status is called from multiple code paths (coordinator or batch reconciliation).
Callback failure isolation
If a callback method raises an error:
- The
PipelineCallbackJobfails and is retried by GoodJob - Pipeline status and step statuses are not affected
- The pipeline remains in its terminal state
- Other callback methods in the same bundle are still attempted
A callback failure never reopens or alters the terminal pipeline record.