[erlang-questions] Unidirectional linking?

Igor Ribeiro Sucupira igorrs@REDACTED
Thu Jun 2 06:33:34 CEST 2011


Well... I'm using something like the last code I posted (with a third
process that creates two monitors) and it's working fine so far.

As for supervision trees, I use them for some cases (usually for
processes that run indefinitely, which I spawn as gen_servers), mostly
because I don't see how they "fit" in the other cases (e.g. in this
discussion).
But maybe I just need to have a better look at supervisors. I got
"Erlang and OTP in Action" from a friend for my birthday. It could be
the opportunity.  :)

Thank you.
Igor.

On Wed, May 25, 2011 at 6:45 AM, Raimo Niskanen
<raimo+erlang-questions@REDACTED> wrote:
> On Wed, May 25, 2011 at 09:28:31AM +0200, Mazen Harake wrote:
>> Perhaps something like this:
>>
>> process_flag(trap_exit, true),
>> Parent = self(),
>> Child = spawn_link(fun() -> Parent ! (catch Op) end),
>> receive
>>   {'EXIT', ParentsParent, Reason} ->
>>     exit(Reason);
>>   Result ->
>>     Result
>>  after N ->
>>     unlink(Child),
>>     exit(Child, timeout),
>>     timeout
>> end.
>
> Can the parent always have trap_exit true?
>
> If so this becomes (rather) simple:
>
>  process_flag(trap_exit, true),
>  ,
>  ,
>  Parent = self(),
>  Ref = make_ref(),
>  Child = spawn_link(fun() -> Parent ! {Ref,Op()} end),
>  receive
>    {'EXIT',Child,Reason} ->
>      receive
>        {Ref,Result} ->
>          {ok,Result}
>      after 0 ->
>        {error,Reason}
>      end;
>  after N ->
>    exit(Child, timeout),
>      receive
>        {'EXIT',Child,timeout} ->
>          receive
>            {Ref,Result} ->
>              {ok,Result}
>          after 0 ->
>            timeout
>          end
>      end
>  end
>
> If you have no control over the parent trap_exit flag I see
> no other alternative than involving a third process.
>
> Note that when a linked process exits normally, the link
> causes no exit at the other end.
>
> You maybe should think about using supervisers
> and all the other heavy OTP stuff. It was designed for
> this kind of problems.
>
>
>
>>
>> if you get an exit signal from the parent's parent you will exit if you are
>> in the receive clause and you will ignore it (unless it is a kill) if you
>> are in between the unlink and exit child?
>>
>> I do however still think that this is very defensive and that the
>> probability of getting an exit between unlink and exit is very small unless
>> the timeout in N is exactly the same (very very close to) the timeout that
>> the parent's parent has for exiting the parent.
>>
>>
>>
>> On 25 May 2011 08:51, Igor Ribeiro Sucupira <igorrs@REDACTED> wrote:
>>
>> > Supposing someone used the same logic (with timeout/kill) to spawn the
>> > parent process, the parent could be killed at any moment (but yeah: it
>> > would be bad luck to have that happening right after it called
>> > unlink).
>> >
>> > Thanks.
>> > Igor.
>> >
>> > On Wed, May 25, 2011 at 3:20 AM, Mazen Harake <mazen.harake@REDACTED>
>> > wrote:
>> > > Why would someone "kill the parent"? Do you have processes which are
>> > > randomly choosing other processes to terminate? ;)
>> > >
>> > > If your answer is "No" then I would suggest that you just kill the worker
>> > > processes that is taking to long, kill it in cold blood, imo.
>> > >
>> > > There is no reason to think about too many "if"-scenarios when the
>> > scenarios
>> > > are too far fetched. Try the simple version first :)
>> > >
>> > > otherwise you can either trap_exits or use monitors instead.
>> > >
>> > > /M
>> > >
>> > > On 25 May 2011 08:00, Igor Ribeiro Sucupira <igorrs@REDACTED> wrote:
>> > >>
>> > >> Suppose there is a heavy operation Op that in some cases takes so long
>> > >> to finish that the caller loses interest in the result and gives up.
>> > >>
>> > >> I want to perform that operation in a way that allows me to:
>> > >> 1) Interrupt its execution if it does not finish in N milliseconds.
>> > >> 2) Interrupt its execution if the calling process exits (here I'm
>> > >> already supposing Op has to be run in another Erlang process, due to
>> > >> goal 1).
>> > >>
>> > >> To implement that, it seems unidirectional linking would be needed. Is
>> > >> there another safe and convenient way to do it?
>> > >>
>> > >> The first idea I had was something like this:
>> > >>
>> > >> Parent = self(),
>> > >> Child = spawn_link(fun() -> Parent ! (catch Op) end),
>> > >> receive Result -> Result
>> > >> after N -> unlink(Child), exit(Child, timeout), timeout
>> > >> end.
>> > >>
>> > >> But, if Parent is killed by another process right after calling
>> > >> unlink, Child would be left executing.
>> > >> Another problem is that I don't want Parent to die if Child exits for
>> > >> non-timeout reasons (although it seems very unlikely in the code
>> > >> above, with the catch).
>> > >>
>> > >> I was now thinking of substituting unlink(Child) with
>> > >> process_flag(trap_exit, true) and then kill Child, receive its exit
>> > >> message, set trap_exit to false again (I'm assuming it was false), and
>> > >> finally check if there were other exit messages (suiciding if it was
>> > >> the case).
>> > >>
>> > >> But then the code would become too ugly, so I got lazy and decided to
>> > >> post to this list.  :-)
>> > >>
>> > >> What do you think?
>> > >>
>> > >> Thanks.
>> > >> Igor.
>
> --
>
> / Raimo Niskanen, Erlang/OTP, Ericsson AB
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list