implementing state_timeout in AshStateMachine
abeeshake456:
Just had a look at https://github.com/ash-project/ash_state_machine/blob/v0.1.4/test/ash_state_machine_test.exs
Is there an option similar to :state_timeout from https://www.erlang.org/doc/man/gen_statem.html#type-timeout_event_type
The use case is - if one state doesn’t get a new transition within
:state_timeout
seconds, it doesn’t keep waiting forever
jharton:
So depending on how long you want your timeout to be (and how restart robust) I see you have two main options.
-
In your actions that move into a timeoutable state you add a change which calls
:timer.apply_after/4
( https://erlang.org/doc/man/timer.html#apply_after-4 ) to invoke another action which moves it into the timeout state if it hasn’t succeeded yet. -
In your actions that move into a timeoutable state you add a change which queues a job for later execution with a durable queue (eg
Oban
https://hexdocs.pm/oban/Oban.html#module-scheduling-jobs )
A variation on option 2 might be to just have an oban job that runs every
n
minutes which checks to see if there are any records that have been in the timeoutable state for longer than expected (eg
expr(state == :waiting && updated_at < ago(5, :minute))
)
zachdaniel:
Keep in mind, ash_state_machine is not starting genservers.
zachdaniel:
Unless you’ve got your actions doing that.
zachdaniel:
It uses whatever data layer you’re using in the resource.
zachdaniel:
Id probably use
ash_oban
with a trigger on how long it’s been waiting, but that’s only good for things longer than a minute, generally
zachdaniel:
Which is basically #2 above but with ash_oban.
\ ឵឵឵:
If the exact duration of the timeout is relevant to the correctness of your application, you may also consider setting a timestamp attribute on your resource when entering the timed state and validating that it is within the allowed offset in actions relevant for that state.
\ ឵឵឵:
This is not mutually exclusive with the aforementioned methods for executing other actions/cleanups at some point after that duration has elapsed.
abeeshake456:
Some of the broader ideas make sense. I’ll try it out to understand better. 🙂