class Contender::FutureTask

Public Class Methods

new(callable) click to toggle source

@param [Object] callable @return [undefined]

# File lib/contender/future_task.rb, line 5
def initialize(callable)
  @callable = callable

  @mutex = Mutex.new
  @condition = ConditionVariable.new

  @state = :ready
end

Public Instance Methods

call() click to toggle source

@api public @return [undefined]

# File lib/contender/future_task.rb, line 75
def call
  @mutex.synchronize do
    return unless @state == :ready

    @state = :running
    @thread = Thread.current
  end

  begin
    @result = @callable.call
  rescue => exception
    @exception = exception
  end

  @mutex.synchronize do
    return unless @state == :running

    @state = :ran
    @condition.broadcast
  end
ensure
  @thread = nil
end
cancel(should_interrupt) click to toggle source

@api public @param [Boolean] should_interrupt @return [Boolean] True if this future was cancelled

# File lib/contender/future_task.rb, line 17
def cancel(should_interrupt)
  @mutex.synchronize do
    return false if done?

    if @state == :running
      return false unless should_interrupt
      @thread.raise InterruptError
    end

    @state = :cancelled
    @condition.broadcast
  end

  return true
end
cancelled?() click to toggle source

@api public @return [Boolean]

# File lib/contender/future_task.rb, line 35
def cancelled?
  @state == :cancelled
end
done?() click to toggle source

@api public @return [Boolean]

# File lib/contender/future_task.rb, line 41
def done?
  @state == :ran || @state == :cancelled
end
result(timeout = nil) click to toggle source

@api public @raise [ExecutionError] If the result of the operation was an exception @raise [TimeoutError] If the timeout was reached before the operation completed @raise [CancellationError] If the operation was cancelled @param [Integer] timeout Time to wait for the result @return [Object] The result of the future

# File lib/contender/future_task.rb, line 51
def result(timeout = nil)
  @mutex.synchronize do
    unless done?
      @condition.wait @mutex, timeout

      unless done?
        raise TimeoutError, 'The operation did not complete before the given timeout'
      end
    end

    if @state == :cancelled
      raise CancellationError, 'Task was cancelled before it could be completed'
    end
  end

  if @exception
    raise ExecutionError, @exception
  end

  @result
end