class Concurrent::Delay
@see Concurrent::Concern::Dereferenceable
execute on the given executor, allowing the call to timeout.
constructor option. This will cause the delayed operation to be
irrelevant. To enable non-blocking behavior, use the ‘executor`
the current thread. This makes the `timeout` value completely
calling either `value` or `wait`, executing the delayed operation on
@note The default behavior of `Delay` is to block indefinitely when
@!macro delay_note_regarding_blocking
@!macro copy_options
safety of the reference returned by `#value`.
`Delay` includes the `Concurrent::Concern::Dereferenceable` mixin to support thread
any side effects created by the operation will only happen once as well.
return the cached value. The operation will only be run once. This means that
blocked on `#value` will return. Subsequent calls to `#value` will immediately
reason will be set to the raised exception, as appropriate. All threads
is complete the value will be set to the result of the operation or the
threads attempting to call `#value` will block as well. Once the operation
enclosed opration will be run and the calling thread will block. Other
reason are both `nil`. The first time the `#value` method is called the
When a `Delay` is created its state is set to `pending`. The value and
with a timeout.
the block execute asynchronously, block indefinitely, or block
At that time the caller can choose to return immediately and let
block will be deferred until the first time `#value` is called.
custom executor upon which to execute the block. Processing of
supports the `Concern::Obligation` interface, and accepts the injection of
expensive operations that may never be needed. It may be non-blocking,
Lazy evaluation of a block yielding an immutable result. Useful for
def execute_task_once # :nodoc:
@!visibility private
def execute_task_once # :nodoc: # this function has been optimized for performance and # should not be modified without running new benchmarks execute = task = nil synchronize do execute = @evaluation_started = true unless @evaluation_started task = @task end if execute executor = Options.executor_from_options(executor: @executor) executor.post do begin result = task.call success = true rescue => ex reason = ex end synchronize do set_state(success, result, reason) event.set end end end end
def initialize(opts = {}, &block)
-
(ArgumentError)
- if no block is given
Other tags:
- Yield: - the delayed operation to perform
def initialize(opts = {}, &block) raise ArgumentError.new('no block given') unless block_given? super(&nil) synchronize { ns_initialize(opts, &block) } end
def ns_initialize(opts, &block)
def ns_initialize(opts, &block) init_obligation set_deref_options(opts) @executor = opts[:executor] @task = block @state = :pending @evaluation_started = false end
def reconfigure(&block)
-
(true, false)
- if success
Other tags:
- Yield: - the delayed operation to perform
def reconfigure(&block) synchronize do raise ArgumentError.new('no block given') unless block_given? unless @evaluation_started @task = block true else false end end end
def value(timeout = nil)
-
(Object)
- the current value of the object
Parameters:
-
timeout
(Numeric
) -- the maximum number of seconds to wait
def value(timeout = nil) if @executor # TODO (pitr 12-Sep-2015): broken unsafe read? super else # this function has been optimized for performance and # should not be modified without running new benchmarks synchronize do execute = @evaluation_started = true unless @evaluation_started if execute begin set_state(true, @task.call, nil) rescue => ex set_state(false, nil, ex) end elsif incomplete? raise IllegalOperationError, 'Recursive call to #value during evaluation of the Delay' end end if @do_nothing_on_deref @value else apply_deref_options(@value) end end end
def value!(timeout = nil)
-
(Exception)
- when `#rejected?` raises `#reason`
Returns:
-
(Object)
- the current value of the object
Parameters:
-
timeout
(Numeric
) -- the maximum number of seconds to wait
def value!(timeout = nil) if @executor super else result = value raise @reason if @reason result end end
def wait(timeout = nil)
-
(Object)
- self
Parameters:
-
timeout
(Integer
) -- (nil) the maximum number of seconds to wait for
def wait(timeout = nil) if @executor execute_task_once super(timeout) else value end self end