Timer implementation models

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Timer implementation models

Chaitanya Chalasani-4
Hi,

I have hundred’s of processes each running its own timers.
I can think of the following models. Wanted to know the pros and cons of each model.

** Model 1 **
loop1(State) ->
  receive
  after 1000 ->
      do_someting()
  end.

** Model 2 **
loop2(State) ->
  erlang:send_after(1000, self(), timeout),
  receive
    timeout ->
      do_someting(),
      erlang:send_after(1000, self(), timeout)
  end.

** Model 3 **
loop3(State) ->
  timer:send_interval(1000, self(), timeout),
  loop3a(State).

loop3a(State) ->
  receive
    timeout ->
      do_someting()
  end.

The above three models using the gen_server -

** Model 1 **
init(_Args) ->
  {ok, State, 1000}.

handle_info(timeout, State) ->
  do_someting(),
  {noreply, State, 1000}

** Model 2 **
init(_Args) ->
  erlang:send_after(1000, self(), timeout),
  {ok, State}.

handle_info(timeout, State) ->
  do_someting(),
  erlang:send_after(1000, self(), timeout),
  {noreply, State}

** Model 3 **
init(_Args) ->
  timer:send_interval(1000, self(), timeout),
  {ok, State}.

handle_info(timeout, State) ->
  do_someting(),
  {noreply, State}

/Chaitanya
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Timer implementation models

Nathaniel Waisbrot
Well for one, send_after/3 and send_interval/3 will produce slightly different timing.

Suppose your do_something/0 takes 50ms to run. Then in "Model 2", ignoring any complexities of scheduling, your function will be invoked at

t+1000, t+2050, t+3100, t+4150, t+5200, t+6250, ...

While "Model 3", under the same simplifying assumption would be invoked at

t+1000, t+2000, t+3000, t+4000, t+5000, t+6000, ...


To give you a few more choices:

- When using gen_server, I prefer to call timer:apply_after/4 and timer:apply_interval/4. I either have them call gen_server:cast/2 or a local function that calls cast.
- When using gen_server, you can give a timeout in your callback response. This works quite differently from the timer module, but might be useful for some things
- When using gen_statem, you can give a timeouts like gen_server, but a wider variety of behavior is available



> On Oct 30, 2017, at 6:35 PM, Chaitanya Chalasani <[hidden email]> wrote:
>
> Hi,
>
> I have hundred’s of processes each running its own timers.
> I can think of the following models. Wanted to know the pros and cons of each model.
>
> ** Model 1 **
> loop1(State) ->
>  receive
>  after 1000 ->
>      do_someting()
>  end.
>
> ** Model 2 **
> loop2(State) ->
>  erlang:send_after(1000, self(), timeout),
>  receive
>    timeout ->
>      do_someting(),
>      erlang:send_after(1000, self(), timeout)
>  end.
>
> ** Model 3 **
> loop3(State) ->
>  timer:send_interval(1000, self(), timeout),
>  loop3a(State).
>
> loop3a(State) ->
>  receive
>    timeout ->
>      do_someting()
>  end.
>
> The above three models using the gen_server -
>
> ** Model 1 **
> init(_Args) ->
>  {ok, State, 1000}.
>
> handle_info(timeout, State) ->
>  do_someting(),
>  {noreply, State, 1000}
>
> ** Model 2 **
> init(_Args) ->
>  erlang:send_after(1000, self(), timeout),
>  {ok, State}.
>
> handle_info(timeout, State) ->
>  do_someting(),
>  erlang:send_after(1000, self(), timeout),
>  {noreply, State}
>
> ** Model 3 **
> init(_Args) ->
>  timer:send_interval(1000, self(), timeout),
>  {ok, State}.
>
> handle_info(timeout, State) ->
>  do_someting(),
>  {noreply, State}
>
> /Chaitanya
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Timer implementation models

Chaitanya Chalasani-4
Thank you Nathaniel, understood about the precision.

If precision isn’t my criteria and considering 100s to 1000s of timers running concurrently, is there any advantage for the model 2 over model 3.

