@@ -20,7 +20,7 @@ module Concurrent
20
20
module Edge
21
21
22
22
module FutureShortcuts
23
- # User is responsible for completing the event once.
23
+ # User is responsible for completing the event once by {CompletableEvent#complete}
24
24
# @return [CompletableEvent]
25
25
def event ( default_executor = :io )
26
26
CompletableEventPromise . new ( default_executor ) . future
@@ -29,42 +29,57 @@ def event(default_executor = :io)
29
29
# @overload future(default_executor = :io, &task)
30
30
# Constructs new Future which will be completed after block is evaluated on executor. Evaluation begins immediately.
31
31
# @return [Future]
32
- # @note FIXME allow to pass in variables as Thread.new(args) {|args| _ } does
33
32
# @overload future(default_executor = :io)
34
- # User is responsible for completing the future once.
33
+ # User is responsible for completing the future once by {CompletableFuture#success} or {CompletableFuture#fail}
35
34
# @return [CompletableFuture]
36
- def future ( default_executor = :io , &task )
35
+ def future ( *args , &task )
36
+ future_on :io , *args , &task
37
+ end
38
+
39
+ def future_on ( default_executor , *args , &task )
37
40
if task
38
- ImmediatePromise . new ( default_executor ) . event . chain ( &task )
41
+ ImmediatePromise . new ( default_executor , * args ) . future . then ( &task )
39
42
else
40
43
CompletableFuturePromise . new ( default_executor ) . future
41
44
end
42
45
end
43
46
44
47
alias_method :async , :future
45
48
46
- # Constructs new Future which will be completed after block is evaluated on executor. Evaluation is delayed until
47
- # requested by `#wait`, `#value`, `#value!`, etc.
49
+ # Constructs new Future which will evaluate to the block after
50
+ # requested by calling `#wait`, `#value`, `#value!`, etc. on it or on any of the chained futures .
48
51
# @return [Delay]
49
- def delay ( default_executor = :io , &task )
50
- Delay . new ( default_executor ) . event . chain ( &task )
52
+ def delay ( *args , &task )
53
+ delay_on :io , *args , &task
54
+ end
55
+
56
+ def delay_on ( default_executor , *args , &task )
57
+ Delay . new ( default_executor , *args ) . future . then ( &task )
51
58
end
52
59
53
60
# Schedules the block to be executed on executor in given intended_time.
54
61
# @return [Future]
55
- def schedule ( intended_time , default_executor = :io , &task )
56
- ScheduledPromise . new ( intended_time , default_executor ) . future . chain ( &task )
62
+ def schedule ( intended_time , *args , &task )
63
+ schedule_on :io , intended_time , *args , &task
64
+ end
65
+
66
+ def schedule_on ( default_executor , intended_time , *args , &task )
67
+ ScheduledPromise . new ( default_executor , intended_time , *args ) . future . then ( &task )
57
68
end
58
69
59
- # fails on first error
60
- # does not block a thread
70
+ # Constructs new {Future} which is completed after all futures are complete. Its value is array
71
+ # of dependent future values. If there is an error it fails with the first one.
72
+ # @param [Event] futures
61
73
# @return [Future]
62
74
def zip ( *futures )
63
- AllPromise . new ( futures ) . future
75
+ AllPromise . new ( futures , :io ) . future
64
76
end
65
77
78
+ # Constructs new {Future} which is completed after first of the futures is complete.
79
+ # @param [Event] futures
80
+ # @return [Future]
66
81
def any ( *futures )
67
- AnyPromise . new ( futures ) . future
82
+ AnyPromise . new ( futures , :io ) . future
68
83
end
69
84
70
85
def post! ( *args , &job )
@@ -89,7 +104,7 @@ def post_on(executor, *args, &job)
89
104
class Event < Synchronization ::Object
90
105
extend FutureShortcuts
91
106
92
- def initialize ( promise , default_executor = :io )
107
+ def initialize ( promise , default_executor )
93
108
@Promise = promise
94
109
@DefaultExecutor = default_executor
95
110
@Touched = AtomicBoolean . new ( false )
@@ -157,7 +172,7 @@ def delay
157
172
end
158
173
159
174
def schedule ( intended_time )
160
- chain { ScheduledPromise . new ( intended_time ) . future . zip ( self ) } . flat
175
+ chain { ScheduledPromise . new ( @DefaultExecutor , intended_time ) . event . zip ( self ) } . flat
161
176
end
162
177
163
178
# @yield [success, value, reason] executed async on `executor` when completed
@@ -172,7 +187,7 @@ def on_completion!(&callback)
172
187
add_callback :pr_callback_on_completion , callback
173
188
end
174
189
175
- def with_default_executor ( executor = @DefaultExecutor )
190
+ def with_default_executor ( executor )
176
191
AllPromise . new ( [ self ] , executor ) . future
177
192
end
178
193
@@ -615,7 +630,7 @@ def evaluate_to(*args, block)
615
630
class CompletableEventPromise < AbstractPromise
616
631
public :complete
617
632
618
- def initialize ( default_executor = :io )
633
+ def initialize ( default_executor )
619
634
super CompletableEvent . new ( self , default_executor )
620
635
end
621
636
end
@@ -624,7 +639,7 @@ def initialize(default_executor = :io)
624
639
class CompletableFuturePromise < AbstractPromise
625
640
# TODO consider to allow being blocked_by
626
641
627
- def initialize ( default_executor = :io )
642
+ def initialize ( default_executor )
628
643
super CompletableFuture . new ( self , default_executor )
629
644
end
630
645
@@ -732,7 +747,7 @@ def on_completable(done_future)
732
747
733
748
# @abstract
734
749
class BlockedTaskPromise < BlockedPromise
735
- def initialize ( blocked_by_future , default_executor = :io , executor = default_executor , &task )
750
+ def initialize ( blocked_by_future , default_executor , executor , &task )
736
751
raise ArgumentError , 'no block given' unless block_given?
737
752
@Executor = executor
738
753
@Task = task
@@ -747,7 +762,7 @@ def executor
747
762
class ThenPromise < BlockedTaskPromise
748
763
private
749
764
750
- def initialize ( blocked_by_future , default_executor = :io , executor = default_executor , &task )
765
+ def initialize ( blocked_by_future , default_executor , executor , &task )
751
766
raise ArgumentError , 'only Future can be appended with then' unless blocked_by_future . is_a? Future
752
767
super blocked_by_future , default_executor , executor , &task
753
768
end
@@ -766,7 +781,7 @@ def on_completable(done_future)
766
781
class RescuePromise < BlockedTaskPromise
767
782
private
768
783
769
- def initialize ( blocked_by_future , default_executor = :io , executor = default_executor , &task )
784
+ def initialize ( blocked_by_future , default_executor , executor , &task )
770
785
raise ArgumentError , 'only Future can be rescued' unless blocked_by_future . is_a? Future
771
786
super blocked_by_future , default_executor , executor , &task
772
787
end
@@ -794,8 +809,16 @@ def on_completable(done_future)
794
809
795
810
# will be immediately completed
796
811
class ImmediatePromise < InnerPromise
797
- def initialize ( default_executor = :io )
798
- super Event . new ( self , default_executor ) . complete
812
+ def initialize ( default_executor , *args )
813
+ # TODO optimize, create completed futures directly
814
+ super case args . size
815
+ when 0
816
+ Event . new ( self , default_executor ) . complete
817
+ when 1
818
+ Future . new ( self , default_executor ) . complete ( true , args [ 0 ] , nil )
819
+ else
820
+ ArrayFuture . new ( self , default_executor ) . complete ( true , args , nil )
821
+ end
799
822
end
800
823
end
801
824
@@ -808,7 +831,7 @@ def blocked_by
808
831
809
832
def process_on_done ( future )
810
833
countdown = super ( future )
811
- value = future . value
834
+ value = future . value!
812
835
if countdown . nonzero?
813
836
case value
814
837
when Future
@@ -824,7 +847,7 @@ def process_on_done(future)
824
847
countdown
825
848
end
826
849
827
- def initialize ( blocked_by_future , levels = 1 , default_executor = :io )
850
+ def initialize ( blocked_by_future , levels , default_executor )
828
851
raise ArgumentError , 'levels has to be higher than 0' if levels < 1
829
852
blocked_by_future . is_a? Future or
830
853
raise ArgumentError , 'only Future can be flatten'
@@ -851,7 +874,7 @@ class AllPromise < BlockedPromise
851
874
852
875
private
853
876
854
- def initialize ( blocked_by_futures , default_executor = :io )
877
+ def initialize ( blocked_by_futures , default_executor )
855
878
klass = Event
856
879
blocked_by_futures . each do |f |
857
880
if f . is_a? ( Future )
@@ -901,7 +924,7 @@ class AnyPromise < BlockedPromise
901
924
902
925
private
903
926
904
- def initialize ( blocked_by_futures , default_executor = :io )
927
+ def initialize ( blocked_by_futures , default_executor )
905
928
blocked_by_futures . all? { |f | f . is_a? Future } or
906
929
raise ArgumentError , 'accepts only Futures not Events'
907
930
super ( Future . new ( self , default_executor ) , blocked_by_futures , blocked_by_futures . size )
@@ -918,13 +941,28 @@ def on_completable(done_future)
918
941
919
942
class Delay < InnerPromise
920
943
def touch
921
- complete
944
+ case @Args . size
945
+ when 0
946
+ @Future . complete
947
+ when 1
948
+ @Future . complete ( true , @Args [ 0 ] , nil )
949
+ else
950
+ @Future . complete ( true , @Args , nil )
951
+ end
922
952
end
923
953
924
954
private
925
955
926
- def initialize ( default_executor = :io )
927
- super Event . new ( self , default_executor )
956
+ def initialize ( default_executor , *args )
957
+ @Args = args
958
+ super case args . size
959
+ when 0
960
+ Event . new ( self , default_executor )
961
+ when 1
962
+ Future . new ( self , default_executor )
963
+ else
964
+ ArrayFuture . new ( self , default_executor )
965
+ end
928
966
end
929
967
end
930
968
@@ -940,7 +978,7 @@ def inspect
940
978
941
979
private
942
980
943
- def initialize ( intended_time , default_executor = :io )
981
+ def initialize ( default_executor , intended_time , * args )
944
982
@IntendedTime = intended_time
945
983
946
984
in_seconds = begin
@@ -953,9 +991,26 @@ def initialize(intended_time, default_executor = :io)
953
991
[ 0 , schedule_time . to_f - now . to_f ] . max
954
992
end
955
993
956
- super Event . new ( self , default_executor )
994
+ super case args . size
995
+ when 0
996
+ Event . new ( self , default_executor )
997
+ when 1
998
+ Future . new ( self , default_executor )
999
+ else
1000
+ ArrayFuture . new ( self , default_executor )
1001
+ end
1002
+
1003
+ Concurrent . global_timer_set . post ( in_seconds , *args ) do |*args |
1004
+ case args . size
1005
+ when 0
1006
+ @Future . complete
1007
+ when 1
1008
+ @Future . complete ( true , args [ 0 ] , nil )
1009
+ else
1010
+ @Future . complete ( true , args , nil )
1011
+ end
1012
+ end
957
1013
958
- Concurrent . global_timer_set . post ( in_seconds ) { complete }
959
1014
end
960
1015
end
961
1016
end
0 commit comments