Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent::Promise.all? doesn't work

I'm trying to make some calculations after I got all promises executed. But proc never calls:

cbr_promise = Concurrent::Promise.execute { CbrRatesService.call }
bitfinex_promise = Concurrent::Promise.execute { BitfinexService.call }

proc = Proc.new do
  puts 10
end
Concurrent::Promise.all?([cbr_promise, bitfinex_promise]).then { proc }

Made with concurrent-ruby gem.

Should I create a loop that will check this every 100 ms for example?

Update

I tried to add a loop and byebug the code (in sidekiq worker):

while @fl
  Concurrent::Promise.all?([cbr_promise, bitfinex_promise]).then { proc }
end

but the state of all promises is pending. It could be because of byebug, but anyway the proc never calls.

like image 666
zishe Avatar asked Mar 20 '18 18:03

zishe


People also ask

Does promise all run concurrently?

all executes them in parallel.

What happens if a promise all fails?

Promise. all is all or nothing. It resolves once all promises in the array resolve, or reject as soon as one of them rejects. In other words, it either resolves with an array of all resolved values, or rejects with a single error.

What happens if a promise doesn't resolve?

A promise is just an object with properties in Javascript. There's no magic to it. So failing to resolve or reject a promise just fails to ever change the state from "pending" to anything else. This doesn't cause any fundamental problem in Javascript because a promise is just a regular Javascript object.


1 Answers

  1. Concurrent::Promise.all? returns a Promise and you have to execute it
  2. you have to pass proc as a block argument &proc
  3. you have to wait for the Promises to finish (e.g. sleep)

This will work:

require 'concurrent'

cbr_promise       = Concurrent::Promise.new { p "cbr" }
bitfinex_promise  = Concurrent::Promise.new { p "bitfinex" }

proc = Proc.new do
  puts 10
end

e = Concurrent::Promise.all?(cbr_promise, bitfinex_promise).execute.then(&proc)

sleep 1

yields

"cbr"
"bitfinex"
10

Note how this will not execute proc because one of the Promises fails:

require 'concurrent'

cbr_promise       = Concurrent::Promise.new { p "cbr" }
bitfinex_promise  = Concurrent::Promise.new { p "bitfinex"; raise 'error' }

proc = Proc.new do
  puts 10
end

e = Concurrent::Promise.all?(cbr_promise, bitfinex_promise).execute.then(&proc)

sleep 1

yields

"cbr"
"bitfinex"
like image 85
Alexander Presber Avatar answered Sep 23 '22 03:09

Alexander Presber