Class: Mistri::AbortSignal
- Inherits:
-
Object
- Object
- Mistri::AbortSignal
- Defined in:
- lib/mistri/abort_signal.rb
Overview
A thread-safe, one-way latch for cancelling a run. The host trips it from any thread; the loop and tools check it cooperatively at safe points, and the transport registers an on-abort callback to close an in-flight socket, so even a stalled read stops immediately instead of waiting out its read timeout.
Instance Attribute Summary collapse
-
#reason ⇒ Object
readonly
Returns the value of attribute reason.
Instance Method Summary collapse
-
#abort!(reason = nil) ⇒ Object
Trip the latch and fire every registered callback exactly once.
- #aborted? ⇒ Boolean
-
#derive ⇒ Object
A signal that trips when this one does, never the reverse: abort the derived signal alone and this one runs on.
-
#initialize ⇒ AbortSignal
constructor
A new instance of AbortSignal.
-
#on_abort(&callback) ⇒ Object
Register a callback for the moment of abort.
-
#remove_callback(handle) ⇒ Object
Deregister a callback, so a completed request does not leak its socket closer into a later abort.
Constructor Details
#initialize ⇒ AbortSignal
Returns a new instance of AbortSignal.
10 11 12 13 14 15 |
# File 'lib/mistri/abort_signal.rb', line 10 def initialize @mutex = Mutex.new @aborted = false @reason = nil @callbacks = [] end |
Instance Attribute Details
#reason ⇒ Object (readonly)
Returns the value of attribute reason.
19 20 21 |
# File 'lib/mistri/abort_signal.rb', line 19 def reason @reason end |
Instance Method Details
#abort!(reason = nil) ⇒ Object
Trip the latch and fire every registered callback exactly once. Subsequent calls are no-ops.
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/mistri/abort_signal.rb', line 23 def abort!(reason = nil) callbacks = @mutex.synchronize do break [] if @aborted @aborted = true @reason = reason @callbacks.dup.tap { @callbacks.clear } end callbacks.each { |callback| safely(callback) } nil end |
#aborted? ⇒ Boolean
17 |
# File 'lib/mistri/abort_signal.rb', line 17 def aborted? = @aborted |
#derive ⇒ Object
A signal that trips when this one does, never the reverse: abort the derived signal alone and this one runs on. Returns [signal, handle]; remove the handle when the derived work ends, so a finished child never leaks a callback into a later abort.
39 40 41 42 43 |
# File 'lib/mistri/abort_signal.rb', line 39 def derive child = AbortSignal.new handle = on_abort { child.abort!(reason) } [child, handle] end |
#on_abort(&callback) ⇒ Object
Register a callback for the moment of abort. Fires immediately when the signal is already tripped. Returns a handle for #remove_callback.
47 48 49 50 51 52 53 54 |
# File 'lib/mistri/abort_signal.rb', line 47 def on_abort(&callback) fire_now = @mutex.synchronize do @callbacks << callback unless @aborted @aborted end safely(callback) if fire_now callback end |
#remove_callback(handle) ⇒ Object
Deregister a callback, so a completed request does not leak its socket closer into a later abort.
58 59 60 61 |
# File 'lib/mistri/abort_signal.rb', line 58 def remove_callback(handle) @mutex.synchronize { @callbacks.delete(handle) } nil end |