Class: Salus::Future
- Inherits:
-
Object
- Object
- Salus::Future
- Includes:
- Logging, Observable
- Defined in:
- lib/salus/thread/future.rb
Constant Summary collapse
- Cancel =
Class.new(Exception)
Class Method Summary collapse
Instance Method Summary collapse
-
#cancel ⇒ Object
Cancel the future, #value will yield a Cancel exception.
-
#cancelled? ⇒ Boolean
Check if the future has been cancelled.
-
#delivered? ⇒ Boolean
(also: #realized?)
Check if the future has been called.
-
#exception ⇒ Object
Return the raised exception.
-
#exception? ⇒ Boolean
Check if an exception has been raised.
-
#initialize(pool = nil, &block) ⇒ Future
constructor
Create a future with the passed block and optionally using the passed pool.
-
#value(timeout = nil) ⇒ Object
(also: #~)
Get the value of the future, if it’s not finished running this call will block.
-
#value!(timeout = nil) ⇒ Object
(also: #!)
Do the same as #value, but return nil in case of exception.
Methods included from Logging
Methods included from Observable
#add_observer, #count_observers, #delete_observer, #delete_observers, #notify_and_delete_observers, #notify_observers, #with_observer
Constructor Details
#initialize(pool = nil, &block) ⇒ Future
Create a future with the passed block and optionally using the passed pool.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/salus/thread/future.rb', line 23 def initialize(pool = nil, &block) raise ArgumentError, 'no block given' unless block @mutex = Mutex.new task = proc { begin deliver block.call notify_and_delete_observers(Time.now, @value, nil) rescue Exception => e @exception = e notify_and_delete_observers(Time.now, nil, e) log DEBUG, @exception deliver nil end } @thread = pool ? pool.process(&task) : Thread.new(&task) ObjectSpace.define_finalizer self, self.class.finalizer(WeakRef.new(@thread)) end |
Class Method Details
Instance Method Details
#cancel ⇒ Object
Cancel the future, #value will yield a Cancel exception
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/salus/thread/future.rb', line 82 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? ⇒ Boolean
Check if the future has been cancelled
99 100 101 102 103 |
# File 'lib/salus/thread/future.rb', line 99 def cancelled? @mutex.synchronize { @exception.is_a? Cancel } end |
#delivered? ⇒ Boolean Also known as: realized?
Check if the future has been called.
73 74 75 76 77 |
# File 'lib/salus/thread/future.rb', line 73 def delivered? @mutex.synchronize { instance_variable_defined? :@value } end |
#exception ⇒ Object
Return the raised exception.
66 67 68 69 70 |
# File 'lib/salus/thread/future.rb', line 66 def exception @mutex.synchronize { @exception } end |
#exception? ⇒ Boolean
Check if an exception has been raised.
59 60 61 62 63 |
# File 'lib/salus/thread/future.rb', line 59 def exception? @mutex.synchronize { instance_variable_defined? :@exception } end |
#value(timeout = nil) ⇒ Object Also known as: ~
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.
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/salus/thread/future.rb', line 112 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 |
#value!(timeout = nil) ⇒ Object Also known as: !
Do the same as #value, but return nil in case of exception.
131 132 133 134 135 136 137 |
# File 'lib/salus/thread/future.rb', line 131 def value!(timeout = nil) begin value(timeout) rescue Exception nil end end |