Module: ActiveJob::Temporal::Cancel

Defined in:
lib/activejob/temporal/cancel.rb,
lib/activejob/temporal/cancel/batch_summary.rb,
lib/activejob/temporal/cancel/batch_canceller.rb

Overview

Note:

Best-Effort Semantics Temporal cancellation is cooperative, not forceful. Activities must check for cancellation by heartbeating or polling ‘Temporalio::Activity::Context.current.cancelled?`. Activities that do not check for cancellation will run to completion even after a cancel request.

Note:

Query Strategy This module queries running workflows first, then closed workflows (completed, failed, cancelled, etc.) to determine the workflow state before issuing a cancellation request. This ensures idempotent cancellation behavior.

Job cancellation with query-based workflow discovery.

This module provides cancellation capabilities for ActiveJob workflows running on Temporal. Cancellation is asynchronous and best-effort: workflows will stop only if they are actively checking for cancellation signals (via heartbeating or cancellation checks).

Examples:

Cancel a running job

ActiveJob::Temporal.cancel(SendInvoiceJob, "550e8400-e29b-41d4-a716-446655440000")

See Also:

Defined Under Namespace

Classes: BatchCanceller, BatchSummary

Constant Summary collapse

UUID_REGEX =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

UUID format regex (compliant with RFC 4122). Matches standard UUID format: 8-4-4-4-12 hexadecimal characters.

/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i

Class Method Summary collapse

Class Method Details

.cancel(job_class, job_id) ⇒ Boolean?

Note:

Asynchronous Cancellation Cancellation requests are asynchronous. The method returns immediately after sending the request. The workflow will stop only if it checks for cancellation.

Cancels a running Temporal workflow by sending a cancellation request.

This method first queries Temporal to determine the workflow state before attempting cancellation. It will not cancel already-completed workflows.

Examples:

Cancel a running job

result = ActiveJob::Temporal.cancel(SendInvoiceJob, "550e8400-e29b-41d4-a716-446655440000")
puts "Cancellation requested" if result.nil?

Handle all outcomes

begin
  result = ActiveJob::Temporal.cancel(MyJob, "abc-123")
  case result
  when false
    puts "Job already completed, cannot cancel"
  when nil
    puts "Cancellation sent to Temporal"
  end
rescue ActiveJob::Temporal::WorkflowNotFoundError
  puts "Job never existed or already removed from history"
rescue ActiveJob::Temporal::TemporalConnectionError => e
  puts "Cannot reach Temporal: #{e.message}"
end

Parameters:

  • job_class (Class)

    The ActiveJob class for the job to cancel.

  • job_id (String)

    Identifier of the job to cancel.

Returns:

  • (Boolean, nil)

    Returns false if workflow already completed, nil if cancellation requested

Raises:

See Also:

  • #find_workflow


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/activejob/temporal/cancel.rb', line 67

def cancel(job_class, job_id)
  validate_job_id!(job_id)
  client = ActiveJob::Temporal.client
  workflow_state = find_workflow(client, job_class, job_id)
  workflow_id = workflow_state[:workflow_id]

  case workflow_state[:status]
  when :closed
    log_workflow_already_completed(job_class, job_id, workflow_id)
    false
  when :not_found
    raise ActiveJob::Temporal::WorkflowNotFoundError,
          "No workflow found for job_id #{job_id}. The job may have never existed."
  when :running
    client.workflow_handle(workflow_id).cancel
    log_cancellation_requested(job_class, job_id, workflow_id)
    log_audit_cancellation_requested(job_class, job_id, workflow_id)
    nil
  end
end

.cancel_all(job_class) ⇒ Object



88
89
90
91
92
# File 'lib/activejob/temporal/cancel.rb', line 88

def cancel_all(job_class)
  validate_job_class!(job_class)

  cancel_where(ajClass: job_class.name)
end

.cancel_where(filters) ⇒ Object



94
95
96
# File 'lib/activejob/temporal/cancel.rb', line 94

def cancel_where(filters)
  BatchCanceller.new(ActiveJob::Temporal.client).cancel_where(filters)
end