Class: Dharma::Promise

Inherits:
Object
  • Object
show all
Includes:
PromiseActions
Defined in:
lib/dharma/promise.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PromiseActions

#complete_with, #failed, #failure, #flat_map, #map, #on_failure, #on_success, #recover, #recover_with, #success, #try_failure, #try_success

Constructor Details

#initializePromise

Returns a new instance of Promise.



17
18
19
20
# File 'lib/dharma/promise.rb', line 17

def initialize
  @mutex     = Monitor.new
  @condition = @mutex.new_cond
end

Class Method Details

.failed(value) ⇒ Object



13
14
15
# File 'lib/dharma/promise.rb', line 13

def self.failed(value)
  KeptPromise.new(value, :failure)
end

.successful(value) ⇒ Object



9
10
11
# File 'lib/dharma/promise.rb', line 9

def self.successful(value)
  KeptPromise.new(value, :success)
end

Instance Method Details

#complete(value, as = nil) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/dharma/promise.rb', line 72

def complete(value, as = nil)
  if try_complete(value, as)
    self
  else
    raise Dharma::IllegalStateException.new("Promise already completed.")
  end
end

#completed?Boolean

Returns:

  • (Boolean)


66
67
68
69
70
# File 'lib/dharma/promise.rb', line 66

def completed?
  @mutex.synchronize do
    @as != nil
  end
end

#failure?Boolean

Returns:

  • (Boolean)


22
23
24
25
26
# File 'lib/dharma/promise.rb', line 22

def failure?
  @mutex.synchronize do
    @as == :failure
  end
end

#on_complete(cb = nil, &block) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/dharma/promise.rb', line 111

def on_complete(cb = nil, &block)
  cb ||= block
  value, as = nil

  @mutex.synchronize do
    if @as
      value, as = @value, @as
    else
      (@on_completed ||= []) << cb
      return
    end
  end

  cb.call(value, as)
  return
end

#ready(at_most = nil) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/dharma/promise.rb', line 40

def ready(at_most = nil)
  @mutex.synchronize do
    if @as
      return self
    else
      @condition.wait(at_most ? at_most.to_f : nil)

      if @as
        return self
      else
        raise Dharma::TimeoutException.new("Futures timed out after [#{at_most}]")
      end
    end
  end
end

#resolve_and_assign(value, as = nil) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/dharma/promise.rb', line 128

def resolve_and_assign(value, as = nil)
  case as
  when :failure
    case value
    when Exception
      @value, @as = value, as
    else
      @value, @as = Dharma::PromiseFailure.new(value), as
      @value.set_backtrace(caller)
    end
  when :success
    @value, @as = value, as
  else
    case value
    when LocalJumpError
      @value, @as = value.exit_value, :success
    when Exception
      @value, @as = value, :failure
    else
      @value, @as = value, :success
    end
  end
end

#result(at_most = nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/dharma/promise.rb', line 28

def result(at_most = nil)
  ready(at_most)

  @mutex.synchronize do
    if @as == :failure
      raise @value
    else
      return @value
    end
  end
end

#try_complete(value, as = nil) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/dharma/promise.rb', line 80

def try_complete(value, as = nil)
  on_completed = nil

  @mutex.synchronize do
    if !@as
      resolve_and_assign(value, as)

      # Grab the value from what we stored
      value, as = @value, @as

      # Clear callbacks
      on_completed = @on_completed
      @on_completed = nil

      # Wake everyone up
      @condition.broadcast

      # We don't need the condition anymore
      @condition = nil
    else
      return false
    end
  end

  if on_completed
    on_completed.each { |cb| cb.call(value, as) }
  end

  return true
end

#valueObject



56
57
58
59
60
61
62
63
64
# File 'lib/dharma/promise.rb', line 56

def value
  @mutex.synchronize do
    if @as
      @value
    else
      nil
    end
  end
end