How to perform actions periodically with Erlang's gen_server?

前端 未结 4 802
伪装坚强ぢ
伪装坚强ぢ 2020-12-23 20:32

I want to start a gen_server that additionally, will perform one action every minute.

What is the best way to schedule that?

4条回答
  •  臣服心动
    2020-12-23 21:01

    To precisely control the timer, you may want to use erlang:start_timer, and save each timer reference you have created.

    erlang:start_timer has a tiny difference with erlang:send_after, see http://www.erlang.org/doc/man/erlang.html#start_timer-3 and http://www.erlang.org/doc/man/erlang.html#send_after-3

    Example use case:

    init(Args) ->
        ...
        TRef = erlang:start_timer(?INTERVAL, self(), trigger),
        State = #state{tref = TRef},
        ...
    
    handle_info({timeout, _Ref, trigger}, State) ->
        %% With this cancel call we are able to manually send the 'trigger' message 
        %% to re-align the timer, and prevent accidentally setting duplicate timers
        erlang:cancel(State#state.tref),
        ...
        TRef = erlang:start_timer(?INTERVAL, self(), trigger),
        NewState = State#state{tref = TRef},
        ...
    
    handle_cast(stop_timer, State) ->
        TRef = State#state.tref,
        erlang:cancel(TRef),
    
        %% Remove the timeout message that may have been put in our queue just before 
        %% the call to erlang:cancel, so that no timeout message would ever get 
        %% handled after the 'stop_timer' message
        receive
            {timeout, TRef, _} -> void
            after 0 -> void
        end,
        ...
    

提交回复
热议问题