[erlang-questions] erlang:restart_timer

Tony Rogvall <>
Wed Nov 5 14:50:22 CET 2014


Hi!

From time to time I implement protocols and services that need watch dogs and/or retransmit timers.
I will normally implement this using a BIF timer:

	WdtTimer = erlang:start_timer(Time, self(), wdt)

This will send a message {timeout,WdtTimer, wdt} after Time milliseconds. 
When using a watchdog the code will normally try to avoid that the wdt is ever sent. 
The idea is that if you get the wdt message you are to late and need to crash / restart or something.
So after som executing some "watched" code you want to re-arm the watch dog (feed it)
This is normally done by:

	erlang:cancel_timer(WdtTimer),
	NewWdtTimer = erlang:start_timer(Time, self(), wdt)

If you match the {timeout,WdtTimer,wdt} message and ignore {timeout,OldWdtTimer,wdt} messages,
you could skip the cancel_timer. But that will generate plenty of waste.

Protocols using retransmit timeouts also use a scheme like the above.

I propose a new BIF:

	erlang:restart_timer(Ref, Time) -> false | RemainingTime

This will restart a time if it is active and return the time that remained when it was restarted.
If restart_timer return false either the timer has already time out or the reference is not a timer.

The benefit is a speedup with at least 2.5 times. comparing:

	erlang:restart_timer(Ref, Time)
vs
	erlang:cancel_timer(Ref)
	Ref1 = erlang:start_timer(Time, self(), Message)

The cost saving is that restart_timer preserve already stored messages. And also internal timer structures are
preserved. Resulting in less overhead. 

The interface is simple and do not require a new reference every restart, this could also save the time
and heap updating a server state.

I have an implementation that perform well, and could probably be optimized even further.

What about it?  I'd like to hear from people actually implementing protocols, not only from the "normal" responders.


/Tony




More information about the erlang-questions mailing list