homanchou
Is there a way to self terminate a genserver after no activity?
When using simple processes we can spawn a recursive loop with a timeout like this:
iex> receive do
...> {:hello, msg} -> msg
...> after
...> 1_000 -> "nothing after 1s"
...> end
after 1s the process will exit.
Is there a similar way of shutting down a genserver after a period of inactivity?
The longer explanation of why I might want this is that I’m looking at using at genservers as a way to load up aggregate instances in domain driven design/cqrs/event-sourcing (Bryan Hunter’s talk: Bryan Hunter - CQRS with Erlang). Each aggregate is initialized with the state of some business entity, they accept commands, they update state, etc. In his talk he loads ups a simple process for each aggregate with a 45 second timeout, but mentions when going to production maybe we want to use genserver or genFSM. I don’t really need these aggregates supervised since they can recreated whenever we need to submit a command (can stick the process into a registry for serialized access).
Marked As Solved
jwarlander
During initialization, you can return with a timeout (see GenServer docs). Same for handle_call etc. Then just take care of the timeout event by, eg., stopping.. Or whatever you need to do ![]()
Also Liked
sasajuric
Keep in mind that the timeout is reset when a new message arrives, and you need to set it again explicitly. If you forget to do that in just one of handle_* clauses, the timeout might never happen.
lucaong
Or even, do exactly what @1player suggested, but instead of scheduling the :check_timeout message every second:
-
Upon every call that counts for the timeout, update the
last_activetimestamp in the state, and send a:check_timeoutdelayed message to the GenServer itself withProcess.send_after/4and a timeout equal to the desired inactivity timeout -
Handle the
:check_timeoutmessage withhandle_info, checking if enough time elapsed sincelast_active. If so, return{:stop, :normal, state}, otherwise{:noreply, state}.
It is basically the same, but it removes the need to poll every second/minute/etc.
OvermindDL1
Not just deflate, it does indeed run a GC over it but it also throws away the stack above the current call context, but it will still receive and process messages as normal after that. Hibernation does not terminate at all, just think of it as running a GC in such a way that you can’t return from any current function (which thankfully a genserver handles for you). ^.^
Last Post!
mrcampbell
Is this essential a debounced/throttled (I’m not sure which in the nuance of the two this is) method?
I’m implementing a spellcheck that I want to have triggered X amount of time after last keydown and was looking to use this method. Unless there’s a better way?
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









