Say I have a list of file names (.zip). I want to extract the files concurrently (parallel), and for each extracted file, process them in parallel. My current code is some what like:
start() ->
% ..
Pid = spawn_link(fun process/0),
Pid ! {self(), process_stats},
receive
{Pid, Response} -> Response;
{'EXIT', Pid, Reason} -> ..
end.
process() ->
receive
{Pid, process_stats} ->
Apps = get_apps(),
Archive = spawn_link(fun archive/0),
lists:foreach(fun({Id, AppId}) ->
Archive ! {self(), {extract, ?STATS_DIR++AppId++".zip", Pid}}
end, Apps),
process();
{Pid, {onextract, FilesList, Reply}} ->
Reply ! {self(), ok}, %
process();
end.
archive() ->
receive
{Pid, {extract, FilePath, Reply}} -> % Passing in Reply so that the receive block can send back message to the initiator. But it looks odd.
{ok, FilesList} = zip:extract(FilePath, [{cwd, ?STATS_DIR}]),
Pid ! {self(), {onextract, FilesList, Reply}},
archive()
end.
get_apps() -> ok. % returns a list of file names.
So, my question is I'm spawing only one process Archive
and sending multiple messages. In doing so will the messages be processed concurrently? The Inside Erlang VM paper says that there are multiple run queues for each scheduler, so I'm assuming that messages can be processed concurrently? Or in order to process messages concurrently do I have to spawn multiple processes and send them one message each? Like in
lists:foreach(fun({Id, AppId}) ->
Archive = spawn_link(fun archive/0),
Archive ! {self(), {extract, ?STATS_DIR++AppId++".zip"}}, % Here I don't have to send the Reply Pid as the receive statement is within.
receive
{Archive, {onextract, FilesList}} -> ok. % Is it ok to have nested receive blocks within a process?
end
end, Apps),
Is it ok to have a process to have nested receive blocks? Which approach is more appropriate here?