@@ -164,37 +164,44 @@ defmodule Task.Supervised do
164
164
# about our reference to it.
165
165
send ( monitor_pid , { parent , monitor_ref } )
166
166
167
- stream_reduce ( acc , max_concurrency , _spawned = 0 , _delivered = 0 , _waiting = % { } , next ,
168
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
167
+ config = % {
168
+ reducer: reducer ,
169
+ monitor_pid: monitor_pid ,
170
+ monitor_ref: monitor_ref ,
171
+ timeout: timeout ,
172
+ on_timeout: on_timeout ,
173
+ }
174
+ stream_reduce ( acc , max_concurrency , _spawned = 0 , _delivered = 0 , _waiting = % { } , next , config )
169
175
end
170
176
171
- defp stream_reduce ( { :halt , acc } , _max , _spawned , _delivered , _waiting , next ,
172
- _reducer , monitor_pid , monitor_ref , timeout , _on_timeout ) do
177
+ defp stream_reduce ( { :halt , acc } , _max , _spawned , _delivered , _waiting , next , config ) do
178
+ % { monitor_pid: monitor_pid , monitor_ref: monitor_ref , timeout: timeout } = config
173
179
stream_close ( monitor_pid , monitor_ref , timeout )
174
180
is_function ( next ) && next . ( { :halt , [ ] } )
175
181
{ :halted , acc }
176
182
end
177
183
178
- defp stream_reduce ( { :suspend , acc } , max , spawned , delivered , waiting , next ,
179
- reducer , monitor_pid , monitor_ref , timeout , on_timeout ) do
180
- continuation = & stream_reduce ( & 1 , max , spawned , delivered , waiting , next , reducer , monitor_pid , monitor_ref , timeout , on_timeout )
184
+ defp stream_reduce ( { :suspend , acc } , max , spawned , delivered , waiting , next , config ) do
185
+ continuation = & stream_reduce ( & 1 , max , spawned , delivered , waiting , next , config )
181
186
{ :suspended , acc , continuation }
182
187
end
183
188
184
189
# All spawned, all delivered, next is :done.
185
190
defp stream_reduce ( { :cont , acc } , _max , spawned , delivered , _waiting , next ,
186
- _reducer , monitor_pid , monitor_ref , timeout , _on_timeout )
191
+ % { monitor_pid: monitor_pid , monitor_ref: monitor_ref , timeout: timeout } )
187
192
when spawned == delivered and next == :done do
188
193
stream_close ( monitor_pid , monitor_ref , timeout )
189
194
{ :done , acc }
190
195
end
191
196
192
197
# No more tasks to spawn because max == 0 or next is :done. We wait for task
193
198
# responses or tasks going down.
194
- defp stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next ,
195
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
199
+ defp stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next , config )
196
200
when max == 0
197
201
when next == :done do
202
+ % { monitor_pid: monitor_pid , monitor_ref: monitor_ref ,
203
+ timeout: timeout , on_timeout: on_timeout } = config
204
+
198
205
receive do
199
206
# The task at position "position" replied with "value". We put the
200
207
# response in the "waiting" map and do nothing, since we'll only act on
@@ -203,8 +210,7 @@ defmodule Task.Supervised do
203
210
{ { ^ monitor_ref , position } , value } ->
204
211
% { ^ position => { pid , :running } } = waiting
205
212
waiting = Map . put ( waiting , position , { pid , { :ok , value } } )
206
- stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next ,
207
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
213
+ stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next , config )
208
214
209
215
# The task at position "position" died for some reason. We check if it
210
216
# replied already (then the death is peaceful) or if it's still running
@@ -231,8 +237,7 @@ defmodule Task.Supervised do
231
237
Map . put ( waiting , position , { nil , { :exit , :timeout } } )
232
238
end
233
239
end
234
- stream_deliver ( { :cont , acc } , max + 1 , spawned , delivered , waiting , next ,
235
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
240
+ stream_deliver ( { :cont , acc } , max + 1 , spawned , delivered , waiting , next , config )
236
241
237
242
# The monitor process died. We just cleanup the messages from the monitor
238
243
# process and exit.
@@ -242,8 +247,9 @@ defmodule Task.Supervised do
242
247
end
243
248
end
244
249
245
- defp stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next ,
246
- reducer , monitor_pid , monitor_ref , timeout , on_timeout ) do
250
+ defp stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next , config ) do
251
+ % { monitor_pid: monitor_pid , monitor_ref: monitor_ref ,
252
+ timeout: timeout } = config
247
253
try do
248
254
next . ( { :cont , [ ] } )
249
255
catch
@@ -254,30 +260,28 @@ defmodule Task.Supervised do
254
260
else
255
261
{ :suspended , [ value ] , next } ->
256
262
waiting = stream_spawn ( value , spawned , waiting , monitor_pid , monitor_ref , timeout )
257
- stream_reduce ( { :cont , acc } , max - 1 , spawned + 1 , delivered , waiting , next ,
258
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
263
+ stream_reduce ( { :cont , acc } , max - 1 , spawned + 1 , delivered , waiting , next , config )
259
264
{ _ , [ value ] } ->
260
265
waiting = stream_spawn ( value , spawned , waiting , monitor_pid , monitor_ref , timeout )
261
- stream_reduce ( { :cont , acc } , max - 1 , spawned + 1 , delivered , waiting , :done ,
262
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
266
+ stream_reduce ( { :cont , acc } , max - 1 , spawned + 1 , delivered , waiting , :done , config )
263
267
{ _ , [ ] } ->
264
- stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , :done ,
265
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
268
+ stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , :done , config )
266
269
end
267
270
end
268
271
269
- defp stream_deliver ( { :suspend , acc } , max , spawned , delivered , waiting , next ,
270
- reducer , monitor_pid , monitor_ref , timeout , on_timeout ) do
271
- continuation = & stream_deliver ( & 1 , max , spawned , delivered , waiting , next , reducer , monitor_pid , monitor_ref , timeout , on_timeout )
272
+ defp stream_deliver ( { :suspend , acc } , max , spawned , delivered , waiting , next , config ) do
273
+ continuation = & stream_deliver ( & 1 , max , spawned , delivered , waiting , next , config )
272
274
{ :suspended , acc , continuation }
273
275
end
274
- defp stream_deliver ( { :halt , acc } , max , spawned , delivered , waiting , next ,
275
- reducer , monitor_pid , monitor_ref , timeout , on_timeout ) do
276
- stream_reduce ( { :halt , acc } , max , spawned , delivered , waiting , next ,
277
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
276
+
277
+ defp stream_deliver ( { :halt , acc } , max , spawned , delivered , waiting , next , config ) do
278
+ stream_reduce ( { :halt , acc } , max , spawned , delivered , waiting , next , config )
278
279
end
279
- defp stream_deliver ( { :cont , acc } , max , spawned , delivered , waiting , next ,
280
- reducer , monitor_pid , monitor_ref , timeout , on_timeout ) do
280
+
281
+ defp stream_deliver ( { :cont , acc } , max , spawned , delivered , waiting , next , config ) do
282
+ % { reducer: reducer , monitor_pid: monitor_pid ,
283
+ monitor_ref: monitor_ref , timeout: timeout } = config
284
+
281
285
case waiting do
282
286
% { ^ delivered => { nil , reply } } ->
283
287
try do
@@ -290,12 +294,10 @@ defmodule Task.Supervised do
290
294
:erlang . raise ( kind , reason , stacktrace )
291
295
else
292
296
pair ->
293
- stream_deliver ( pair , max , spawned , delivered + 1 , Map . delete ( waiting , delivered ) , next ,
294
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
297
+ stream_deliver ( pair , max , spawned , delivered + 1 , Map . delete ( waiting , delivered ) , next , config )
295
298
end
296
299
% { } ->
297
- stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next ,
298
- reducer , monitor_pid , monitor_ref , timeout , on_timeout )
300
+ stream_reduce ( { :cont , acc } , max , spawned , delivered , waiting , next , config )
299
301
end
300
302
end
301
303
@@ -356,13 +358,24 @@ defmodule Task.Supervised do
356
358
# process waits, this process dies with the same reason.
357
359
receive do
358
360
{ ^ parent_pid , monitor_ref } ->
359
- stream_monitor_loop ( parent_pid , parent_ref , mfa , spawn , monitor_ref , _running_tasks = % { } , timeout )
361
+ config = % {
362
+ parent_pid: parent_pid ,
363
+ parent_ref: parent_ref ,
364
+ mfa: mfa ,
365
+ spawn: spawn ,
366
+ monitor_ref: monitor_ref ,
367
+ timeout: timeout ,
368
+ }
369
+ stream_monitor_loop ( _running_tasks = % { } , config )
360
370
{ :DOWN , ^ parent_ref , _ , _ , reason } ->
361
371
exit ( reason )
362
372
end
363
373
end
364
374
365
- defp stream_monitor_loop ( parent_pid , parent_ref , mfa , spawn , monitor_ref , running_tasks , timeout ) do
375
+ defp stream_monitor_loop ( running_tasks , config ) do
376
+ % { parent_pid: parent_pid , parent_ref: parent_ref , mfa: mfa ,
377
+ spawn: spawn , monitor_ref: monitor_ref , timeout: timeout } = config
378
+
366
379
receive do
367
380
# The parent process is telling us to spawn a new task to process
368
381
# "value". We spawn it and notify the parent about its pid.
@@ -379,7 +392,7 @@ defmodule Task.Supervised do
379
392
timed_out?: false ,
380
393
}
381
394
running_tasks = Map . put ( running_tasks , ref , task_info )
382
- stream_monitor_loop ( parent_pid , parent_ref , mfa , spawn , monitor_ref , running_tasks , timeout )
395
+ stream_monitor_loop ( running_tasks , config )
383
396
384
397
# The parent process is telling us to stop because the stream is being
385
398
# closed. In this case, we forcely kill all spawned processes and then
@@ -410,7 +423,7 @@ defmodule Task.Supervised do
410
423
:ok = Process . cancel_timer ( timer_ref , async: true , info: false )
411
424
message_kind = if ( timed_out? , do: :timed_out , else: :down )
412
425
send ( parent_pid , { message_kind , { monitor_ref , position } , reason } )
413
- stream_monitor_loop ( parent_pid , parent_ref , mfa , spawn , monitor_ref , running_tasks , timeout )
426
+ stream_monitor_loop ( running_tasks , config )
414
427
415
428
# One of the spawned processes timed out. We kill that process here
416
429
# regardless of the value of :on_timeout. We then send a message to the
@@ -425,10 +438,10 @@ defmodule Task.Supervised do
425
438
_other ->
426
439
running_tasks
427
440
end
428
- stream_monitor_loop ( parent_pid , parent_ref , mfa , spawn , monitor_ref , running_tasks , timeout )
441
+ stream_monitor_loop ( running_tasks , config )
429
442
430
443
{ :EXIT , _ , _ } ->
431
- stream_monitor_loop ( parent_pid , parent_ref , mfa , spawn , monitor_ref , running_tasks , timeout )
444
+ stream_monitor_loop ( running_tasks , config )
432
445
end
433
446
end
434
447
0 commit comments