[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