Session on a GenServer

Assuming you will have a GenServer per session, you can send yourself a message on init to shutdown:

def init(args) do
  Process.send_after(self(), :bye, @expires_in_minutes * 60 * 1000) # microseconds
  {:ok, struct(...)}
end

Then after a certain time, you will receive the message above, which you can handle in handle_info:

def handle_info(:bye, state) do
  {:stop, :shutdown, state}
end

But you may say: “I don’t want to shutdown if I received a get request not a long time ago”. Then you can cancel the shutdown request on every get and schedule a new one:

def init(args) do
  ref = schedule_shutdown(make_ref()) # create a fake reference to cancel the first time 
  {:ok, struct(..., ref: ref)} # store the reference in the struct too
end

def handle_call(:get, _from, session) do
  ref = schedule_shutdown(session.ref) # cancel existing reference
  {:reply, session, %{session | ref: ref}} # and set the new reference
end

defp schedule_shutdown(ref) do
  Process.cancel_timer(ref)
  Process.send_after(self(), :bye, @expires_in_minutes * 60 * 1000) # microseconds
end
7 Likes