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 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
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 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

!(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 78
def cancel
        return self if delivered?

        @mutex.synchronize {
                if @thread.is_a? Thread
                        @thread.raise Cancel
                else
                        @thread.terminate! Cancel
                end

                @exception = Cancel.new
        }

        self
end
cancelled?() click to toggle source

Check if the future has been cancelled

# File lib/thread/future.rb, line 95
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 69
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 62
def exception
        @mutex.synchronize {
                @exception
        }
end
exception?() click to toggle source

Check if an exception has been raised.

# File lib/thread/future.rb, line 55
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 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
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 127
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 142
def cond
        @cond ||= ConditionVariable.new
end
cond?() click to toggle source
# File lib/thread/future.rb, line 138
def cond?
        instance_variable_defined? :@cond
end
deliver(value) click to toggle source
# File lib/thread/future.rb, line 146
def deliver (value)
        return if delivered?

        @mutex.synchronize {
                @value = value

                cond.broadcast if cond?
        }

        self
end