Module: DeferrableGratification::Combinators::ClassMethods
- Included in:
- DeferrableGratification
- Defined in:
- lib/deferrable_gratification/combinators.rb
Overview
Combinators which don’t make sense as methods on Deferrable
.
DeferrableGratification extends this module, and thus the methods here are accessible via the DG alias.
Instance Method Summary collapse
-
#chain(*actions) ⇒ Deferrable
Execute a sequence of asynchronous operations that may each depend on the result of the previous operation.
-
#join_first_success(*operations) ⇒ Deferrable
Combinator that waits for any of the supplied asynchronous operations to succeed, and succeeds with the result of the first (chronologically) to do so.
-
#join_successes(*operations) ⇒ Deferrable
Combinator that waits for all of the supplied asynchronous operations to succeed or fail, then succeeds with the results of all those operations that were successful.
-
#loop_until_success(loop_deferrable = DefaultDeferrable.new, &block) ⇒ Deferrable
Combinator that repeatedly executes the supplied block until it succeeds, then succeeds itself with the eventual result.
Instance Method Details
#chain(*actions) ⇒ Deferrable
Execute a sequence of asynchronous operations that may each depend on the result of the previous operation.
241 242 243 |
# File 'lib/deferrable_gratification/combinators.rb', line 241 def chain(*actions) actions.inject(DG.const(nil), &:>>) end |
#join_first_success(*operations) ⇒ Deferrable
Combinator that waits for any of the supplied asynchronous operations to succeed, and succeeds with the result of the first (chronologically) to do so.
This Deferrable will fail if all the operations fail. It may never succeed or fail, if one of the operations also does not.
279 280 281 |
# File 'lib/deferrable_gratification/combinators.rb', line 279 def join_first_success(*operations) Join::FirstSuccess.setup!(*operations) end |
#join_successes(*operations) ⇒ Deferrable
Combinator that waits for all of the supplied asynchronous operations to succeed or fail, then succeeds with the results of all those operations that were successful.
This Deferrable will never fail. It may also never succeed, if any of the supplied operations does not either succeed or fail.
The successful results are guaranteed to be in the same order as the operations were passed in (which may not be the same as the chronological order in which they succeeded).
263 264 265 |
# File 'lib/deferrable_gratification/combinators.rb', line 263 def join_successes(*operations) Join::Successes.setup!(*operations) end |
#loop_until_success(loop_deferrable = DefaultDeferrable.new, &block) ⇒ Deferrable
this combinator is intended for use inside EventMachine. It will still work outside of EventMachine, provided that the operation is synchronous (although a simple while
loop might be preferable in this case!).
Combinator that repeatedly executes the supplied block until it succeeds, then succeeds itself with the eventual result.
This Deferrable may never succeed, if the operation never succeeds. It will fail if an iteration raises an exception.
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/deferrable_gratification/combinators.rb', line 303 def loop_until_success(loop_deferrable = DefaultDeferrable.new, &block) if EM.reactor_running? EM.next_tick do begin attempt = yield rescue => e loop_deferrable.fail(e) else attempt.callback(&loop_deferrable.method(:succeed)) attempt.errback { loop_until_success(loop_deferrable, &block) } end end else # In the synchronous case, we could simply use the same # implementation as in EM, but without the next_tick; unfortunately # that means direct recursion, so risks stack overflow. Instead we # just reimplement as a loop. results = [] begin yield.callback {|*values| results << values } while results.empty? rescue => e loop_deferrable.fail(e) else loop_deferrable.succeed(*results[0]) end end loop_deferrable end |