Class: Fear::Future
- Inherits:
-
Object
- Object
- Fear::Future
- Defined in:
- lib/fear/future.rb
Overview
Asynchronous computations that yield futures are created with the Fear.future
call:
Multiple callbacks may be registered; there is no guarantee that they will be executed in a particular order.
The future may contain an exception and this means that the future failed. Futures obtained through combinators have the same error as the future they were obtained from.
Class Method Summary collapse
-
.failed(exception) ⇒ Fear::Future
Creates an already completed
Future
with the specified error. -
.successful(result) ⇒ Fear::Future
Creates an already completed
Future
with the specified result.
Instance Method Summary collapse
-
#and_then(&block) ⇒ Object
Applies the side-effecting block to the result of
self
future, and returns a new future with the result of this future. -
#completed? ⇒ true, false
Returns whether the future has already been completed with a value or an error.
-
#fallback_to(fallback) ⇒ Fear::Future
Creates a new future which holds the result of
self
future if it was completed successfully, or, if not, the result of thefallback
future iffallback
is completed successfully. -
#flat_map {|| ... } ⇒ Fear::Future
Creates a new future by applying a block to the successful result of this future, and returns the result of the function as the new future.
-
#initialize(promise = nil, **options) { ... } ⇒ Future
constructor
private
A new instance of Future.
-
#map(&block) ⇒ Fear::Future
Creates a new future by applying a block to the successful result of this future.
-
#on_complete {|| ... } ⇒ self
When this future is completed call the provided block.
-
#on_failure {|| ... } ⇒ self
When this future is completed with a failure apply the provided callback to the error.
-
#on_success {|| ... } ⇒ self
(also: #each)
Calls the provided callback When this future is completed successfully.
-
#recover(&block) ⇒ Fear::Future
Creates a new future that will handle any matching error that this future might contain.
-
#select {|| ... } ⇒ Fear::Future
Creates a new future by filtering the value of the current future with a predicate.
-
#transform(success, failure) {|success, failure| ... } ⇒ Fear::Future
Creates a new future by applying the
success
function to the successful result of this future, or thefailure
function to the failed result. -
#value ⇒ Fear::Option<Fear::Try>
The value of this
Future
. -
#zip(other) ⇒ Fear::Future
Zips the values of
self
andother
future, and creates a new future holding the array of their results.
Constructor Details
#initialize(promise = nil, **options) { ... } ⇒ Future
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Future.
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/fear/future.rb', line 47 def initialize(promise = nil, **, &block) if block_given? && promise raise ArgumentError, 'pass block or future' end @options = @promise = promise || Concurrent::Promise.execute(@options) do Fear.try(&block) end end |
Class Method Details
.failed(exception) ⇒ Fear::Future
Creates an already completed Future
with the specified error.
397 398 399 400 401 |
# File 'lib/fear/future.rb', line 397 def failed(exception) new(executor: Concurrent::ImmediateExecutor.new) do raise exception end end |
.successful(result) ⇒ Fear::Future
Creates an already completed Future
with the specified result.
407 408 409 410 411 |
# File 'lib/fear/future.rb', line 407 def successful(result) new(executor: Concurrent::ImmediateExecutor.new) do result end end |
Instance Method Details
#and_then(&block) ⇒ Object
that if one of the chained and_then
callbacks throws
Applies the side-effecting block to the result of self
future, and returns a new future with the result of this future.
This method allows one to enforce that the callbacks are executed in a specified order.
an error, that error is not propagated to the subsequent and_then
callbacks. Instead, the subsequent and_then
callbacks are given the original value of this future.
382 383 384 385 386 387 388 389 390 |
# File 'lib/fear/future.rb', line 382 def and_then(&block) promise = Promise.new(@options) on_complete do |try| Fear.try { try.match(&block) } promise.complete!(try) end promise.to_future end |
#completed? ⇒ true, false
Returns whether the future has already been completed with a value or an error.
134 135 136 |
# File 'lib/fear/future.rb', line 134 def completed? promise.fulfilled? end |
#fallback_to(fallback) ⇒ Fear::Future
Creates a new future which holds the result of self
future if it was completed successfully, or, if not, the result of the fallback
future if fallback
is completed successfully. If both futures are failed, the resulting future holds the error object of the first future.
rubocop: disable Metrics/MethodLength
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/fear/future.rb', line 342 def fallback_to(fallback) promise = Promise.new(@options) on_complete do |try| try.match do |m| m.success { |value| promise.complete!(value) } m.failure do |error| fallback.on_complete do |fallback_try| fallback_try.match do |m2| m2.success { |value| promise.complete!(value) } m2.failure { promise.failure!(error) } end end end end end promise.to_future end |
#flat_map {|| ... } ⇒ Fear::Future
Creates a new future by applying a block to the successful result of this future, and returns the result of the function as the new future. If this future is completed with an exception then the new future will also contain this exception.
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/fear/future.rb', line 225 def flat_map # rubocop: disable Metrics/MethodLength promise = Promise.new(@options) on_complete do |result| result.match do |m| m.failure { promise.complete!(result) } m.success do |value| begin yield(value).on_complete { |callback_result| promise.complete!(callback_result) } rescue StandardError => error promise.failure!(error) end end end end promise.to_future end |
#map(&block) ⇒ Fear::Future
Creates a new future by applying a block to the successful result of this future. If this future is completed with an error then the new future will also contain this error.
199 200 201 202 203 204 205 206 |
# File 'lib/fear/future.rb', line 199 def map(&block) promise = Promise.new(@options) on_complete do |try| promise.complete!(try.map(&block)) end promise.to_future end |
#on_complete {|| ... } ⇒ self
When this future is completed call the provided block.
If the future has already been completed, this will either be applied immediately or be scheduled asynchronously.
115 116 117 118 119 120 |
# File 'lib/fear/future.rb', line 115 def on_complete promise.add_observer do |_time, try, _error| yield try end self end |
#on_failure {|| ... } ⇒ self
When this future is completed with a failure apply the provided callback to the error.
If the future has already been completed with a failure, this will either be applied immediately or be scheduled asynchronously.
Will not be called in case that the future is completed with a value.
95 96 97 98 99 100 101 |
# File 'lib/fear/future.rb', line 95 def on_failure on_complete do |result| if result.failure? yield result.exception end end end |
#on_success {|| ... } ⇒ self Also known as: each
Calls the provided callback When this future is completed successfully.
If the future has already been completed with a value, this will either be applied immediately or be scheduled asynchronously.
73 74 75 76 77 |
# File 'lib/fear/future.rb', line 73 def on_success(&block) on_complete do |result| result.each(&block) end end |
#recover(&block) ⇒ Fear::Future
Creates a new future that will handle any matching error that this future might contain. If there is no match, or if this future contains a valid result then the new future will contain the same.
283 284 285 286 287 288 289 290 |
# File 'lib/fear/future.rb', line 283 def recover(&block) promise = Promise.new(@options) on_complete do |try| promise.complete!(try.recover(&block)) end promise.to_future end |
#select {|| ... } ⇒ Fear::Future
Creates a new future by filtering the value of the current future with a predicate.
If the current future contains a value which satisfies the predicate, the new future will also hold that value. Otherwise, the resulting future will fail with a NoSuchElementError
.
If the current future fails, then the resulting future also fails.
259 260 261 262 263 264 265 266 267 |
# File 'lib/fear/future.rb', line 259 def select map do |result| if yield(result) result else raise NoSuchElementError, '#select predicate is not satisfied' end end end |
#transform(success, failure) {|success, failure| ... } ⇒ Fear::Future
Creates a new future by applying the success
function to the successful result of this future, or the failure
function to the failed result. If there is any non-fatal error raised when success
or failure
is applied, that error will be propagated to the resulting future.
178 179 180 181 182 183 184 185 186 187 |
# File 'lib/fear/future.rb', line 178 def transform(success, failure) promise = Promise.new(@options) on_complete do |try| try.match do |m| m.success { |value| promise.success(success.call(value)) } m.failure { |error| promise.failure(failure.call(error)) } end end promise.to_future end |
#value ⇒ Fear::Option<Fear::Try>
The value of this Future
.
146 147 148 |
# File 'lib/fear/future.rb', line 146 def value Fear.option(promise.value(0)) end |
#zip(other) ⇒ Fear::Future
Zips the values of self
and other
future, and creates a new future holding the array of their results.
If self
future fails, the resulting future is failed with the error stored in self
. Otherwise, if other
future fails, the resulting future is failed with the error stored in other
.
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/fear/future.rb', line 309 def zip(other) # rubocop: disable Metrics/MethodLength promise = Promise.new(@options) on_complete do |try_of_self| try_of_self.match do |m| m.success do |value| other.on_complete do |try_of_other| promise.complete!(try_of_other.map { |other_value| [value, other_value] }) end end m.failure do |error| promise.failure!(error) end end end promise.to_future end |