[erlang-questions] Calling multiple processes simultaneously

Raimo Niskanen <>
Tue May 24 09:39:37 CEST 2011


Hello.

I am just jumping in here; because it sounds like you guys
are trying to reinvent gen_server:multi_call/2..5.

But I have not read all posts so there is probably
something that invalidates it. Just wanted to point to
it in case not.... And the code might be worth reading.
You can probably forget all cruft about C-nodes and
legacy nodes that can not do monitor (if it still is there),
though.

  http://www.erlang.org/doc/man/gen_server.html#multi_call-2

/ Raimo



On Mon, May 23, 2011 at 01:20:23PM -0700, Geoff Cant wrote:
> 
> gen_server:call boils down to
> 
> call(Server, Msg, Timeout) ->
>    Ref = monitor(Server), % or make_ref()
>    Server ! {'$gen_call$', {self(), Ref}, Msg},
>    receive
>        {Ref, Reply} -> Reply
>        {'DOWN', Ref, _, _, Reason} -> exit(Reason)
>    after Timeout ->
>        exit(timeout)
>    end.
> 
> If you do:
> barrier(Servers, Msg) -> [ gen_server:call(S, Msg) || S <- Servers ],
> ok.
> 
> Then you'll wait at least Servers*2 message delays, and at worst Servers
> * the gen_server call default timeout (5s).
> 
> You could do all the calls concurrently with something like:
> 
> call(Servers, Msg, Timeout) ->
>     Refs = [{S, monitor(S)}|| S <- Servers],
>     [S ! {'$gen_call$', {self(), Ref}, Msg}
>      || {S, Ref} <- Refs ],
>     collect_replies(Refs, Timeout).
> 
> collect_replies([], _) -> [];
> collect_replies([{S, Ref} | Rest], Timeout) ->
>     receive
>         {Ref, Reply} -> [{S, Reply} | collect_replies(Rest, Timeout)];
>         {'DOWN', Ref, _, _, Reason} -> [{S, {error, Reason}} |
>             collect_replies(Rest, Timeout)]
>     after Timeout ->
>         %% Timeout is now expired for all servers.
>         [{S, {error, timeout}} | collect_replies(Rest, 0)]
>     end.
> 
> This contains a basic attempt to not wait N*Timeout at worst, but could
> be made closer to 1 timeout max by measuring the time from entering
> collect_replies to receiving a Ref message and subtracting that from
> Timeout before recurring.
> 
> This code doesn't handle all the special cases that gen:call does (
> https://github.com/erlang/otp/blob/master/lib/stdlib/src/gen.erl#L191 ),
> but should illustrate the idea.
> 
> --
> Geoff Cant
> 
> Martin Dimitrov <> writes:
> 
> > Hi, please, advise on this one,
> >
> > We have several hundred processes (gen_servers) . At one point the
> > program has to send them a message that needs to be handled before the
> > calling process can continue executing. This naturally led us to use
> > gen_server:call in loop over the processes.
> >
> > I started to wonder if there is a more efficient way of doing it since
> > the calling process doesn???t care about the return value ??? just needs to
> > be sure that all processes had handled the message. Can we somehow call
> > the processes simultaneously? Something similar to gen_server:multi_call
> > but for one node with different processes?
> >
> > Regards,
> >
> > Martin
> >
> > _______________________________________________
> > erlang-questions mailing list
> > 
> > http://erlang.org/mailman/listinfo/erlang-questions
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list