Class: Mistri::AbortSignal

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initializeAbortSignal

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

#reasonObject (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

Returns:

  • (Boolean)


17
# File 'lib/mistri/abort_signal.rb', line 17

def aborted? = @aborted

#deriveObject

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