Skip to content

Commit d85aaf3

Browse files
davishmcclurgpitr-ch
authored andcommitted
Add option to not execute zipped promises
This restores the default behavior for zipped promises and adds an option (`execute`) to leave them unscheduled.
1 parent 2e8027a commit d85aaf3

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/concurrent/promise.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,13 @@ def flat_map(&block)
387387
#
388388
# @return [Promise<Array>]
389389
def self.zip(*promises)
390-
opts = promises.last.is_a?(::Hash) ? promises.pop : {}
390+
opts = promises.last.is_a?(::Hash) ? promises.pop.dup : {}
391391
opts[:executor] ||= ImmediateExecutor.new
392-
zero = Promise.new(opts) { [] }
392+
zero = if !opts.key?(:execute) || opts.delete(:execute)
393+
fulfill([], opts)
394+
else
395+
Promise.new(opts) { [] }
396+
end
393397

394398
promises.reduce(zero) do |p1, p2|
395399
p1.flat_map do |results|

spec/concurrent/promise_spec.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,21 @@ def get_ivar_from_args(opts)
357357
let(:promise2) { Promise.new(executor: :immediate) { 2 } }
358358
let(:promise3) { Promise.new(executor: :immediate) { [3] } }
359359

360-
it 'does not execute the returned Promise' do
360+
it 'executes the returned Promise by default' do
361361
composite = promise1.zip(promise2, promise3)
362362

363+
expect(composite).to be_fulfilled
364+
end
365+
366+
it 'executes the returned Promise when execute is true' do
367+
composite = promise1.zip(promise2, promise3, execute: true)
368+
369+
expect(composite).to be_fulfilled
370+
end
371+
372+
it 'does not execute the returned Promise when execute is false' do
373+
composite = promise1.zip(promise2, promise3, execute: false)
374+
363375
expect(composite).to be_unscheduled
364376
end
365377

@@ -389,9 +401,21 @@ def get_ivar_from_args(opts)
389401
let(:promise2) { Promise.new(executor: :immediate) { 2 } }
390402
let(:promise3) { Promise.new(executor: :immediate) { [3] } }
391403

392-
it 'does not execute the returned Promise' do
404+
it 'executes the returned Promise by default' do
393405
composite = Promise.zip(promise1, promise2, promise3)
394406

407+
expect(composite).to be_fulfilled
408+
end
409+
410+
it 'executes the returned Promise when execute is true' do
411+
composite = Promise.zip(promise1, promise2, promise3, execute: true)
412+
413+
expect(composite).to be_fulfilled
414+
end
415+
416+
it 'does not execute the returned Promise when execute is false' do
417+
composite = Promise.zip(promise1, promise2, promise3, execute: false)
418+
395419
expect(composite).to be_unscheduled
396420
end
397421

0 commit comments

Comments
 (0)