gen_fsm:send_after | start_timer

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

gen_fsm:send_after | start_timer

Sean Hinde-2
> sysTimer:apply_after/4 does this:
>
> apply_after(Time, M, F, A) when integer(Time) ->
>     spawn_link(sysTimer, do_apply_after,
>                [Time, M, F, A, self()]);
> apply_after(Name, M, F, A) ->
>     spawn_link(sysTimer, do_apply_after,
>                [get_value(Name), M, F, A, self()]).
>
> do_apply_after(Time, M, F, A, LinkedPid) ->
>     put(arguments, [Time, M, F, A, LinkedPid]),
>     sleep(Time),
>     apply(M, F, A),
>     unlink(LinkedPid).
>
>

> and this version of apply_after/4 also supports named timers,
> which is very useful for protocol programming, as the standard
> timers must often be customizable.

This sounds like a nice feature. I just implemented a bunch of callbacks to
be able to change the timer values in my protocol module..

> I will not present sleep(), because I just found that it has been
> inefficiently (re-)implemented since the last time I looked.  ):
> Its efficient implementation is trivial.

In the latest stdlib I have access to (1.9.4) it is:

sleep(T) ->      
    receive      
    after T -> ok
    end.

This looks reasonably trivial :)

> The method of timer.erl to use a sorted list in order to offload
> the timer wheel in the emulator is a sub-optimization. We've
> verified that the timer wheel (timeout queue) in BEAM shows
> hardly no degradation at all even with 20,000 concurrent timers.

Nice to know.

> An erlang implementation simply cannot compete with the built-in
> timeout support, and apply_after should basically only do the
> required extra of spawning a process to give the function an
> execution context. Everything else is just garnish.

What about the performance difference between your apply_after and
erlang:start_timer?

Do you know if receive loops use the same timer wheel?

How about:

apply_after(T, M, F, A) ->
        erlang:start_timer(T, timer, {apply, M, F, A}).

%% Permanent loop registered as {local, timer}:

loop() ->
    receive
        {timeout, Ref, {apply, M, F, A}} ->
            spawn_link(?MODULE, do, [M, F, A, self()]),
            loop().

do(M, F, A, Pid) ->
        apply(M, F, A).
        unlink(Pid).

This avoids having lots of extra processes lying around (but the timer isn't
linked to the requesting process).

- Sean



NOTICE AND DISCLAIMER:
This email (including attachments) is confidential.  If you have received
this email in error please notify the sender immediately and delete this
email from your system without copying or disseminating it or placing any
reliance upon its contents.  We cannot accept liability for any breaches of
confidence arising through use of email.  Any opinions expressed in this
email (including attachments) are those of the author and do not necessarily
reflect our opinions.  We will not accept responsibility for any commitments
made by our employees outside the scope of our business.  We do not warrant
the accuracy or completeness of such information.



Reply | Threaded
Open this post in threaded view
|

Supervisor Strategy

Martin Carlson-2
Hello, I have a project under development that consists of 2 supervisors and 4
supervised processes.

                        S
                  /     /   \
                 W  W   \
                                S
                               /   \
                             W   W

This is my current supervision tree.  I have one more process in this scheme,
it is an extremly temporary process. Thousands of them can be spawned and
killed in an hour.  The process is spawned in response to a packet recieved by
one of the workers.  My question to the list is this; is it proper form to
spawn the process via the worker directly with a spawn( I really don't care
about it after I spawn it so I would not be inclined to use a link) or should I
use the supervisors ability to dynamically spawn children with
supervisor:start_child?  What is more efficiant/robust/proper?

                                                        Thanks,
                                                        Martin Logan





Reply | Threaded
Open this post in threaded view
|

gen_fsm:send_after | start_timer

Ulf Wiger-4
In reply to this post by Sean Hinde-2
On Tue, 10 Jul 2001, Sean Hinde wrote:

>> An erlang implementation simply cannot compete with the built-in
>> timeout support, and apply_after should basically only do the
>> required extra of spawning a process to give the function an
>> execution context. Everything else is just garnish.
>
>What about the performance difference between your apply_after and
>erlang:start_timer?

It's somewhere in the neighbourhood of 5x more overhead:
erlang:start_timer/3 clocks in at about 20-25 us. Spawning a
process costs a bit more. Our apply_after was less than 100 us
overhead last time I checked (which was a while ago on a
36MHz SuperSPARC.)

>Do you know if receive loops use the same timer wheel?

Yes, they do.


>How about:
>
>apply_after(T, M, F, A) ->
> erlang:start_timer(T, timer, {apply, M, F, A}).
>
>%% Permanent loop registered as {local, timer}:
>
>loop() ->
>    receive
>        {timeout, Ref, {apply, M, F, A}} ->
>            spawn_link(?MODULE, do, [M, F, A, self()]),
>            loop().
>
>do(M, F, A, Pid) ->
> apply(M, F, A).
> unlink(Pid).

You will reduce the overhead, but add latency since all the
timer functions must be serialized. This will force the
requirement on the user of the timer to keep the function very
short, which is sometimes inconvenient.

Also, I'd put a catch around the apply. ;)


>This avoids having lots of extra processes lying around (but the timer isn't
>linked to the requesting process).

Yes, but Erlang handles lots of extra processes exceedingly well.
I wouldn't worry about the performance aspect, but memory could
sometimes be a factor.

/Uffe
--
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB