Skip to content

Instantly share code, notes, and snippets.

@lenary
Created April 10, 2012 20:30
Show Gist options
  • Save lenary/2354251 to your computer and use it in GitHub Desktop.
Save lenary/2354251 to your computer and use it in GitHub Desktop.
call multiple gen_servers in parallel
-module(call_servers).
% External Methods
-exports([call_servers/3]).
% Internal Methods that are needed anyway (I think)
-exports([call_server/3, wait_loop/2]).
call_servers(Servers, Message, Timeout) ->
Receiver = spawn(?MODULE, wait_loop, [self(), Servers, []]),
[spawn(?MODULE, call_server, [GServer, Receiver, Message]) || GServer <- Servers ],
receive
{done, Results} -> {ok, Results};
{unfinished, Results, Servers} -> {unfinished, Results, Servers};
OtherMessage ->
% not sure what to do if we get another message.
% this is naively going to just put any other messages at the back of the mailbox.
self() ! OtherMessage
after
Timeout*0.9 ->
Receiver ! abandon_ship,
wait_for_results(Timeout)
end.
wait_for_results(Timeout) ->
receive
{done, Results} -> {ok, Results};
{unfinished, Results, Servers} -> {unfinished, Results, Servers};
OtherMessage ->
% as above, no idea. put it on the end
self() ! OtherMessage
after
Timeout*0.1 ->
{error, not_even_unfinished_recieved}
end.
call_server(GServer, Receiver, Message) ->
Results = gen_server:call(GServer, Message),
Receiver ! {done, GServer, Results}.
wait_loop(Master, Servers, Results) ->
receive
abandon_ship ->
Master ! {unfinished, Results, Servers},
ok; % stop recursing
{done, GServer, GResults} when lists:member(GServer, Server) ->
Servers1 = lists:delete(GServer, Servers),
Results1 = [{GServer, GResults} | Results],
case Servers1 of
[] -> Master ! {done, Results1};
_ -> wait_loop(Servers1, Timeout, Results1)
end;
_ ->
% log something
wait_loop(Servers, Timeout, Results)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment