Cancel jobs that have not yet finished successfully.

API

{:ok, cancelled} = Kathikon.cancel(job_id)
cancelled.state        # :cancelled
cancelled.cancelled_at # DateTime.utc_now() at cancel time

Cancellable states

StateCan cancel?
:scheduledYes
:availableYes
:retryableYes
:runningNo{:error, :executing} (legacy error name)
:claimedYes
:failedNo
:deadNo
:waiting_for_childrenNo
:completedNo{:error, {:invalid_state, :completed}}
:cancelledNo{:error, {:invalid_state, :cancelled}}
:discardedNo{:error, {:invalid_state, :discarded}}

Running jobs are not interrupted in v0.2.0. A job already in :running will finish even if you need to cancel it — design workers for short tasks or add cancellation checks in a future release.

Example: cancel a scheduled newsletter

{:ok, job} =
  Kathikon.insert(NewsletterWorker, %{"list" => "monthly"},
    schedule_in: 86_400
  )

# User unsubscribes before send
{:ok, cancelled} = Kathikon.cancel(job.id)

Example: double cancel

Kathikon.cancel(job_id)
# {:ok, %Job{state: :cancelled, ...}}

Kathikon.cancel(job_id)
# {:error, {:invalid_state, :cancelled}}

Pruning

Cancelled jobs are terminal. The pruner deletes them after retention_period.

Telemetry

[:kathikon, :job, :cancel] with metadata %{queue: ..., job_id: ...}.