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

finalizer(thread) click to toggle source

@private

# File lib/thread/future.rb, line 41
def self.finalizer(thread)
        proc {
                thread.raise Cancel.new
        }
end
new(pool = nil, &block) click to toggle source

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

!(timeout = nil)
Alias for: value!
cancel() click to toggle source

Cancel the future, {#value} will yield a Cancel exception

# File lib/thread/future.rb, line 71
def cancel
        return self if delivered?

        @mutex.synchronize {
                @thread.raise Cancel.new('future cancelled')
        }

        self
end
cancelled?() click to toggle source

Check if the future has been cancelled

# File lib/thread/future.rb, line 82
def cancelled?
        @mutex.synchronize {
                @exception.is_a? Cancel
        }
end
delivered?() click to toggle source

Check if the future has been called.

# File lib/thread/future.rb, line 62
def delivered?
        @mutex.synchronize {
                instance_variable_defined? :@value
        }
end
Also aliased as: realized?
exception() click to toggle source

Return the raised exception.

# File lib/thread/future.rb, line 55
def exception
        @mutex.synchronize {
                @exception
        }
end
exception?() click to toggle source

Check if an exception has been raised.

# File lib/thread/future.rb, line 48
def exception?
        @mutex.synchronize {
                instance_variable_defined? :@exception
        }
end
realized?()
Alias for: delivered?
value(timeout = nil) click to toggle source

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
Also aliased as: ~
value!(timeout = nil) click to toggle source

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
Also aliased as: !
~(timeout = nil)
Alias for: value

Private Instance Methods

cond() click to toggle source
# File lib/thread/future.rb, line 129
def cond
        @cond ||= ConditionVariable.new
end
cond?() click to toggle source
# File lib/thread/future.rb, line 125
def cond?
        instance_variable_defined? :@cond
end
deliver(value) click to toggle source
# File lib/thread/future.rb, line 133
def deliver (value)
        return if delivered?

        @mutex.synchronize {
                @value = value

                cond.broadcast if cond?
        }

        self
end