class QuackConcurrency::Future
Used to send a value or error from one thread to another without the need for coordination.
Public Class Methods
Creates a new {Future} concurrency tool. @return [Future]
# File lib/quack_concurrency/future.rb, line 8 def initialize @complete = false @exception = false @mutex = ::Mutex.new @value = nil @waiter = Waiter.new end
Public Instance Methods
Cancels it. If no exception
is specified, a {Canceled} error will be set. @raise [Complete] if the {Future} has already completed @param exception [Exception] custom exception to set (see {#raise}) @return [void]
# File lib/quack_concurrency/future.rb, line 21 def cancel(exception = nil) exception ||= Canceled.new self.raise(exception) nil end
Checks if it has a value or error set. @return [Boolean]
# File lib/quack_concurrency/future.rb, line 29 def complete? @complete end
Gets it's value. @note This method will block until the future has completed @raise [Canceled] if it is canceled @raise [Exception] if specific error was set @return [Object] it's value
# File lib/quack_concurrency/future.rb, line 38 def get @waiter.wait Kernel.raise(@exception) if @exception @value end
Sets it to an error. @raise [Complete] if the it has already completed @param exception [nil,Object] Exception
class or instance to set, otherwise a StandardError
will be set @return [void]
# File lib/quack_concurrency/future.rb, line 48 def raise(exception = nil) exception = case when exception == nil then StandardError.new when exception.is_a?(Exception) then exception when Exception >= exception then exception.new else Kernel.raise(TypeError, "'exception' must be nil or an instance of or descendant of Exception") end @mutex.synchronize do Kernel.raise(Complete) if @complete @complete = true @exception = exception @waiter.resume_all_indefinitely end nil end
Sets it to a value. @raise [Complete] if it has already completed @param new_value [nil,Object] value to assign to future @return [void]
# File lib/quack_concurrency/future.rb, line 69 def set(new_value = nil) @mutex.synchronize do Kernel.raise(Complete) if @complete @complete = true @value = new_value @waiter.resume_all_indefinitely end nil end