homanchou

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

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 :slight_smile:

Also Liked

sasajuric

sasajuric

Author of Elixir In Action

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

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_active timestamp in the state, and send a :check_timeout delayed message to the GenServer itself with Process.send_after/4 and a timeout equal to the desired inactivity timeout

  • Handle the :check_timeout message with handle_info, checking if enough time elapsed since last_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

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

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?

Where Next?

Popular in Questions Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

Other popular topics Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement