spawn without linking?

Joe Armstrong <>
Mon Apr 26 14:56:01 CEST 2004


On Thu, 22 Apr 2004, Sean Hinde wrote:

> 
> On 21 Apr 2004, at 04:20, Shawn Pearce wrote:
> 
> > Actually, it is that hard to do...  the OTP behaviors offer lots
> > of well tested/debugging implementations which handle the border
> > cases extremely well.  Which a naive quick implementation using
> > just the basic spawn_link/* and trap_exit won't get quite right on
> > the first few tries.
> >
> > OTP rocks for that reason alone... but yea, gen_server isn't the
> > most "Erlang" way to write a server, but its the Erlang/OTP way.
> 
> How about this which I had fun writing today. It is almost Erlangish, 
> and it is something like OTP, and it is exactly Joe's selective receive 
> example. I can't decide whether it is ugly or profoundly beautiful.

It is of course profoundly beautiful, but the syntax obscures the beauty.

Just overload the LHS of !! so you can write

	[A,B,C] !! M

This means send M to three processes (machines or whatever's) and
gather three replies yielding [V1,V2,V3]

Cheers

/Joe

> 
> Sean
> 
> %% Call a bunch of gen_servers with different requests in
> %% parallel and return successes and failures. Any which
> %% fail to answer within Timeout ms are included as failures.
> 
> %% We require that the calling process will continue to ignore
> %% late answers
> 
> multi_call(Requests, Timeout) ->
>      Mrefs = lists:map(
>                fun({Name, Req}) ->
>                        Mref = erlang:monitor(process, Name),
>                        Name ! {'$gen_call', {self(), Mref}, Req},
>                        {Name, Mref}
>                end, Requests),
>      get_results(Mrefs, [], [], Timeout, now()).
> 
> get_results([{Name, Mref}|T], Succ, Fail, Timeout, Now_at_start) ->
>      Timeout_val = max(Timeout - (timer:now_diff(now(), Now_at_start) 
> div 1000), 0),
>      receive
>          {Mref, Reply} ->
>              erlang:demonitor(Mref),
>              receive
>                  {'DOWN', Mref, _, _, _} ->
>                      get_results(T, [{Name, Reply}|Succ], Fail, Timeout, 
> Now_at_start)
>              after 0 ->
>                      get_results(T, [{Name, Reply}|Succ], Fail, Timeout, 
> Now_at_start)
>              end;
>          {'DOWN', Mref, _, _, _} ->
>              get_results(T, Succ, [Name|Fail], Timeout, Now_at_start)
>      after Timeout_val ->
>              erlang:demonitor(Mref),
>              get_results(T, Succ, [Name|Fail], Timeout, Now_at_start)
>      end;
> get_results([], Succ, Fail, _, _) ->
>      {Succ, Fail}.
> 
> max(A, B) when A >= B -> A;
> max(A, B)             -> B.
> 




More information about the erlang-questions mailing list