ruby-concurrency / ruby-concurrency/concurrent-ruby
Promise.zip hangs on rejected promise in chain
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 5.8k
- Forks
- 420
- Avg merge
- 20h 45m
- Merged PRs (30d)
- 4
Description
Promise.zip seems to hang with any rejected promise in its collection for large enough collections (several hundred items).
Here is a minimal repro:
1.upto(1000).map do |n|
puts n
promises = Array.new(n) do |i|
Concurrent::Promise.new do
raise 'rejected' if i.zero?
'.'
end
end
all = Concurrent::Promise.zip(*promises).execute
all.wait(1)
raise 'failed' if all.state == :unscheduled
end
Removing the rejected promise (e.g., removing the raise 'rejected' if i.zero? line) causes the code to run without issue for higher n as expected.
Tested on concurrent-ruby version 1.1.6, Ubuntu 18.04.4, with various rubies installed via rbenv:
- MRI 2.7.1 (fails at
n= 340 both with and withoutconcurrent-ruby-ext) - MRI 2.6.0 (fails at
n= 261) - JRuby 9.2.11.1 (fails at
nusually somewhere between 100-500) - TruffleRuby 20.0.0 (fails randomly with
[ruby] WARNING StackOverflowError, sometimes handlingn> 10000, other times failing atn= 50)
Using the newer Promises APIs (e.g., replacing Concurrent::Promise.new with Concurrent::Promises.future and Concurrent::Promises.zip with Concurrent::Promises) seems to work without any issues for much higher n. This still seems like a valid bug for as long the original Promise APIs are still available and bugs are still being fixed in them.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided reproduction against the legacy Concurrent::Promise.zip API and compare its behavior with Concurrent::Promises.zip. Trace the rejection handling and completion behavior in Promise.zip; done means rejected collections complete without hanging, with a regression test covering a large collection.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100