> On 31-Oct-2017, at 4:46 AM, Nathaniel Waisbrot <[hidden email]> wrote:
>
> Well for one, send_after/3 and send_interval/3 will produce slightly different timing.
>
> Suppose your do_something/0 takes 50ms to run. Then in "Model 2", ignoring any complexities of scheduling, your function will be invoked at
>
> t+1000, t+2050, t+3100, t+4150, t+5200, t+6250, ...
>
> While "Model 3", under the same simplifying assumption would be invoked at
>
> t+1000, t+2000, t+3000, t+4000, t+5000, t+6000, ...
>
>
> To give you a few more choices:
>
> - When using gen_server, I prefer to call timer:apply_after/4 and timer:apply_interval/4. I either have them call gen_server:cast/2 or a local function that calls cast.
> - When using gen_server, you can give a timeout in your callback response. This works quite differently from the timer module, but might be useful for some things
> - When using gen_statem, you can give a timeouts like gen_server, but a wider variety of behavior is available
>
>
>
>> On Oct 30, 2017, at 6:35 PM, Chaitanya Chalasani <[hidden email]> wrote:
>>
>> Hi,
>>
>> I have hundred’s of processes each running its own timers.
>> I can think of the following models. Wanted to know the pros and cons of each model.
>>
>> ** Model 1 **
>> loop1(State) ->
>> receive
>> after 1000 ->
>>     do_someting()
>> end.
>>
>> ** Model 2 **
>> loop2(State) ->
>> erlang:send_after(1000, self(), timeout),
>> receive
>>   timeout ->
>>     do_someting(),
>>     erlang:send_after(1000, self(), timeout)
>> end.
>>
>> ** Model 3 **
>> loop3(State) ->
>> timer:send_interval(1000, self(), timeout),
>> loop3a(State).
>>
>> loop3a(State) ->
>> receive
>>   timeout ->
>>     do_someting()
>> end.
>>
>> The above three models using the gen_server -
>>
>> ** Model 1 **
>> init(_Args) ->
>> {ok, State, 1000}.
>>
>> handle_info(timeout, State) ->
>> do_someting(),
>> {noreply, State, 1000}
>>
>> ** Model 2 **
>> init(_Args) ->
>> erlang:send_after(1000, self(), timeout),
>> {ok, State}.
>>
>> handle_info(timeout, State) ->
>> do_someting(),
>> erlang:send_after(1000, self(), timeout),
>> {noreply, State}
>>
>> ** Model 3 **
>> init(_Args) ->
>> timer:send_interval(1000, self(), timeout),
>> {ok, State}.
>>
>> handle_info(timeout, State) ->
>> do_someting(),
>> {noreply, State}
>>
>> /Chaitanya
>> _______________________________________________
>> erlang-questions mailing list
>> [hidden email]
>> http://erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Timer implementation models

Jesper Louis Andersen-2
The timer module is often a performance problem, so avoiding that is a good idea (It's in the efficiency guide as well).

Gen server variants:

Model 1 will reset the timer if an event arrives. This means the timer will never trigger if events arrive before 1000ms each time (it'll starve the timeout message forever).

Model 2, seems a bit better to me.

Raw variants:

All models look fine to me.



On Tue, Oct 31, 2017 at 11:55 AM Chaitanya Chalasani <[hidden email]> wrote:
Thank you Nathaniel, understood about the precision.

If precision isn’t my criteria and considering 100s to 1000s of timers running concurrently, is there any advantage for the model 2 over model 3.

> On 31-Oct-2017, at 4:46 AM, Nathaniel Waisbrot <[hidden email]> wrote:
>
> Well for one, send_after/3 and send_interval/3 will produce slightly different timing.
>
> Suppose your do_something/0 takes 50ms to run. Then in "Model 2", ignoring any complexities of scheduling, your function will be invoked at
>
> t+1000, t+2050, t+3100, t+4150, t+5200, t+6250, ...
>
> While "Model 3", under the same simplifying assumption would be invoked at
>
> t+1000, t+2000, t+3000, t+4000, t+5000, t+6000, ...
>
>
> To give you a few more choices:
>
> - When using gen_server, I prefer to call timer:apply_after/4 and timer:apply_interval/4. I either have them call gen_server:cast/2 or a local function that calls cast.
> - When using gen_server, you can give a timeout in your callback response. This works quite differently from the timer module, but might be useful for some things
> - When using gen_statem, you can give a timeouts like gen_server, but a wider variety of behavior is available
>
>
>
>> On Oct 30, 2017, at 6:35 PM, Chaitanya Chalasani <[hidden email]> wrote:
>>
>> Hi,
>>
>> I have hundred’s of processes each running its own timers.
>> I can think of the following models. Wanted to know the pros and cons of each model.
>>
>> ** Model 1 **
>> loop1(State) ->
>> receive
>> after 1000 ->
>>     do_someting()
>> end.
>>
>> ** Model 2 **
>> loop2(State) ->
>> erlang:send_after(1000, self(), timeout),
>> receive
>>   timeout ->
>>     do_someting(),
>>     erlang:send_after(1000, self(), timeout)
>> end.
>>
>> ** Model 3 **
>> loop3(State) ->
>> timer:send_interval(1000, self(), timeout),
>> loop3a(State).
>>
>> loop3a(State) ->
>> receive
>>   timeout ->
>>     do_someting()
>> end.
>>
>> The above three models using the gen_server -
>>
>> ** Model 1 **
>> init(_Args) ->
>> {ok, State, 1000}.
>>
>> handle_info(timeout, State) ->
>> do_someting(),
>> {noreply, State, 1000}
>>
>> ** Model 2 **
>> init(_Args) ->
>> erlang:send_after(1000, self(), timeout),
>> {ok, State}.
>>
>> handle_info(timeout, State) ->
>> do_someting(),
>> erlang:send_after(1000, self(), timeout),
>> {noreply, State}
>>
>> ** Model 3 **
>> init(_Args) ->
>> timer:send_interval(1000, self(), timeout),
>> {ok, State}.
>>
>> handle_info(timeout, State) ->
>> do_someting(),
>> {noreply, State}
>>
>> /Chaitanya
>> _______________________________________________
>> erlang-questions mailing list
>> [hidden email]
>> http://erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions