class Px::Service::Client::Future
Public Class Methods
new() { || ... }
click to toggle source
Create a new future. If a block is given, it is executed and the future is automatically completed with the block's return value
# File lib/px/service/client/future.rb, line 12 def initialize @completed = false @pending_calls = [] if block_given? Fiber.new do value = begin yield rescue Exception => ex ex end complete(value) end.resume end end
Public Instance Methods
complete(value)
click to toggle source
# File lib/px/service/client/future.rb, line 28 def complete(value) raise AlreadyCompletedError.new if @completed @value = value @completed = true @pending_calls.each do |pending_call| if value.kind_of?(Exception) pending_call[:fiber].resume(value) else result = nil begin if pending_call[:method] result = value.send(pending_call[:method], *pending_call[:args]) else result = value end rescue Exception => ex result = ex end pending_call[:fiber].resume(result) end end end
completed?()
click to toggle source
# File lib/px/service/client/future.rb, line 76 def completed? @completed end
method_missing(method, *args)
click to toggle source
Calls superclass method
# File lib/px/service/client/future.rb, line 80 def method_missing(method, *args) super unless respond_to_missing?(method) value!.send(method, *args) end
respond_to_missing?(method, include_private = false)
click to toggle source
# File lib/px/service/client/future.rb, line 85 def respond_to_missing?(method, include_private = false) # NoMethodError is handled by method_missing here, so that exceptions # are raised properly even though they don't respond_to the same things # as the future values themselves true end
value()
click to toggle source
# File lib/px/service/client/future.rb, line 52 def value if @completed @value else wait_for_value(nil) end end
value!()
click to toggle source
# File lib/px/service/client/future.rb, line 60 def value! if @completed result = @value else result = wait_for_value(nil) end if result.kind_of?(Exception) # Set the backtrack properly to reflect where this method is called result.set_backtrace(caller) raise result end result end
Private Instance Methods
wait_for_value(method, *args)
click to toggle source
# File lib/px/service/client/future.rb, line 94 def wait_for_value(method, *args) # TODO: check for root fiber @pending_calls << { fiber: Fiber.current, method: method, args: args } Fiber.yield end