I want to start a gen_server that additionally, will perform one action every minute.
What is the best way to schedule that?
You have two easy alternatives, use timer:send_interval/2
or erlang:send_after/3
. send_interval
is easier to setup, while send_after
(when used in the Erlang module) is more reliable since it is a built-in function, see the Efficiency Guide.
Using send_after
also ensures that the gen_server
process is not overloaded. If you were using the send_interval
function you would get a message regardless if the process can keep up or not. With send_after
being called just before the return in handle_info
you only schedule a new message once you handled the previous one. If you want more accurate time tracking you can still schedule a send_after
with the time set dynamically to something lower than ?INTERVAL
(or even 0) to catch up.
I would recommend something along the following lines in your gen_server
:
-define(INTERVAL, 60000). % One minute
init(Args) ->
... % Start first timer
erlang:send_after(?INTERVAL, self(), trigger),
...
handle_info(trigger, State) ->
... % Do the action
... % Start new timer
erlang:send_after(?INTERVAL, self(), trigger),
...
Instead of trigger
you could send something with a state if it is needed, like {trigger, Count}
or something.