@@ -76,12 +76,23 @@ def schedule(intended_time, default_executor = :io, &task)
76
76
ScheduledPromise . new ( default_executor , intended_time ) . future . then ( &task )
77
77
end
78
78
79
- # Constructs new {Future} which is completed after all futures are complete. Its value is array
80
- # of dependent future values. If there is an error it fails with the first one.
81
- # @param [Event] futures
79
+ # Constructs new {Future} which is completed after all futures_and_or_events are complete. Its value is array
80
+ # of dependent future values. If there is an error it fails with the first one. Event does not
81
+ # have a value so it's represented by nil in the array of values.
82
+ # @param [Event] futures_and_or_events
82
83
# @return [Future]
83
- def zip ( *futures )
84
- ZipPromise . new ( futures , :io ) . future
84
+ def zip_futures ( *futures_and_or_events )
85
+ ZipFuturesPromise . new ( futures_and_or_events , :io ) . future
86
+ end
87
+
88
+ alias_method :zip , :zip_futures
89
+
90
+ # Constructs new {Event} which is completed after all futures_and_or_events are complete
91
+ # (Future is completed when Success or Failed).
92
+ # @param [Event] futures_and_or_events
93
+ # @return [Event]
94
+ def zip_events ( *futures_and_or_events )
95
+ ZipEventsPromise . new ( futures_and_or_events , :io ) . future
85
96
end
86
97
87
98
# Constructs new {Future} which is completed after first of the futures is complete.
@@ -95,6 +106,7 @@ def any(*futures)
95
106
# @return [Future]
96
107
def select ( *channels )
97
108
future do
109
+ # noinspection RubyArgCount
98
110
Channel . select do |s |
99
111
channels . each do |ch |
100
112
s . take ( ch ) { |value | [ value , ch ] }
@@ -503,9 +515,9 @@ def apply(block)
503
515
# @!visibility private
504
516
class PartiallyFailed < CompletedWithResult
505
517
def initialize ( value , reason )
518
+ super ( )
506
519
@Value = value
507
520
@Reason = reason
508
- super ( )
509
521
end
510
522
511
523
def success?
@@ -670,7 +682,7 @@ def schedule(intended_time)
670
682
# Zips with selected value form the suplied channels
671
683
# @return [Future]
672
684
def then_select ( *channels )
673
- ZipPromise . new ( [ self , Concurrent . select ( *channels ) ] , @DefaultExecutor ) . future
685
+ ZipFuturesPromise . new ( [ self , Concurrent . select ( *channels ) ] , @DefaultExecutor ) . future
674
686
end
675
687
676
688
# Changes default executor for rest of the chain
@@ -987,12 +999,16 @@ class InnerPromise < AbstractPromise
987
999
# @abstract
988
1000
# @!visibility private
989
1001
class BlockedPromise < InnerPromise
1002
+ def self . new ( *args , &block )
1003
+ promise = super ( *args , &block )
1004
+ promise . blocked_by . each { |f | f . add_callback :pr_callback_notify_blocked , promise }
1005
+ promise
1006
+ end
1007
+
990
1008
def initialize ( future , blocked_by_futures , countdown )
1009
+ super ( future )
991
1010
initialize_blocked_by ( blocked_by_futures )
992
1011
@Countdown = AtomicFixnum . new countdown
993
-
994
- super ( future )
995
- @BlockedBy . each { |f | f . add_callback :pr_callback_notify_blocked , self }
996
1012
end
997
1013
998
1014
# @api private
@@ -1053,9 +1069,9 @@ def on_completable(done_future)
1053
1069
class BlockedTaskPromise < BlockedPromise
1054
1070
def initialize ( blocked_by_future , default_executor , executor , &task )
1055
1071
raise ArgumentError , 'no block given' unless block_given?
1072
+ super Future . new ( self , default_executor ) , blocked_by_future , 1
1056
1073
@Executor = executor
1057
1074
@Task = task
1058
- super Future . new ( self , default_executor ) , blocked_by_future , 1
1059
1075
end
1060
1076
1061
1077
def executor
@@ -1203,8 +1219,8 @@ def on_completable(done_future)
1203
1219
# @!visibility private
1204
1220
class ZipFutureEventPromise < BlockedPromise
1205
1221
def initialize ( future , event , default_executor )
1206
- @FutureResult = future
1207
1222
super Future . new ( self , default_executor ) , [ future , event ] , 2
1223
+ @FutureResult = future
1208
1224
end
1209
1225
1210
1226
def on_completable ( done_future )
@@ -1215,9 +1231,9 @@ def on_completable(done_future)
1215
1231
# @!visibility private
1216
1232
class ZipFutureFuturePromise < BlockedPromise
1217
1233
def initialize ( future1 , future2 , default_executor )
1234
+ super Future . new ( self , default_executor ) , [ future1 , future2 ] , 2
1218
1235
@Future1Result = future1
1219
1236
@Future2Result = future2
1220
- super Future . new ( self , default_executor ) , [ future1 , future2 ] , 2
1221
1237
end
1222
1238
1223
1239
def on_completable ( done_future )
@@ -1256,62 +1272,54 @@ def on_completable(done_future)
1256
1272
end
1257
1273
1258
1274
# @!visibility private
1259
- class ZipPromise < BlockedPromise
1275
+ class ZipFuturesPromise < BlockedPromise
1260
1276
1261
1277
private
1262
1278
1263
1279
def initialize ( blocked_by_futures , default_executor )
1264
- klass = Event
1265
- blocked_by_futures . each do |f |
1266
- if f . is_a? ( Future )
1267
- if klass == Event
1268
- klass = Future
1269
- break
1270
- end
1271
- end
1272
- end
1273
-
1274
- # noinspection RubyArgCount
1275
- super ( klass . new ( self , default_executor ) , blocked_by_futures , blocked_by_futures . size )
1280
+ super ( Future . new ( self , default_executor ) , blocked_by_futures , blocked_by_futures . size )
1276
1281
1277
- if blocked_by_futures . empty?
1278
- on_completable nil
1279
- end
1282
+ on_completable nil if blocked_by_futures . empty?
1280
1283
end
1281
1284
1282
1285
def on_completable ( done_future )
1283
1286
all_success = true
1284
- values = [ ]
1285
- reasons = [ ]
1286
-
1287
- blocked_by . each do |future |
1288
- next unless future . is_a? ( Future )
1289
- success , value , reason = future . result
1287
+ values = Array . new ( blocked_by . size )
1288
+ reasons = Array . new ( blocked_by . size )
1290
1289
1291
- unless success
1292
- all_success = false
1290
+ blocked_by . each_with_index do |future , i |
1291
+ if future . is_a? ( Future )
1292
+ success , values [ i ] , reasons [ i ] = future . result
1293
+ all_success &&= success
1294
+ else
1295
+ values [ i ] = reasons [ i ] = nil
1293
1296
end
1294
-
1295
- values << value
1296
- reasons << reason
1297
1297
end
1298
1298
1299
1299
if all_success
1300
- if values . empty?
1301
- complete_with Event ::COMPLETED
1302
- else
1303
- if values . size == 1
1304
- complete_with Future ::Success . new ( values . first )
1305
- else
1306
- complete_with Future ::SuccessArray . new ( values )
1307
- end
1308
- end
1300
+ complete_with Future ::SuccessArray . new ( values )
1309
1301
else
1310
1302
complete_with Future ::PartiallyFailed . new ( values , reasons )
1311
1303
end
1312
1304
end
1313
1305
end
1314
1306
1307
+ # @!visibility private
1308
+ class ZipEventsPromise < BlockedPromise
1309
+
1310
+ private
1311
+
1312
+ def initialize ( blocked_by_futures , default_executor )
1313
+ super ( Event . new ( self , default_executor ) , blocked_by_futures , blocked_by_futures . size )
1314
+
1315
+ on_completable nil if blocked_by_futures . empty?
1316
+ end
1317
+
1318
+ def on_completable ( done_future )
1319
+ complete_with Event ::COMPLETED
1320
+ end
1321
+ end
1322
+
1315
1323
# @!visibility private
1316
1324
class AnyPromise < BlockedPromise
1317
1325
@@ -1354,8 +1362,8 @@ def touch
1354
1362
private
1355
1363
1356
1364
def initialize ( default_executor , value )
1357
- @Value = value
1358
1365
super Future . new ( self , default_executor )
1366
+ @Value = value
1359
1367
end
1360
1368
end
1361
1369
@@ -1373,6 +1381,8 @@ def inspect
1373
1381
private
1374
1382
1375
1383
def initialize ( default_executor , intended_time )
1384
+ super Event . new ( self , default_executor )
1385
+
1376
1386
@IntendedTime = intended_time
1377
1387
1378
1388
in_seconds = begin
@@ -1385,8 +1395,6 @@ def initialize(default_executor, intended_time)
1385
1395
[ 0 , schedule_time . to_f - now . to_f ] . max
1386
1396
end
1387
1397
1388
- super Event . new ( self , default_executor )
1389
-
1390
1398
Concurrent . global_timer_set . post ( in_seconds ) do
1391
1399
@Future . complete_with Event ::COMPLETED
1392
1400
end
0 commit comments