Class: Concurrent::Delay
- Inherits:
-
Object
- Object
- Concurrent::Delay
- Includes:
- Obligation
- Defined in:
- lib/concurrent/delay.rb
Overview
Lazy evaluation of a block yielding an immutable result. Useful for expensive operations that may never be needed.
A Delay is similar to Future but solves a different problem. Where a Future schedules an operation for immediate execution and performs the operation asynchronously, a Delay (as the name implies) delays execution of the operation until the result is actually needed.
When a Delay is created its state is set to pending. The value and reason are both nil. The first time the #value method is called the enclosed opration will be run and the calling thread will block. Other threads attempting to call #value will block as well. Once the operation is complete the value will be set to the result of the operation or the reason will be set to the raised exception, as appropriate. All threads blocked on #value will return. Subsequent calls to #value will immediately return the cached value. The operation will only be run once. This means that any side effects created by the operation will only happen once as well.
Delay includes the Concurrent::Dereferenceable mixin to support thread safety of the reference returned by #value.
Instance Method Summary collapse
-
#initialize(opts = {}) { ... } ⇒ Delay
constructor
Create a new
Delayin the:pendingstate. -
#reconfigure { ... } ⇒ true, false
reconfigures the block returning the value if still #incomplete?.
- #wait(timeout) ⇒ Object
Methods included from Obligation
#completed?, #exception, #fulfilled?, #incomplete?, #no_error!, #pending?, #reason, #rejected?, #state, #unscheduled?, #value, #value!
Methods included from Dereferenceable
Constructor Details
#initialize(opts = {}) { ... } ⇒ Delay
Create a new Delay in the :pending state.
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/concurrent/delay.rb', line 48 def initialize(opts = {}, &block) raise ArgumentError.new('no block given') unless block_given? init_obligation @state = :pending @task = block (opts) @task_executor = OptionsParser.get_task_executor_from(opts) @computing = false end |
Instance Method Details
#reconfigure { ... } ⇒ true, false
reconfigures the block returning the value if still #incomplete?
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/concurrent/delay.rb', line 67 def reconfigure(&block) mutex.lock raise ArgumentError.new('no block given') unless block_given? unless @computing @task = block true else false end ensure mutex.unlock end |
#wait(timeout) ⇒ Object
59 60 61 62 |
# File 'lib/concurrent/delay.rb', line 59 def wait(timeout) execute_task_once super timeout end |