exit in fun running via timer:apply_interval/4

Reto Kramer <>
Wed Jun 8 01:31:59 CEST 2005


Thanks Mark and Bengt!

I've settled on casting a message to a gen_server triggered by a timer 
on a regular basis.

That way the code in the apply_interval is trivial and I simply don't 
worry about it breaking. Should the processing of the message that the 
timer casts break then gen_server will crash and the exit from that 
activity will infect the rest of the system as desired.

- Reto

On Jun 7, 2005, at 2:33 PM, Mark Scandariato wrote:

>
> On Jun 7, 2005, at 7:11 AM, Bengt Kleberg wrote:
>
>> On 2005-06-03 20:53, Reto Kramer wrote:
>>> Folks,
>>> I'm looking for the best (elegant) way to make sure that if there's 
>>> an exit in the Mod:Fun that I run via timer:apply_interval/4, the 
>>> "parent" process (the one that scheduled the timer) will receive the 
>>> exit message, so I can programmatically react to it (and e.g. 
>>> shutdown my system).
>>> I'm sure someone out there has an elegant solution.
>>
>> i do not have a solution. instead i have a follow-up question:
>>
>> what does the following from the man page of the timer module mean?
>>
>>         An interval timer, i.e. a timer created by evaluating any of 
>> the  func-
>>        tions apply_interval/4, send_interval/3, and send_interval/2, 
>> is linked
>>        to the process towards which the timer performs its task.
>>
>> i interpreted it to mean that the process that called 
>> timer:apply_interval will be linked to the (temporary) process doing 
>> the  module:function() supplied as argument to apply_interval/4.
>> this is not the case, so what does it really mean?
>> who is linked, and to whom?
>>
>
> The caller of timer:apply_interval is linked to the timer_server 
> process - when the caller exits, the timer is deleted.
>
> If you pass the pid of the caller to the function, it could be 
> notified. Something like this:
>
>
> -module(foo).
> -export([main/0, tick/3]).
>
> action(Arg) -> whatever.
>
> tick(Parent, Ref, Arg) ->
> 	try action(Arg)
> 	catch
> 		exit:Reason -> Parent ! {Ref, Reason}
> 	end.
>
> main() ->
> 	Ref = make_ref(),
> 	timer:apply_interval(100, foo, tick, [self(), Ref, Arg]),
> 	receive
> 		{Ref, Reason} -> whatever
> 	end.
>
>
> On the other hand, if you're that concerned about the execution of the 
> function, you might want to rethink  the use of apply_interval.
>
> Mark.
>
>>
>> bengt, who has included a little test module to play with when 
>> investigating this problem.
>>
>>
>> -module(interval).
>> -export([main/1, crashing/0]).
>>
>>
>> main(_) ->
>> 	timer:apply_interval(1000,  interval,  crashing,  []),
>> 	loop(0),
>> 	init:stop().
>>
>> crashing() ->
>> 	io:fwrite("~w~n", [erlang:self()]),
>> 	erlang:exit(crashing).
>>
>> loop(N) ->
>> 	receive
>> 	Something ->
>> 		io:fwrite("~w~n", [Something])
>> 	after 500 ->
>> 		io:fwrite("~w~n", [N])
>> 	end,
>> 	loop(N+1).
>>
>




More information about the erlang-questions mailing list