From 94d19cd0b27285de22b725b333c9f1a7258ba968 Mon Sep 17 00:00:00 2001 From: Ian Ker-Seymer Date: Tue, 6 Jun 2017 16:19:22 -0400 Subject: [PATCH 1/3] Add specs for Promise#zip/Promise.zip ordering --- spec/concurrent/promise_spec.rb | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/spec/concurrent/promise_spec.rb b/spec/concurrent/promise_spec.rb index 3fb35b276..ae6fa11b9 100644 --- a/spec/concurrent/promise_spec.rb +++ b/spec/concurrent/promise_spec.rb @@ -368,6 +368,27 @@ def get_ivar_from_args(opts) expect(composite).to be_rejected end + + it 'preserves ordering of the executed promises' do + promise1 = Promise.execute do + # resolves after the second promise + sleep 0.2 + 'one' + end + + promise2 = Promise.execute do + sleep 0.1 + 'two' + end + + promise3 = Promise.execute do + 'three' + end + + result = promise1.zip(promise2, promise3).value + + expect(result).to eql(['one', 'two', 'three']) + end end describe '.zip' do @@ -386,6 +407,27 @@ def get_ivar_from_args(opts) expect(composite).to be_rejected end + + it 'preserves ordering of the executed promises' do + promise1 = Promise.execute do + # resolves after the second promise + sleep 0.2 + 'one' + end + + promise2 = Promise.execute do + sleep 0.1 + 'two' + end + + promise3 = Promise.execute do + 'three' + end + + result = Promise.zip(promise1, promise2, promise3).value + + expect(result).to eql(['one', 'two', 'three']) + end end describe 'aggregators' do From 47befe994a6792af258aa0fb1396ca4eda8dd5ca Mon Sep 17 00:00:00 2001 From: Ian Ker-Seymer Date: Wed, 15 Nov 2017 23:24:47 -0500 Subject: [PATCH 2/3] Use CVs to test ordering of Promise#zip resolution --- spec/concurrent/promise_spec.rb | 42 ++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/spec/concurrent/promise_spec.rb b/spec/concurrent/promise_spec.rb index ae6fa11b9..f17828657 100644 --- a/spec/concurrent/promise_spec.rb +++ b/spec/concurrent/promise_spec.rb @@ -370,24 +370,38 @@ def get_ivar_from_args(opts) end it 'preserves ordering of the executed promises' do - promise1 = Promise.execute do - # resolves after the second promise - sleep 0.2 - 'one' - end + 10.times do + running = Mutex.new + cond = ConditionVariable.new + cond2 = ConditionVariable.new + executor = SimpleExecutorService.new - promise2 = Promise.execute do - sleep 0.1 - 'two' - end + p1 = Concurrent::Promise.execute(executor: executor) do + running.synchronize do + cond.wait(running) + 'one' + end + end - promise3 = Promise.execute do - 'three' - end + p2 = Concurrent::Promise.execute(executor: executor) do + running.synchronize do + cond2.wait(running) + 'two' + end + end - result = promise1.zip(promise2, promise3).value + p3 = Concurrent::Promise.execute(executor: executor) do + running.synchronize do + 'three' + end + end - expect(result).to eql(['one', 'two', 'three']) + cond2.signal + cond.signal + + result = Concurrent::Promise.zip(p1, p2, p3).value + expect(result) .to eq(['one', 'two', 'three']) + end end end From 8720d173da1245ce95d3d7949499d4a8536c4ad5 Mon Sep 17 00:00:00 2001 From: Petr Chalupa Date: Sat, 24 Feb 2018 21:44:38 +0100 Subject: [PATCH 3/3] Use CountDownLatch --- spec/concurrent/promise_spec.rb | 35 +++++++++------------------------ 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/spec/concurrent/promise_spec.rb b/spec/concurrent/promise_spec.rb index f17828657..c49930014 100644 --- a/spec/concurrent/promise_spec.rb +++ b/spec/concurrent/promise_spec.rb @@ -371,36 +371,19 @@ def get_ivar_from_args(opts) it 'preserves ordering of the executed promises' do 10.times do - running = Mutex.new - cond = ConditionVariable.new - cond2 = ConditionVariable.new + latch1 = CountDownLatch.new + latch2 = CountDownLatch.new executor = SimpleExecutorService.new - p1 = Concurrent::Promise.execute(executor: executor) do - running.synchronize do - cond.wait(running) - 'one' - end - end - - p2 = Concurrent::Promise.execute(executor: executor) do - running.synchronize do - cond2.wait(running) - 'two' - end - end - - p3 = Concurrent::Promise.execute(executor: executor) do - running.synchronize do - 'three' - end - end + p1 = Concurrent::Promise.execute(executor: executor) { latch1.wait; 'one' } + p2 = Concurrent::Promise.execute(executor: executor) { latch2.wait; 'two' } + p3 = Concurrent::Promise.execute(executor: executor) { 'three' } - cond2.signal - cond.signal + latch1.count_down + latch2.count_down - result = Concurrent::Promise.zip(p1, p2, p3).value - expect(result) .to eq(['one', 'two', 'three']) + result = Concurrent::Promise.zip(p1, p2, p3).value! + expect(result).to eq(['one', 'two', 'three']) end end end