module Concurrent::Promises::Resolvable
Public Class Methods
Source
# File lib/concurrent-ruby-edge/concurrent/edge/promises.rb, line 150 def self.atomic_resolution(resolvable_map) # atomic_resolution event => [], future => [true, :v, nil] sorted = resolvable_map.to_a.sort_by { |resolvable, _| locking_order_by resolvable } reserved = 0 while reserved < sorted.size && sorted[reserved].first.reserve reserved += 1 end if reserved == sorted.size sorted.each { |resolvable, args| resolvable.resolve(*args, true, true) } true else while reserved > 0 reserved -= 1 raise 'has to be reserved' unless sorted[reserved].first.release end false end end
Resolves all passed events and futures to the given resolutions if possible (all are unresolved) or none.
@param [Hash{Resolvable=>resolve_arguments}, Array<Array(Resolvable
, resolve_arguments)>] resolvable_map
collection of resolvable events and futures which should be resolved all at once and what should they be resolved to, examples: ```ruby { a_resolvable_future1 => [true, :val, nil], a_resolvable_future2 => [false, nil, :err], a_resolvable_event => [] } ``` or ```ruby [[a_resolvable_future1, [true, :val, nil]], [a_resolvable_future2, [false, nil, :err]], [a_resolvable_event, []]] ```
@return [true, false] if success
Source
# File lib/concurrent-ruby-edge/concurrent/edge/promises.rb, line 128 def self.locking_order_by(resolvable) resolvable.object_id end
@return [Comparable] an item to sort the resolvable events or futures
by to get the right global locking order of resolvable events or futures
@see .atomic_resolution
Public Instance Methods
Source
# File lib/concurrent-ruby-edge/concurrent/edge/promises.rb, line 121 def release compare_and_set_internal_state(RESERVED, PENDING) end
@return [true, false] on successful release of the reservation
Source
# File lib/concurrent-ruby-edge/concurrent/edge/promises.rb, line 111 def reserve while true return true if compare_and_set_internal_state(PENDING, RESERVED) return false if resolved? # FIXME (pitr-ch 17-Jan-2019): sleep until given up or resolved instead of busy wait Thread.pass end end
Reserves the event or future, if reserved others are prevented from resolving it. Advanced feature. Be careful about the order of reservation to avoid deadlocks, the method blocks if the future or event is already reserved until it is released or resolved.
@example
f = Concurrent::Promises.resolvable_future reserved = f.reserve Thread.new { f.resolve true, :val, nil } # fails f.resolve true, :val, nil, true if reserved # must be called only if reserved
@return [true, false] on successful reservation