Module: Cql::FutureCombinators

Included in:
Future
Defined in:
lib/cql/future.rb

Instance Method Summary collapse

Instance Method Details

#fallback {|error| ... } ⇒ Cql::Future

Returns a new future which represents either the value of the original future, or the value of the future returned by the given block.

This is like #recover but for cases when the handling of an error is itself asynchronous. In other words, #fallback is to #recover what #flat_map is to #map.

If the block raises an error a failed future with that error will be returned (this can be used to transform an error into another error, instead of tranforming an error into a value).

Examples:

result = http_get('/foo/bar').fallback do |error|
  http_get('/baz')
end
result.value # either the response to /foo/bar, or if that failed
             # the response to /baz

Yield Parameters:

  • error (Object)

    the error from the original future

Yield Returns:

  • (Object)

    the value of the new future

Returns:

  • (Cql::Future)

    a new future representing a value recovered from the error



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/cql/future.rb', line 224

def fallback(&block)
  p = Promise.new
  on_failure do |e|
    begin
      f = block.call(e)
      p.observe(f)
    rescue => e
      p.fail(e)
    end
  end
  on_value do |v|
    p.fulfill(v)
  end
  p.future
end

#flat_map {|value| ... } ⇒ Cql::Future

Returns a new future representing a transformation of this future’s value, but where the transformation itself may be asynchronous.

This method is useful when you want to chain asynchronous operations.

Examples:

future2 = future1.flat_map { |value| method_returning_a_future(value) }

Yield Parameters:

  • value (Object)

    the value of this future

Yield Returns:

  • (Cql::Future)

    a future representing the transformed value

Returns:

  • (Cql::Future)

    a new future representing the transformed value



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/cql/future.rb', line 159

def flat_map(&block)
  p = Promise.new
  on_failure { |e| p.fail(e) }
  on_value do |v|
    begin
      f = block.call(v)
      p.observe(f)
    rescue => e
      p.fail(e)
    end
  end
  p.future
end

#map {|value| ... } ⇒ Cql::Future

Returns a new future representing a transformation of this future’s value.

Examples:

future2 = future1.map { |value| value * 2 }

Yield Parameters:

  • value (Object)

    the value of this future

Yield Returns:

  • (Object)

    the transformed value

Returns:

  • (Cql::Future)

    a new future representing the transformed value



139
140
141
142
143
144
145
146
# File 'lib/cql/future.rb', line 139

def map(&block)
  p = Promise.new
  on_failure { |e| p.fail(e) }
  on_value do |v|
    p.try(v, &block)
  end
  p.future
end

#recover {|error| ... } ⇒ Cql::Future

Returns a new future which represents either the value of the original future, or the result of the given block, if the original future fails.

This method is similar to#map, but is triggered by a failure. You can also think of it as a ‘rescue` block for asynchronous operations.

If the block raises an error a failed future with that error will be returned (this can be used to transform an error into another error, instead of tranforming an error into a value).

Examples:

future2 = future1.recover { |error| 'foo' }
future1.fail(error)
future2.value # => 'foo'

Yield Parameters:

  • error (Object)

    the error from the original future

Yield Returns:

  • (Object)

    the value of the new future

Returns:

  • (Cql::Future)

    a new future representing a value recovered from the error



191
192
193
194
195
196
197
198
199
200
# File 'lib/cql/future.rb', line 191

def recover(&block)
  p = Promise.new
  on_failure do |e|
    p.try(e, &block)
  end
  on_value do |v|
    p.fulfill(v)
  end
  p.future
end