How to perform actions periodically with Erlang’s gen_server?

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.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)