class Thread::Future
A future is an object that incapsulates a block which is called in a different thread, upon retrieval the caller gets blocked until the block has finished running, and its result is returned and cached.
Constants
- Cancel
Public Class Methods
@private
# File lib/thread/future.rb, line 42 def self.finalizer(thread) proc { if thread.weakref_alive? if thread.is_a? Thread thread.raise Cancel else thread.terminate! Cancel end end } end
Create a future with the passed block and optionally using the passed pool.
# File lib/thread/future.rb, line 21 def initialize(pool = nil, &block) raise ArgumentError, 'no block given' unless block @mutex = Mutex.new task = proc { begin deliver block.call rescue Exception => e @exception = e deliver nil end } @thread = pool ? pool.process(&task) : Thread.new(&task) ObjectSpace.define_finalizer self, self.class.finalizer(WeakRef.new(@thread)) end
Public Instance Methods
Check if the future has been cancelled
# File lib/thread/future.rb, line 95 def cancelled? @mutex.synchronize { @exception.is_a? Cancel } end
Check if the future has been called.
# File lib/thread/future.rb, line 69 def delivered? @mutex.synchronize { instance_variable_defined? :@value } end
Return the raised exception.
# File lib/thread/future.rb, line 62 def exception @mutex.synchronize { @exception } end
Check if an exception has been raised.
# File lib/thread/future.rb, line 55 def exception? @mutex.synchronize { instance_variable_defined? :@exception } end
Get the value of the future, if it's not finished running this call will block.
In case the block raises an exception, it will be raised, the exception is cached and will be raised every time you access the value.
An optional timeout can be passed which will return nil if nothing has been delivered.
# File lib/thread/future.rb, line 108 def value(timeout = nil) raise @exception if exception? return @value if delivered? @mutex.synchronize { cond.wait(@mutex, *timeout) } if exception? raise @exception elsif delivered? return @value end end
Do the same as {#value}, but return nil in case of exception.
# File lib/thread/future.rb, line 127 def value!(timeout = nil) begin value(timeout) rescue Exception nil end end
Private Instance Methods
# File lib/thread/future.rb, line 142 def cond @cond ||= ConditionVariable.new end
# File lib/thread/future.rb, line 138 def cond? instance_variable_defined? :@cond end
# File lib/thread/future.rb, line 146 def deliver (value) return if delivered? @mutex.synchronize { @value = value cond.broadcast if cond? } self end