Class: Rubino::API::Operations::Tasks::StopOperation

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/api/operations/tasks/stop_operation.rb

Overview

POST /v1/tasks/:id/stop Cancels a running background subagent — the HTTP twin of the ‘task_stop` tool. Flips the child Runner’s CancelToken (the same mechanism the top-level run stop-watcher uses), which unwinds the child loop cooperatively at its next cancel checkpoint.

Cancellation is asynchronous: this returns the entry’s CURRENT snapshot, so ‘status` may still read “running” until the worker thread reaches a checkpoint and records its terminal (cancelled/failed) state. Poll GET /v1/tasks/:id to observe the transition.

Raises:

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(registry: nil) ⇒ StopOperation

Accepts an alternate registry for tests.



26
27
28
# File 'lib/rubino/api/operations/tasks/stop_operation.rb', line 26

def initialize(registry: nil)
  @registry = registry || ::Rubino::Tools::BackgroundTasks.instance
end

Class Method Details

.call(request) ⇒ Object



21
22
23
# File 'lib/rubino/api/operations/tasks/stop_operation.rb', line 21

def self.call(request)
  new.call(request)
end

Instance Method Details

#call(request) ⇒ Object

Raises:



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rubino/api/operations/tasks/stop_operation.rb', line 30

def call(request)
  id = request.params.fetch("id")
  entry = @registry.find(id)
  raise NotFoundError.new("task", id) unless entry

  raise ConflictError, "task #{id} already #{entry.status} — nothing to stop" unless entry.status == :running

  entry.runner&.cancel!
  # Stop-cascade (S5a): wake any descendant parked on a blocking
  # ask_parent so the whole subtree unwinds at once.
  @registry.cancel_descendant_ask_gates(id)
  [202, Serializer.detail(entry)]
end