File tree Expand file tree Collapse file tree 2 files changed +39
-7
lines changed Expand file tree Collapse file tree 2 files changed +39
-7
lines changed Original file line number Diff line number Diff line change @@ -1141,17 +1141,24 @@ def blocked_by
1141
1141
1142
1142
def process_on_done ( future )
1143
1143
countdown = super ( future )
1144
- value = future . value!
1145
1144
if countdown . nonzero?
1145
+ internal_state = future . internal_state
1146
+
1147
+ unless internal_state . success?
1148
+ complete_with internal_state
1149
+ return countdown
1150
+ end
1151
+
1152
+ value = internal_state . value
1146
1153
case value
1147
1154
when Future
1148
1155
@BlockedBy . push value
1149
1156
value . add_callback :pr_callback_notify_blocked , self
1150
1157
@Countdown . value
1151
1158
when Event
1152
- raise TypeError , 'cannot flatten to Event'
1159
+ evaluate_to ( lambda { raise TypeError , 'cannot flatten to Event' } )
1153
1160
else
1154
- raise TypeError , "returned value #{ value . inspect } is not a Future"
1161
+ evaluate_to ( lambda { raise TypeError , "returned value #{ value . inspect } is not a Future" } )
1155
1162
end
1156
1163
end
1157
1164
countdown
@@ -1174,6 +1181,10 @@ def clear_blocked_by!
1174
1181
@BlockedBy . clear
1175
1182
nil
1176
1183
end
1184
+
1185
+ def completable? ( countdown )
1186
+ !@Future . internal_state . completed? && super ( countdown )
1187
+ end
1177
1188
end
1178
1189
1179
1190
# @!visibility private
Original file line number Diff line number Diff line change 194
194
describe 'Future' do
195
195
it 'has sync and async callbacks' do
196
196
callbacks_tester = -> ( future ) do
197
- queue = Queue . new
197
+ queue = Queue . new
198
198
future . on_completion ( :io ) { |result | queue . push ( "async on_completion #{ result . inspect } " ) }
199
199
future . on_completion! { |result | queue . push ( "sync on_completion #{ result . inspect } " ) }
200
200
future . on_success ( :io ) { |value | queue . push ( "async on_success #{ value . inspect } " ) }
309
309
expect ( Concurrent . zip ( branch1 , branch2 ) . value! ) . to eq [ 2 , 3 ]
310
310
end
311
311
312
- it 'has flat map' do
313
- f = Concurrent . future { Concurrent . future { 1 } } . flat . then ( &:succ )
314
- expect ( f . value! ) . to eq 2
312
+ describe '#flat' do
313
+ it 'returns value of inner future' do
314
+ f = Concurrent . future { Concurrent . future { 1 } } . flat . then ( &:succ )
315
+ expect ( f . value! ) . to eq 2
316
+ end
317
+
318
+ it 'propagates failure of inner future' do
319
+ err = StandardError . new ( 'boo' )
320
+ f = Concurrent . future { Concurrent . failed_future ( err ) } . flat
321
+ expect ( f . reason ) . to eq err
322
+ end
323
+
324
+ it 'it propagates failure of the future which was suppose to provide inner future' do
325
+ f = Concurrent . future { raise 'boo' } . flat
326
+ expect ( f . reason . message ) . to eq 'boo'
327
+ end
328
+
329
+ it 'fails if inner value is not a future' do
330
+ f = Concurrent . future { 'boo' } . flat
331
+ expect ( f . reason ) . to be_an_instance_of TypeError
332
+
333
+ f = Concurrent . future { Concurrent . completed_event } . flat
334
+ expect ( f . reason ) . to be_an_instance_of TypeError
335
+ end
315
336
end
316
337
end
317
338
You can’t perform that action at this time.
0 commit comments