spawn without linking?
Ulf Wiger
ulf.wiger@REDACTED
Mon Apr 26 20:19:34 CEST 2004
On Mon, 26 Apr 2004 14:56:01 +0200 (CEST), Joe Armstrong <joe@REDACTED>
wrote:
> On Thu, 22 Apr 2004, Sean Hinde wrote:
>> 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]
Ah, but Joe, you changed the semantics. Sean had a timeout argument,
which you don't. ;-)
BTW, Sean, you should rethink the implementation of the timeout.
I think it's better to start a timer and handle a timeout message.
In your present implementation, the "timer" will restart anytime
one of the servers responds, making it fuzzy what the timeout
really means.
Regards,
Uffe
>> %% 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.
>>
>
--
Ulf Wiger
More information about the erlang-questions
mailing list