This is draft code of asyncronous data-processing:
process_all_items(Items) ->
Monitors = lists:map(fun process_single_item/1, Items),
_MonitoredPIDs = lists:map(fun({Pid, _MonitorRef}) -> Pid end, Monitors),
yield_results(Monitors, []).
process_single_item(Item) ->
ParentPid = self(),
spawn_monitor(fun() ->
Result = case process_single_item_logic(Item) of
{ok, Result} -> {<data ok, something>};
{error, Reason} -> {<error, something2>};
end,
ParentPid ! {self(), Result}
end).
yield_results([], Results) ->
lists:reverse(Results);
% (!)
yield_results([MonitorRef | Rest], Results) ->
receive
% (1) (?) How to handle only my PIDs?
{_Pid, Result} ->
yield_results(Rest, [Result | Results]);
% (2) (?) How to handle only my PIDs?
{'DOWN', _ActualMonitorRef, process, _Pid, _Reason} ->
yield_results(Rest, Results)
after 5000 ->
% (3) (?) How to throw only for my PIDs?
throw("Timeout!")
end.
How will I ensure that in yield_results(..)
ONLY the messages with the certain, previously spawned PIDs, are processed? The ones contained in Monitors