Serge Aleynikov | 18 Aug 21:56

max timeout

I recall this question being asked on the mailing list before, but I 
can't seem to find that thread.

What's the MaxAllowedTimeout that can be specified in the after clause?

receive
after MaxAllowedTimeout ->
     ok
end.

It would be nice if the section 6.10 of the reference manual would 
include this info.

Thanks.

Serge
Ulf Wiger | 18 Aug 23:18

Re: max timeout

It does:

"receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
after
    ExprT ->
        BodyT
end

"ExprT should evaluate to an integer. The highest allowed value is
16#ffffffff, that is, the value must fit in 32 bits."

BR,
Ulf W

2008/8/18 Serge Aleynikov <saleyn <at> gmail.com>:
> I recall this question being asked on the mailing list before, but I
> can't seem to find that thread.
>
> What's the MaxAllowedTimeout that can be specified in the after clause?
>
> receive
> after MaxAllowedTimeout ->
>     ok
> end.
>
(Continue reading)

Serge Aleynikov | 19 Aug 00:12

Re: max timeout

For some reason I have a vague recollection (that may very well be 
wrong) that when this subject was discussed on the list before the 
actual timeout number was less then 2^32...  I have a case when I need 
to put a process to sleep for up to a couple of days (e.g. not to run on 
a weekend) - in practice I am doing a loop sleep with a smaller timeout 
to compensate for time drifts and clock adjustments, but nevertheless 
this question came up about a practical upper bound.

Serge

Ulf Wiger wrote:
> It does:
> 
> "receive
>     Pattern1 [when GuardSeq1] ->
>         Body1;
>     ...;
>     PatternN [when GuardSeqN] ->
>         BodyN
> after
>     ExprT ->
>         BodyT
> end
> 
> "ExprT should evaluate to an integer. The highest allowed value is
> 16#ffffffff, that is, the value must fit in 32 bits."
> 
> BR,
> Ulf W
> 
(Continue reading)

Matthias Lang | 19 Aug 09:42
Favicon

Re: max timeout

On Monday, August 18, Serge Aleynikov wrote:

> For some reason I have a vague recollection (that may very well be 
> wrong) that when this subject was discussed on the list before the 
> actual timeout number was less then 2^32...  I have a case when I need 
> to put a process to sleep for up to a couple of days (e.g. not to run on 
> a weekend) - in practice I am doing a loop sleep with a smaller timeout 
> to compensate for time drifts and clock adjustments, but nevertheless 
> this question came up about a practical upper bound.

This may be the thread you remember, it starts here:

  http://www.erlang.org/pipermail/erlang-questions/2008-February/032609.html

Executive summary: In R11B-2, a timeout of 16#ffffFFFF doesn't work as
    expected on a 32-bit machine. Something changed between R11B-2 and
    R11B-5 which made it work in the shell, but still not in compiled
    code. I haven't noticed anything in the release notes saying it's
    been fixed for real.

Matt
Serge Aleynikov | 19 Aug 13:39

Re: max timeout

Matt, thanks, that was the thread!  And this was Ulf's statement that 
seemed to have settled in my memory:

"...you cannot use timeout values that are larger than a smallint."
http://www.erlang.org/pipermail/erlang-questions/2008-February/032625.html

So from that thread and your "executive summary" below, it's still not 
clear which one is the upper limit for the timeout:

