[erlang-questions] Question about gen_server:multi_call/2
Scott Lystig Fritchie
fritchie@REDACTED
Tue May 13 04:22:58 CEST 2008
Kevin A. Smith <kevin@REDACTED> wrote:
ks> I've been reading the man page on gen_server and the section
ks> describing multi_call/2 states:
Alas, gen_server:multi_call() cannot be used with non-locally-registered
servers. You need to roll your own mechanism to do what you're looking
for, which isn't too difficult to do(*) for the simple case. The
complexity lies in dealing with what happens when one of the remote
servers fails.
Using middle-man processes makes life a lot easier. And by using
gen_server:call(), we get the remote node monitoring for free. Untested
code, beware.
%% Inspired by dim memory of Joe Armstrong wisdom from years ago, bugs
%% mine not his.
multi_call(SpecList, Term, Timeout) when is_integer(Timeout) ->
Me = self(),
Pids = [spawn(fun() -> X = catch gen_server:call(Spec, Term, Timeout),
Me ! {self(), X}
end) || Spec <- SpecList],
[receive {Pid, X} -> X end || Pid <- Pids].
Which doesn't sort real vs. error messages, like gen_server:multi_call()
does. The above assumes the spawned pids never crashing (and thus
keeping you waiting forever), gen_server:call() handling server
failures, and perhaps several other assumptions I'm forgetting (and
probably let bugs sneak in).
See also in this mailing list (or was it on a TrapExit forum?), perhaps,
discussion about implementing pmap() robustly.
-Scott
(*) But I agree that multi_call() using a mix of Pids, {registered_name,
node}, and {global, Name} should be part of OTP's gen_server.
More information about the erlang-questions
mailing list