Class: Gienah::Future
- Inherits:
-
Object
- Object
- Gienah::Future
- Defined in:
- lib/gienah/future.rb,
sig/gienah.rbs
Instance Attribute Summary collapse
-
#id ⇒ Integer
readonly
Returns the value of attribute id.
Instance Method Summary collapse
- #await(timeout: nil) ⇒ Object
- #cancel ⇒ Boolean
- #done? ⇒ Boolean
- #fulfill(value = nil, error: nil) ⇒ Future
-
#initialize(id, on_cancel: nil) ⇒ Future
constructor
A new instance of Future.
- #then {|arg0, arg1| ... } ⇒ Future
Constructor Details
#initialize(id, on_cancel: nil) ⇒ Future
Returns a new instance of Future.
5 6 7 8 9 10 11 |
# File 'lib/gienah/future.rb', line 5 def initialize(id, on_cancel: nil) @id = id @on_cancel = on_cancel @lock = Mutex.new @ready = ConditionVariable.new @callbacks = [] end |
Instance Attribute Details
#id ⇒ Integer (readonly)
Returns the value of attribute id.
13 14 15 |
# File 'lib/gienah/future.rb', line 13 def id @id end |
Instance Method Details
#await(timeout: nil) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/gienah/future.rb', line 29 def await(timeout: nil) validate_timeout(timeout) deadline = timeout && Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout timed_out = false result = @lock.synchronize do until @done remaining = deadline && deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC) if remaining && remaining <= 0 timed_out = true break end @ready.wait(@lock, remaining) end break if timed_out raise @error if @error @value end if timed_out cancel raise Gienah::Timeout, "request #{@id} timed out" end result end |
#cancel ⇒ Boolean
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/gienah/future.rb', line 63 def cancel callback = @lock.synchronize do return false if @done || @cancelling @cancelling = true @on_cancel end begin callback&.call(@id) rescue StandardError nil end fulfill(error: Error.new("request #{@id} cancelled")) true end |
#done? ⇒ Boolean
78 79 80 |
# File 'lib/gienah/future.rb', line 78 def done? @lock.synchronize { !!@done } end |
#fulfill(value = nil, error: nil) ⇒ Future
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/gienah/future.rb', line 15 def fulfill(value = nil, error: nil) callbacks = @lock.synchronize do return self if @done @value = value @error = error @done = true @ready.broadcast callbacks, @callbacks = @callbacks, [] callbacks end callbacks.each { |callback| callback.call(@value, @error) } self end |
#then {|arg0, arg1| ... } ⇒ Future
53 54 55 56 57 58 59 60 61 |
# File 'lib/gienah/future.rb', line 53 def then(&callback) raise ArgumentError, "callback required" unless callback ready = @lock.synchronize do @callbacks << callback unless @done @done end callback.call(@value, @error) if ready self end |