Class: Concurrent::Promise

Inherits:
Object
  • Object
show all
Includes:
Obligation, UsesGlobalThreadPool
Defined in:
lib/concurrent/promise.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from UsesGlobalThreadPool

included

Methods included from Obligation

#completed?, #fulfilled?, #incomplete?, #pending?, #reason, #rejected?, #state, #unscheduled?, #value

Methods included from Dereferenceable

#init_mutex, #mutex, #set_deref_options, #value

Constructor Details

#initialize(options = {}, &block) ⇒ Promise

Returns a new instance of Promise.



14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/concurrent/promise.rb', line 14

def initialize(options = {}, &block)
  options.delete_if {|k, v| v.nil?}

  @parent = options.fetch(:parent) { nil }
  @on_fulfill = options.fetch(:on_fulfill) { Proc.new{ |result| result } }
  @on_reject = options.fetch(:on_reject) { Proc.new{ |reason| raise reason } }

  @promise_body = block || Proc.new{|result| result }
  @state = :unscheduled
  @children = []

  init_obligation
end

Class Method Details

.execute(&block) ⇒ Object

Since:

  • 0.5.0



54
55
56
# File 'lib/concurrent/promise.rb', line 54

def self.execute(&block)
  new(&block).execute
end

.fulfill(value) ⇒ Promise

Returns:



29
30
31
# File 'lib/concurrent/promise.rb', line 29

def self.fulfill(value)
  Promise.new.tap { |p| p.send(:synchronized_set_state!, true, value, nil) }
end

.reject(reason) ⇒ Promise

Returns:



35
36
37
# File 'lib/concurrent/promise.rb', line 35

def self.reject(reason)
  Promise.new.tap { |p| p.send(:synchronized_set_state!, false, nil, reason) }
end

Instance Method Details

#executePromise

Returns:

Since:

  • 0.5.0



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/concurrent/promise.rb', line 41

def execute
  if root?
    if compare_and_set_state(:pending, :unscheduled)
      set_pending
      realize(@promise_body)
    end
  else
    @parent.execute
  end
  self
end

#on_success(&block) ⇒ Promise

Returns:

Raises:



76
77
78
79
# File 'lib/concurrent/promise.rb', line 76

def on_success(&block)
  raise ArgumentError.new('no block given') unless block_given?
  self.then &block
end

#rescue(&block) ⇒ Promise Also known as: catch, on_error

Returns:



82
83
84
# File 'lib/concurrent/promise.rb', line 82

def rescue(&block)
  self.then(block)
end

#then(rescuer = nil, &block) ⇒ Promise

Returns the new promise.

Returns:

  • the new promise

Raises:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/concurrent/promise.rb', line 60

def then(rescuer = nil, &block)
  raise ArgumentError.new('rescuers and block are both missing') if rescuer.nil? && !block_given?
  block = Proc.new{ |result| result } if block.nil?
  child = Promise.new(parent: self, on_fulfill: block, on_reject: rescuer)

  mutex.synchronize do
    child.state = :pending if @state == :pending
    child.on_fulfill(apply_deref_options(@value)) if @state == :fulfilled
    child.on_reject(@reason) if @state == :rejected
    @children << child
  end

  child
end