Class: Insika::Commands::CancelTask

Inherits:
Object
  • Object
show all
Defined in:
lib/insika/commands/cancel_task.rb

Overview

Control command: posts :cancel to the Task's in-process mailbox and responds synchronously. Payload { task_id: String } -> returns Task.

Cancellation is COOPERATIVE: the one that transitions the status is the task's fiber when it drains the mailbox — NEVER this handler. Cancelling a task with no live fiber (terminal or orphaned) is an idempotent no-op.

Instance Method Summary collapse

Constructor Details

#initialize(task_store:, executor:) ⇒ CancelTask

executor: object with #cancel(task_id) — the real implementation is @running[task_id]&.post(:cancel); here it's a contract (duck type).



14
15
16
17
# File 'lib/insika/commands/cancel_task.rb', line 14

def initialize(task_store:, executor:)
  @task_store = task_store
  @executor = executor
end

Instance Method Details

#call(command) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/insika/commands/cancel_task.rb', line 19

def call(command)
  task_id = command.payload[:task_id] || command.payload["task_id"]
  raise Insika::ValidationError, "task_id is required" if task_id.to_s.empty?

  task = @task_store.find(task_id)
  raise Insika::NotFoundError, "task '#{task_id}' not found" unless task

  @executor.cancel(task_id) # no-op if there is no live fiber in this process
  # Does not transition status nor touch the persisted mailbox_state: it only uses
  # the in-process mailbox (Async::Queue). Returns the current state after the post.
  @task_store.find(task_id)
end