[erlang-questions] state_timeout reset in gen_statem

40 views
Skip to first unread message

Nato

unread,
Apr 27, 2018, 5:06:37 PM4/27/18
to erlang-q...@erlang.org
I may be muddled, but as far I can observe, my
code seems correct, but am getting unexpected
behavior from OTP 20's gen_statem behavior.

I have a state that times out in, say, 3 seconds.
I have a `bump' routine that casts to that state,
and subsequently set it again to 3 seconds. In my
tests, the initial timer holds fast, and despite
my debugging efforts, the original timer isn't
reset as the documentation says is ought to in
the gen_statem manual (state_timeout() type
section) :

`...

Setting this timer while it is running will
restart it with the new time-out value.
Therefore it is possible to cancel this
time-out by setting it to infinity.

...'

Some relevant code as follows:

...
waiting({call, From}, {entry, Key}, #session{}=Ld) ->
{ok, Ld1} = handle(start_session, {Key, Ld}),
Reply = {reply, From, ok},
Timeout = session_duration(alive),
{next_state, alive, Ld1, [
Reply, {state_timeout, Timeout, hard_stop}]};
...

alive(cast, bump, #session{}=Ld) ->
ok = handle(bump_session, Ld),
Timeout = session_duration(alive),
{keep_state, Ld, [Timeout]};
...

session_duration(alive) ->
timer:hms(0, 0, 3);
...

Indeed, the new `bump' cast, never resets the
original, extending the timeout to a fresh 3
second timeout.

On a separate note, any best practices for putting
together test code that juggles timeouts to
validate such things, would be appreciate.

_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Raimo Niskanen

unread,
Apr 30, 2018, 2:50:00 AM4/30/18
to erlang-q...@erlang.org
This function returns 3000, which, when returned in from alive/3 as
{keep_state, Ld, [3000]]} is equivalent to
{keep_state, Ld, [{timeout,3000,3000}]}.

That sets the event timeout in addition to the running state timeout.

With "this timer" the manual understands that there are different
"this timer"s: The event timeour, the state timeout, and each
generic timeout are all separate timers.

You should return
{keep_state, Ld, [{state_timeout,session_duration(alive),hard_stop}]}
instead.

/ Raimo Niskanen


> ...
>
> Indeed, the new `bump' cast, never resets the
> original, extending the timeout to a fresh 3
> second timeout.
>
> On a separate note, any best practices for putting
> together test code that juggles timeouts to
> validate such things, would be appreciate.
>
> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
Reply all
Reply to author
Forward
0 new messages