Class: Phronomy::CancellationScope
- Inherits:
-
Object
- Object
- Phronomy::CancellationScope
- Defined in:
- lib/phronomy/cancellation_scope.rb
Overview
Represents a bounded execution scope that owns a CancellationToken and optionally a Deadline.
+CancellationScope+ replaces ad-hoc +Timeout.timeout+ calls in agent and tool code. All work performed within a scope should observe the scope's token; when the scope is cancelled (explicitly or by deadline expiry) the token is cancelled and all child tasks that check it will stop.
Instance Attribute Summary collapse
-
#deadline ⇒ Deadline?
readonly
The deadline attached to this scope, if any.
-
#token ⇒ CancellationToken
readonly
The token owned by this scope.
Instance Method Summary collapse
-
#cancel! ⇒ void
private
Cancels this scope immediately.
-
#cancelled? ⇒ Boolean
private
Returns +true+ if this scope has been cancelled.
-
#deadline_in(seconds) ⇒ self
private
Attaches a deadline that will cancel this scope after +seconds+.
-
#initialize(parent_token: nil) ⇒ CancellationScope
constructor
private
A new instance of CancellationScope.
-
#pop_queue(queue, fallback_timeout: nil) { ... } ⇒ Object
private
Pops from +queue+ with a timeout derived from the attached deadline (or +fallback_timeout+ seconds when no deadline is set).
-
#remaining_seconds ⇒ Float?
private
Returns the remaining time in seconds before the deadline expires, or +nil+ when no deadline is set.
Constructor Details
#initialize(parent_token: nil) ⇒ CancellationScope
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of CancellationScope.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/phronomy/cancellation_scope.rb', line 37 def initialize(parent_token: nil) @token = Phronomy::CancellationToken.new @deadline = nil if parent_token # Propagate explicit cancel() from parent to child via callback. parent_token.on_cancel { @token.cancel! } # Propagate monotonic-deadline expiry from parent to child via the # timer queue (avoids a polling thread). remaining = parent_token.remaining_monotonic_seconds if !remaining.nil? if remaining <= 0 @token.cancel! else Phronomy::Runtime.instance.timer_queue.schedule(seconds: remaining) do @token.cancel! end end end end end |
Instance Attribute Details
#deadline ⇒ Deadline? (readonly)
Returns the deadline attached to this scope, if any.
30 31 32 |
# File 'lib/phronomy/cancellation_scope.rb', line 30 def deadline @deadline end |
#token ⇒ CancellationToken (readonly)
Returns the token owned by this scope.
27 28 29 |
# File 'lib/phronomy/cancellation_scope.rb', line 27 def token @token end |
Instance Method Details
#cancel! ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Cancels this scope immediately.
74 75 76 |
# File 'lib/phronomy/cancellation_scope.rb', line 74 def cancel! @token.cancel! end |
#cancelled? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns +true+ if this scope has been cancelled.
81 82 83 |
# File 'lib/phronomy/cancellation_scope.rb', line 81 def cancelled? @token.cancelled? end |
#deadline_in(seconds) ⇒ self
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Attaches a deadline that will cancel this scope after +seconds+.
65 66 67 68 69 |
# File 'lib/phronomy/cancellation_scope.rb', line 65 def deadline_in(seconds) @deadline = Phronomy::Deadline.in(seconds) @deadline.attach_to(@token) self end |
#pop_queue(queue, fallback_timeout: nil) { ... } ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Pops from +queue+ with a timeout derived from the attached deadline (or +fallback_timeout+ seconds when no deadline is set). If the pop times out, the scope is cancelled and the block is called (or a TimeoutError raised).
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/phronomy/cancellation_scope.rb', line 103 def pop_queue(queue, fallback_timeout: nil) timeout = @deadline&.remaining_seconds || fallback_timeout result = if timeout queue.pop(timeout: timeout) else queue.pop end if result.nil? cancel! if block_given? yield else raise Phronomy::TimeoutError, "CancellationScope timed out" end end result end |
#remaining_seconds ⇒ Float?
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the remaining time in seconds before the deadline expires, or +nil+ when no deadline is set.
89 90 91 |
# File 'lib/phronomy/cancellation_scope.rb', line 89 def remaining_seconds @deadline&.remaining_seconds end |