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 41 def self.finalizer(thread) proc { thread.raise Cancel.new } end
Create a future with the passed block and optionally using the passed pool.
# File lib/thread/future.rb, line 20 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(@thread) end
Public Instance Methods
Check if the future has been cancelled
# File lib/thread/future.rb, line 82 def cancelled? @mutex.synchronize { @exception.is_a? Cancel } end
Check if the future has been called.
# File lib/thread/future.rb, line 62 def delivered? @mutex.synchronize { instance_variable_defined? :@value } end
Return the raised exception.
# File lib/thread/future.rb, line 55 def exception @mutex.synchronize { @exception } end
Check if an exception has been raised.
# File lib/thread/future.rb, line 48 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 95 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 114 def value!(timeout = nil) begin value(timeout) rescue Exception nil end end
Private Instance Methods
# File lib/thread/future.rb, line 129 def cond @cond ||= ConditionVariable.new end
# File lib/thread/future.rb, line 125 def cond? instance_variable_defined? :@cond end
# File lib/thread/future.rb, line 133 def deliver (value) return if delivered? @mutex.synchronize { @value = value cond.broadcast if cond? } self end