Skip to content

Commit 4b224b1

Browse files
committed
Fix rescue behavior to be like Scala's Future#recover
1 parent 2a4d5d4 commit 4b224b1

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

lib/concurrent/next.rb

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def schedule(intended_time, executor = :fast, &task)
160160
# does not block a thread
161161
# @return [Future]
162162
def join(*futures)
163+
# TODO consider renaming to zip as in scala
163164
countdown = Concurrent::AtomicFixnum.new futures.size
164165
promise = OuterPromise.new(futures)
165166
futures.each { |future| future.add_callback :join_callback, countdown, promise, *futures }
@@ -300,13 +301,13 @@ def chain_delay(executor = default_executor, &callback)
300301

301302
# lazy version of #then
302303
def then_delay(executor = default_executor, &callback)
303-
delay = Delay.new(self, executor) { conditioned_callback callback }
304+
delay = Delay.new(self, executor) { conditioned_success_callback callback }
304305
delay.future
305306
end
306307

307308
# lazy version of #rescue
308309
def rescue_delay(executor = default_executor, &callback)
309-
delay = Delay.new(self, executor) { callback_on_failure callback }
310+
delay = Delay.new(self, executor) { conditioned_failure_callback callback }
310311
delay.future
311312
end
312313

@@ -436,11 +437,11 @@ def chain_callback(executor, promise, callback)
436437
end
437438

438439
def then_callback(executor, promise, callback)
439-
with_async(executor) { promise.evaluate_to { conditioned_callback callback } }
440+
with_async(executor) { promise.evaluate_to { conditioned_success_callback callback } }
440441
end
441442

442443
def rescue_callback(executor, promise, callback)
443-
with_async(executor) { promise.evaluate_to { callback_on_failure callback } }
444+
with_async(executor) { promise.evaluate_to { conditioned_failure_callback callback } }
444445
end
445446

446447
def with_async(executor)
@@ -471,10 +472,14 @@ def callback_on_failure(callback)
471472
callback.call reason if failed?
472473
end
473474

474-
def conditioned_callback(callback)
475+
def conditioned_success_callback(callback)
475476
self.success? ? callback.call(value) : raise(reason)
476477
end
477478

479+
def conditioned_failure_callback(callback)
480+
self.failed? ? callback.call(reason) : value
481+
end
482+
478483
def call_callback(method, *args)
479484
self.send method, *args
480485
end
@@ -615,6 +620,7 @@ def initialize(executor = :fast, &task)
615620
end
616621
end
617622

623+
# will be evaluated to task in intended_time
618624
class Scheduled < Promise
619625
def initialize(intended_time, executor = :fast, &task)
620626
super(executor)
@@ -702,11 +708,12 @@ def execute_once
702708
future5 = future3.with_default_executor(:io) # connects new future with different executor, the new future is completed when future3 is
703709
future6 = future5.then(&:capitalize) # executes on IO_EXECUTOR because default was set to :io on future5
704710
future7 = ConcurrentNext.join(future0, future3)
711+
future8 = future0.rescue { raise 'never happens' } # future0 succeeds so future8'll have same value as future 0
705712

706713
p future3, future5
707714
p future3.callbacks, future5.callbacks
708715

709-
futures = [future0, future1, future2, future3, future4, future5, future6, future7]
716+
futures = [future0, future1, future2, future3, future4, future5, future6, future7, future8]
710717
futures.each &:wait
711718

712719

@@ -721,6 +728,7 @@ def execute_once
721728
# 5 true boo io
722729
# 6 true Boo io
723730
# 7 true [3, "boo"] fast
731+
# 8 true 3 fast
724732

725733
puts '-- delay'
726734

@@ -782,7 +790,7 @@ def execute_once
782790
puts '-- scheduled'
783791

784792
start = Time.now.to_f
785-
ConcurrentNext.schedule(0.1) { 1 + 1 }.then { |v| p v, Time.now.to_f - start}
793+
ConcurrentNext.schedule(0.1) { 1 + 1 }.then { |v| p v, Time.now.to_f - start }
786794
sleep 0.2
787795

788796
puts '-- using shortcuts'

0 commit comments

Comments
 (0)