Class: TIMEx::CancellationToken

Inherits:
Object
  • Object
show all
Defined in:
lib/timex/cancellation_token.rb

Overview

Thread-safe manual cancellation signal for long-running or hedged work.

Observers registered via #on_cancel run outside the mutex after the transition to cancelled; observer exceptions are swallowed and reported through Telemetry.

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializevoid



14
15
16
17
18
19
# File 'lib/timex/cancellation_token.rb', line 14

def initialize
  @mutex = Mutex.new
  @cancelled = false
  @reason = nil
  @observers = []
end

Instance Attribute Details

#reasonObject (readonly)

Returns the value of attribute reason.



26
27
28
# File 'lib/timex/cancellation_token.rb', line 26

def reason
  @reason
end

Instance Method Details

#cancel(reason: nil) ⇒ Boolean

Marks the token cancelled and notifies observers (once).

Parameters:

  • reason (Object, nil) (defaults to: nil)

    opaque payload passed to observers

Returns:

  • (Boolean)

    true when this call performed the transition, false if already cancelled



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/timex/cancellation_token.rb', line 32

def cancel(reason: nil) # rubocop:disable Naming/PredicateMethod
  observers_to_notify = nil
  @mutex.synchronize do
    return false if @cancelled

    @cancelled = true
    @reason = reason
    observers_to_notify = @observers.dup
  end
  observers_to_notify.each { |o| safe_call(o, reason) }
  true
end

#cancelled?Boolean

Returns true after #cancel succeeds.

Returns:

  • (Boolean)

    true after #cancel succeeds



22
23
24
# File 'lib/timex/cancellation_token.rb', line 22

def cancelled?
  @mutex.synchronize { @cancelled }
end

#on_cancel {|reason| ... } ⇒ self

Registers a callback invoked on cancellation (immediately if already cancelled).

Yields:

  • (reason)

    invoked when cancelled

Yield Parameters:

  • reason (Object, nil)

    the reason passed to #cancel

Returns:

  • (self)

    for chaining



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/timex/cancellation_token.rb', line 50

def on_cancel(&block)
  fire_now = false
  @mutex.synchronize do
    if @cancelled
      fire_now = true
    else
      @observers << block
    end
  end
  safe_call(block, @reason) if fire_now
  self
end