1. 2^32 (this is what's documented, but only seems to work in the shell)
2. 2^32-1 = 49.5 days
3. Erlang's small integers (2^27-1 = 1.5 days)

I still claim that the reference manual documentation ch. 6.10 is not 
accurate and leaves room for questions.

Serge

Matthias Lang wrote:
> On Monday, August 18, Serge Aleynikov wrote:
> 
>> For some reason I have a vague recollection (that may very well be 
>> wrong) that when this subject was discussed on the list before the 
>> actual timeout number was less then 2^32...  I have a case when I need 
>> to put a process to sleep for up to a couple of days (e.g. not to run on 
>> a weekend) - in practice I am doing a loop sleep with a smaller timeout 
>> to compensate for time drifts and clock adjustments, but nevertheless 
>> this question came up about a practical upper bound.
> 
> This may be the thread you remember, it starts here:
(Continue reading)

Alpár Jüttner | 20 Aug 07:26

Re: max timeout

Hi,

As I recall, someone noted on that thread that timer:sleep() works well
for arbitrarily large numbers.

Now I looked at the source and found that this is _not_ true. Strangely
enough, all the functions of the timer modules seem to work correctly
with large numbers _except_ timer:sleep() which has a definition as
simple as this:

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

It might be worth fixing.

> 1. 2^32 (this is what's documented, but only seems to work in the shell)
> 2. 2^32-1 = 49.5 days
> 3. Erlang's small integers (2^27-1 = 1.5 days)

4. timer.erl says this:
-define(MAX_TIMEOUT, 16#0800000).

Best regards,
Alpar

Serge Aleynikov | 20 Aug 12:33

Re: max timeout

Alpár Jüttner wrote:
> Hi,
> 
> As I recall, someone noted on that thread that timer:sleep() works well
> for arbitrarily large numbers.
> 
> Now I looked at the source and found that this is _not_ true. Strangely
> enough, all the functions of the timer modules seem to work correctly
> with large numbers _except_ timer:sleep() which has a definition as
> simple as this:
> 
> sleep(T) ->
>     receive
>     after T -> ok
>     end.

This is the reason why in this thread I was questioning the max timeout 
of the receive statement as opposed to timer:sleep/1 implemented in 
bytecode. ;-)

> It might be worth fixing.
> 
>> 1. 2^32 (this is what's documented, but only seems to work in the shell)
>> 2. 2^32-1 = 49.5 days
>> 3. Erlang's small integers (2^27-1 = 1.5 days)
> 
> 4. timer.erl says this:
> -define(MAX_TIMEOUT, 16#0800000).

Though, if you look at the use of this define in timer.erl, it's there 
(Continue reading)

Per Hedeland | 22 Aug 00:11

Re: [erlang-questions] max timeout

Alpár Jüttner <alpar <at> cs.elte.hu> wrote:
>
>As I recall, someone noted on that thread that timer:sleep() works well
>for arbitrarily large numbers.

I thought that might have been me:-( - but I see now that I just said
"the timer module" and gave an example using timer:send_after/2, so I
was almost right...

>Now I looked at the source and found that this is _not_ true. Strangely
>enough, all the functions of the timer modules seem to work correctly
>with large numbers _except_ timer:sleep() which has a definition as
>simple as this:
>
>sleep(T) ->
>    receive
>    after T -> ok
>    end.

Ouch. But no-one will ever need to sleep for 50 days or more, right?:-)

>It might be worth fixing.

And I guess I half-owe the fix - the problem is (as I discovered...)
that there may be (is) code, um, "out there", that relies on being able
to use timer:sleep/1 without having the timer_server running *or*
getting "auto-started". Below is what I believe to be a backwards-
compatible fix (against R12B-3), but it's pretty ugly - would probably
be better to e.g.  define a new function long_sleep/1 or somesuch for
the "unlimited" case.
(Continue reading)

Hynek Vychodil | 22 Aug 10:06
Gravatar

Re: max timeout

It should be much more simpler to do it without modify timer_server:

sleep(Time) ->
    case whereis(timer_server) of
       undefined -> receive after Time -> ok end;
       _ ->
          Ref = make_ref(),
          send_after(Time, Ref),
          receive Ref -> ok end
    end.

On Fri, Aug 22, 2008 at 12:11 AM, Per Hedeland <per <at> hedeland.org> wrote:
Alpár Jüttner <alpar <at> cs.elte.hu> wrote:
>
>As I recall, someone noted on that thread that timer:sleep() works well
>for arbitrarily large numbers.

I thought that might have been me:-( - but I see now that I just said
"the timer module" and gave an example using timer:send_after/2, so I
was almost right...

>Now I looked at the source and found that this is _not_ true. Strangely
>enough, all the functions of the timer modules seem to work correctly
>with large numbers _except_ timer:sleep() which has a definition as
>simple as this:
>
>sleep(T) ->
>    receive
>    after T -> ok
>    end.

Ouch. But no-one will ever need to sleep for 50 days or more, right?:-)

>It might be worth fixing.

And I guess I half-owe the fix - the problem is (as I discovered...)
that there may be (is) code, um, "out there", that relies on being able
to use timer:sleep/1 without having the timer_server running *or*
getting "auto-started". Below is what I believe to be a backwards-
compatible fix (against R12B-3), but it's pretty ugly - would probably
be better to e.g.  define a new function long_sleep/1 or somesuch for
the "unlimited" case.

--Per Hedeland

--- lib/stdlib/src/timer.erl.orig       2007-11-26 19:55:44.000000000 +0100
+++ lib/stdlib/src/timer.erl    2008-08-21 23:00:45.000000000 +0200
<at> <at> -75,9 +75,14 <at> <at>
 cancel(BRef) ->
    req(cancel, BRef).

-sleep(T) ->
-    receive
-    after T -> ok
+sleep(Time) ->
+    case whereis(timer_server) of
+       undefined ->
+           receive
+           after Time -> ok
+           end;
+       _ ->
+           req(sleep, Time)
    end.

 %%
<at> <at> -176,6 +181,13 <at> <at>
           {reply, {error, badarg}, [], next_timeout()}
    end;

+handle_call({sleep, Time, Started}, From, Ts) ->
+    Req = {apply_after, {Time, {gen_server, reply, [From, ok]}}, Started},
+    case handle_call(Req, From, Ts) of
+        {reply, {ok, _}, _, Timeout} -> {noreply, [], Timeout};
+        Reply                        -> Reply
+    end;
+
 handle_call({cancel, BRef = {_Time, Ref}, _}, _From, Ts)
                                           when is_reference(Ref) ->
    delete_ref(BRef),
_______________________________________________
erlang-questions mailing list
erlang-questions <at> erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions



--
--Hynek (Pichi) Vychodil
<div><div dir="ltr">It should be much more simpler to do it without modify timer_server:<br><br>sleep(Time) -&gt;<br>
&nbsp;&nbsp;&nbsp; case whereis(timer_server) of<br>
&nbsp;&nbsp; &nbsp; &nbsp; undefined -&gt; receive after Time -&gt; ok end;<br>
&nbsp;&nbsp; &nbsp; &nbsp; _ -&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ref = make_ref(),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; send_after(Time, Ref),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receive Ref -&gt; ok end<br>&nbsp;&nbsp;&nbsp; end.<br><br><div class="gmail_quote">On Fri, Aug 22, 2008 at 12:11 AM, Per Hedeland <span dir="ltr">&lt;<a href="mailto:per <at> hedeland.org">per <at> hedeland.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote">
<div class="Ih2E3d">Alp&aacute;r J&uuml;ttner &lt;<a href="mailto:alpar <at> cs.elte.hu">alpar <at> cs.elte.hu</a>&gt; wrote:<br>

&gt;<br>
&gt;As I recall, someone noted on that thread that timer:sleep() works well<br>
&gt;for arbitrarily large numbers.<br><br>
</div>I thought that might have been me:-( - but I see now that I just said<br>
"the timer module" and gave an example using timer:send_after/2, so I<br>
was almost right...<br><div class="Ih2E3d">
<br>
&gt;Now I looked at the source and found that this is _not_ true. Strangely<br>
&gt;enough, all the functions of the timer modules seem to work correctly<br>
&gt;with large numbers _except_ timer:sleep() which has a definition as<br>
&gt;simple as this:<br>
&gt;<br>
&gt;sleep(T) -&gt;<br>
&gt; &nbsp; &nbsp;receive<br>
&gt; &nbsp; &nbsp;after T -&gt; ok<br>
&gt; &nbsp; &nbsp;end.<br><br>
</div>Ouch. But no-one will ever need to sleep for 50 days or more, right?:-)<br><div class="Ih2E3d">
<br>
&gt;It might be worth fixing.<br><br>
</div>And I guess I half-owe the fix - the problem is (as I discovered...)<br>
that there may be (is) code, um, "out there", that relies on being able<br>
to use timer:sleep/1 without having the timer_server running *or*≤br>
getting "auto-started". Below is what I believe to be a backwards-<br>
compatible fix (against R12B-3), but it's pretty ugly - would probably<br>
be better to e.g. &nbsp;define a new function long_sleep/1 or somesuch for<br>
the "unlimited" case.<br><br>
--Per Hedeland<br><br>
--- lib/stdlib/src/timer.erl.orig &nbsp; &nbsp; &nbsp; 2007-11-26 19:55:44.000000000 +0100<br>
+++ lib/stdlib/src/timer.erl &nbsp; &nbsp;2008-08-21 23:00:45.000000000 +0200<br>
 <at>  <at>  -75,9 +75,14  <at>  <at> <br>
&nbsp;cancel(BRef) -&gt;<br>
 &nbsp; &nbsp; req(cancel, BRef).<br><br>
-sleep(T) -&gt;<br>
- &nbsp; &nbsp;receive<br>
- &nbsp; &nbsp;after T -&gt; ok<br>
+sleep(Time) -&gt;<br>
+ &nbsp; &nbsp;case whereis(timer_server) of<br>
+ &nbsp; &nbsp; &nbsp; undefined -&gt;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; receive<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; after Time -&gt; ok<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>
+ &nbsp; &nbsp; &nbsp; _ -&gt;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req(sleep, Time)<br>
 &nbsp; &nbsp; end.<br><br>
&nbsp;%%<br>
 <at>  <at>  -176,6 +181,13  <at>  <at> <br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{reply, {error, badarg}, [], next_timeout()}<br>
 &nbsp; &nbsp; end;<br><br>
+handle_call({sleep, Time, Started}, From, Ts) -&gt;<br>
+ &nbsp; &nbsp;Req = {apply_after, {Time, {gen_server, reply, [From, ok]}}, Started},<br>
+ &nbsp; &nbsp;case handle_call(Req, From, Ts) of<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;{reply, {ok, _}, _, Timeout} -&gt; {noreply, [], Timeout};<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;Reply &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt; Reply<br>
+ &nbsp; &nbsp;end;<br>
+<br>
&nbsp;handle_call({cancel, BRef = {_Time, Ref}, _}, _From, Ts)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;when is_reference(Ref) -&gt;<br>
 &nbsp; &nbsp; delete_ref(BRef),<br><div>
<div></div>
<div class="Wj3C7c">_______________________________________________<br>
erlang-questions mailing list<br><a href="mailto:erlang-questions <at> erlang.org">erlang-questions <at> erlang.org</a><br><a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
</div>
</div>
</blockquote>
</div>
<br><br clear="all"><br>-- <br>--Hynek (Pichi) Vychodil<br>
</div></div>
Hynek Vychodil | 22 Aug 10:19
Gravatar

Re: max timeout

Sorry, I haven't done it reliable and as recommended by best practices :-)

fixed:

sleep(Time) ->
    case whereis(timer_server) of
       undefined -> receive after Time -> ok end;
       _ ->
          Ref = make_ref(),
          {ok, _} = send_after(Time, Ref),
          receive Ref -> ok end
    end.


On Fri, Aug 22, 2008 at 10:06 AM, Hynek Vychodil <vychodil.hynek <at> gmail.com> wrote:
It should be much more simpler to do it without modify timer_server:


sleep(Time) ->
    case whereis(timer_server) of
       undefined -> receive after Time -> ok end;
       _ ->
          Ref = make_ref(),
          send_after(Time, Ref),
          receive Ref -> ok end
    end.


On Fri, Aug 22, 2008 at 12:11 AM, Per Hedeland <per <at> hedeland.org> wrote:
Alpár Jüttner <alpar <at> cs.elte.hu> wrote:
>
>As I recall, someone noted on that thread that timer:sleep() works well
>for arbitrarily large numbers.

I thought that might have been me:-( - but I see now that I just said
"the timer module" and gave an example using timer:send_after/2, so I
was almost right...

>Now I looked at the source and found that this is _not_ true. Strangely
>enough, all the functions of the timer modules seem to work correctly
>with large numbers _except_ timer:sleep() which has a definition as
>simple as this:
>
>sleep(T) ->
>    receive
>    after T -> ok
>    end.

Ouch. But no-one will ever need to sleep for 50 days or more, right?:-)

>It might be worth fixing.

And I guess I half-owe the fix - the problem is (as I discovered...)
that there may be (is) code, um, "out there", that relies on being able
to use timer:sleep/1 without having the timer_server running *or*
getting "auto-started". Below is what I believe to be a backwards-
compatible fix (against R12B-3), but it's pretty ugly - would probably
be better to e.g.  define a new function long_sleep/1 or somesuch for
the "unlimited" case.

--Per Hedeland

--- lib/stdlib/src/timer.erl.orig       2007-11-26 19:55:44.000000000 +0100
+++ lib/stdlib/src/timer.erl    2008-08-21 23:00:45.000000000 +0200
<at> <at> -75,9 +75,14 <at> <at>
 cancel(BRef) ->
    req(cancel, BRef).

-sleep(T) ->
-    receive
-    after T -> ok
+sleep(Time) ->
+    case whereis(timer_server) of
+       undefined ->
+           receive
+           after Time -> ok
+           end;
+       _ ->
+           req(sleep, Time)
    end.

 %%
<at> <at> -176,6 +181,13 <at> <at>
           {reply, {error, badarg}, [], next_timeout()}
    end;

+handle_call({sleep, Time, Started}, From, Ts) ->
+    Req = {apply_after, {Time, {gen_server, reply, [From, ok]}}, Started},
+    case handle_call(Req, From, Ts) of
+        {reply, {ok, _}, _, Timeout} -> {noreply, [], Timeout};
+        Reply                        -> Reply
+    end;
+
 handle_call({cancel, BRef = {_Time, Ref}, _}, _From, Ts)
                                           when is_reference(Ref) ->
    delete_ref(BRef),
_______________________________________________
erlang-questions mailing list
erlang-questions <at> erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions



--
--Hynek (Pichi) Vychodil



--
--Hynek (Pichi) Vychodil
<div><div dir="ltr">Sorry, I haven't done it reliable and as recommended by best practices :-)<br><br>fixed:<br><br>sleep(Time) -&gt;<br>
&nbsp;&nbsp;&nbsp; case whereis(timer_server) of<br>
&nbsp;&nbsp; &nbsp; &nbsp; undefined -&gt; receive after Time -&gt; ok end;<br>
&nbsp;&nbsp; &nbsp; &nbsp; _ -&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ref = make_ref(),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {ok, _} = send_after(Time, Ref),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receive Ref -&gt; ok end<br>&nbsp;&nbsp;&nbsp; end.<br><br><br><div class="gmail_quote">On Fri, Aug 22, 2008 at 10:06 AM, Hynek Vychodil <span dir="ltr">&lt;<a href="mailto:vychodil.hynek <at> gmail.com">vychodil.hynek <at> gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote">
<div dir="ltr">It should be much more simpler to do it without modify timer_server:<div class="Ih2E3d">
<br><br>sleep(Time) -&gt;<br>
&nbsp;&nbsp;&nbsp; case whereis(timer_server) of<br>
&nbsp;&nbsp; &nbsp; &nbsp; undefined -&gt; receive after Time -&gt; ok end;<br>
</div>
&nbsp;&nbsp; &nbsp; &nbsp; _ -&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ref = make_ref(),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; send_after(Time, Ref),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receive Ref -&gt; ok end<br>&nbsp;&nbsp;&nbsp; end.<div>
<div></div>
<div class="Wj3C7c">
<br><br><div class="gmail_quote">On Fri, Aug 22, 2008 at 12:11 AM, Per Hedeland <span dir="ltr">&lt;<a href="mailto:per <at> hedeland.org" target="_blank">per <at> hedeland.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote">
<div>Alp&aacute;r J&uuml;ttner &lt;<a href="mailto:alpar <at> cs.elte.hu" target="_blank">alpar <at> cs.elte.hu</a>&gt; wrote:<br>

&gt;<br>
&gt;As I recall, someone noted on that thread that timer:sleep() works well<br>
&gt;for arbitrarily large numbers.<br><br>
</div>I thought that might have been me:-( - but I see now that I just said<br>
"the timer module" and gave an example using timer:send_after/2, so I<br>
was almost right...<br><div>
<br>
&gt;Now I looked at the source and found that this is _not_ true. Strangely<br>
&gt;enough, all the functions of the timer modules seem to work correctly<br>
&gt;with large numbers _except_ timer:sleep() which has a definition as<br>
&gt;simple as this:<br>
&gt;<br>
&gt;sleep(T) -&gt;<br>
&gt; &nbsp; &nbsp;receive<br>
&gt; &nbsp; &nbsp;after T -&gt; ok<br>
&gt; &nbsp; &nbsp;end.<br><br>
</div>Ouch. But no-one will ever need to sleep for 50 days or more, right?:-)<br><div>
<br>
&gt;It might be worth fixing.<br><br>
</div>And I guess I half-owe the fix - the problem is (as I discovered...)<br>
that there may be (is) code, um, "out there", that relies on being able<br>
to use timer:sleep/1 without having the timer_server running *or*≤br>
getting "auto-started". Below is what I believe to be a backwards-<br>
compatible fix (against R12B-3), but it's pretty ugly - would probably<br>
be better to e.g. &nbsp;define a new function long_sleep/1 or somesuch for<br>
the "unlimited" case.<br><br>
--Per Hedeland<br><br>
--- lib/stdlib/src/timer.erl.orig &nbsp; &nbsp; &nbsp; 2007-11-26 19:55:44.000000000 +0100<br>
+++ lib/stdlib/src/timer.erl &nbsp; &nbsp;2008-08-21 23:00:45.000000000 +0200<br>
 <at>  <at>  -75,9 +75,14  <at>  <at> <br>
&nbsp;cancel(BRef) -&gt;<br>
 &nbsp; &nbsp; req(cancel, BRef).<br><br>
-sleep(T) -&gt;<br>
- &nbsp; &nbsp;receive<br>
- &nbsp; &nbsp;after T -&gt; ok<br>
+sleep(Time) -&gt;<br>
+ &nbsp; &nbsp;case whereis(timer_server) of<br>
+ &nbsp; &nbsp; &nbsp; undefined -&gt;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; receive<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; after Time -&gt; ok<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>
+ &nbsp; &nbsp; &nbsp; _ -&gt;<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req(sleep, Time)<br>
 &nbsp; &nbsp; end.<br><br>
&nbsp;%%<br>
 <at>  <at>  -176,6 +181,13  <at>  <at> <br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{reply, {error, badarg}, [], next_timeout()}<br>
 &nbsp; &nbsp; end;<br><br>
+handle_call({sleep, Time, Started}, From, Ts) -&gt;<br>
+ &nbsp; &nbsp;Req = {apply_after, {Time, {gen_server, reply, [From, ok]}}, Started},<br>
+ &nbsp; &nbsp;case handle_call(Req, From, Ts) of<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;{reply, {ok, _}, _, Timeout} -&gt; {noreply, [], Timeout};<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;Reply &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-&gt; Reply<br>
+ &nbsp; &nbsp;end;<br>
+<br>
&nbsp;handle_call({cancel, BRef = {_Time, Ref}, _}, _From, Ts)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;when is_reference(Ref) -&gt;<br>
 &nbsp; &nbsp; delete_ref(BRef),<br><div>
<div></div>
<div>_______________________________________________<br>
erlang-questions mailing list<br><a href="mailto:erlang-questions <at> erlang.org" target="_blank">erlang-questions <at> erlang.org</a><br><a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br>
</div>
</div>
</blockquote>
</div>
<br><br clear="all"><br>
</div>
</div>-- <br>--Hynek (Pichi) Vychodil<br>
</div>
</blockquote>
</div>
<br><br clear="all"><br>-- <br>--Hynek (Pichi) Vychodil<br>
</div></div>
Per Hedeland | 24 Aug 21:25

Re: max timeout

"Hynek Vychodil" <vychodil.hynek <at> gmail.com> wrote:
>
>          {ok, _} = send_after(Time, Ref),

>> It should be much more simpler to do it without modify timer_server:
>>
>> sleep(Time) ->
>>     case whereis(timer_server) of
>>        undefined -> receive after Time -> ok end;
>>        _ ->
>>           Ref = make_ref(),
>>           send_after(Time, Ref),
>>           receive Ref -> ok end
>>     end.

Matter of taste perhaps, whether you prefer the absolute minimum of
change vs regularity of implementation. One thing that often falls out
of the latter is consistency in API, such that you don't end up with one
API function doing a badmatch crash on erroneous input, while all the
others return {error, badarg}. And of course one could ask why create an
unneeded ref, or why require two messages from the server when you only
need one, but that's more in the nitpicking area.

--Per Hedeland
Bjorn Gustavsson | 25 Aug 09:18

Re: [erlang-questions] max timeout

On Sun, Aug 24, 2008 at 9:25 PM, Per Hedeland <per <at> hedeland.org> wrote:
"Hynek Vychodil" <vychodil.hynek <at> gmail.com> wrote:
>
>          {ok, _} = send_after(Time, Ref),

>> It should be much more simpler to do it without modify timer_server:
>>
>> sleep(Time) ->
>>     case whereis(timer_server) of
>>        undefined -> receive after Time -> ok end;
>>        _ ->
>>           Ref = make_ref(),
>>           send_after(Time, Ref),
>>           receive Ref -> ok end
>>     end.

Matter of taste perhaps, whether you prefer the absolute minimum of
change vs regularity of implementation. One thing that often falls out
of the latter is consistency in API, such that you don't end up with one
API function doing a badmatch crash on erroneous input, while all the
others return {error, badarg}. And of course one could ask why create an
unneeded ref, or why require two messages from the server when you only
need one, but that's more in the nitpicking area.

We have had problems with the timer server becoming seriously overloaded. See:

http://erlang.org/doc/efficiency_guide/commoncaveats.html#3.2

Therefore, I think that the proper way is to do "receive after" in a try/catch,
and only call the timer server if the timeout value is invalid.

If anyone submits a patch like that, we'll try to include it in R12B-4.

/Bjorn

 

--Per Hedeland
_______________________________________________
erlang-questions mailing list
erlang-questions <at> erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions



--
Björn Gustavsson, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-patches mailing list
erlang-patches <at> erlang.org
http://www.erlang.org/mailman/listinfo/erlang-patches
Bjorn Gustavsson | 20 Aug 11:59

Re: max timeout

On Tue, Aug 19, 2008 at 9:42 AM, Matthias Lang <matthias <at> corelatus.se> wrote:

This may be the thread you remember, it starts here:

 http://www.erlang.org/pipermail/erlang-questions/2008-February/032609.html

Executive summary: In R11B-2, a timeout of 16#ffffFFFF doesn't work as
   expected on a 32-bit machine. Something changed between R11B-2 and
   R11B-5 which made it work in the shell, but still not in compiled
   code. I haven't noticed anything in the release notes saying it's
   been fixed for real.

Actually, a value of 16#ffffFFFF sometimes works, sometimes doesn't. It has
nothing to do with whether it is executed from the shell or from compiled code.

The problem is an integer overflow. We will include a correction in R12B-4.

/Bjorn
--
Björn Gustavsson, Erlang/OTP, Ericsson AB
<div><div dir="ltr">On Tue, Aug 19, 2008 at 9:42 AM, Matthias Lang <span dir="ltr">&lt;<a href="mailto:matthias <at> corelatus.se">matthias <at> corelatus.se</a>&gt;</span> wrote:<br><div class="gmail_quote">
<blockquote class="gmail_quote">
<div class="Ih2E3d"><br></div>This may be the thread you remember, it starts here:<br><br>
 &nbsp;<a href="http://www.erlang.org/pipermail/erlang-questions/2008-February/032609.html" target="_blank">http://www.erlang.org/pipermail/erlang-questions/2008-February/032609.html</a><br><br>
Executive summary: In R11B-2, a timeout of 16#ffffFFFF doesn't work as<br>
 &nbsp; &nbsp;expected on a 32-bit machine. Something changed between R11B-2 and<br>
 &nbsp; &nbsp;R11B-5 which made it work in the shell, but still not in compiled<br>
 &nbsp; &nbsp;code. I haven't noticed anything in the release notes saying it's<br>
 &nbsp; &nbsp;been fixed for real.<br>
</blockquote>
<div>
<br>Actually, a value of 16#ffffFFFF sometimes works, sometimes doesn't. It has<br>nothing to do with whether it is executed from the shell or from compiled code.<br><br>The problem is an integer overflow. We will include a correction in R12B-4.<br><br>/Bjorn<br>
</div>
</div>-- <br>Bj&ouml;rn Gustavsson, Erlang/OTP, Ericsson AB<br>
</div></div>
Serge Aleynikov | 20 Aug 12:38

Re: max timeout

So, does this mean that #1 below is indeed the right answer and that 
'receve after' implementation correctly deals with bignums between 2^27 
and 2^32?

1. 2^32 (this is what's documented, but only seems to work in the shell)
2. 2^32-1 = 49.5 days
3. Erlang's small integers (2^27-1 = 1.5 days)

Bjorn Gustavsson wrote:
> On Tue, Aug 19, 2008 at 9:42 AM, Matthias Lang <matthias <at> corelatus.se>wrote:
> 
>> This may be the thread you remember, it starts here:
>>
>>
>> http://www.erlang.org/pipermail/erlang-questions/2008-February/032609.html
>>
>> Executive summary: In R11B-2, a timeout of 16#ffffFFFF doesn't work as
>>    expected on a 32-bit machine. Something changed between R11B-2 and
>>    R11B-5 which made it work in the shell, but still not in compiled
>>    code. I haven't noticed anything in the release notes saying it's
>>    been fixed for real.
>>
> 
> Actually, a value of 16#ffffFFFF sometimes works, sometimes doesn't. It has
> nothing to do with whether it is executed from the shell or from compiled
> code.
> 
> The problem is an integer overflow. We will include a correction in R12B-4.
> 
> /Bjorn
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions <at> erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions


Gmane