Ideally I want to create a gen_server and stop it after some timeout after inactivity (not receiving messages).
With simple process I can achieve that with this:
def MyProcess do
def new do
spawn fn -> init() end
end
def init do
state = %State{}
loop(state)
end
def loop(state) do
receive do
some_stuff ->
# some stuff going here
loop(state)
after
@timeout ->
exit(:normal)
end
end
end
If I’m reading this properly, there’s actually something built into GenServer for this too.
defmodule Timesout do
@timeout 1000
use GenServer
require Logger
def start_link do
GenServer.start_link(__MODULE__, [])
end
def init(_) do
Logger.info "starting up with timeout #{@timeout}"
{:ok, [], @timeout}
end
def handle_call({:add, a, b}, _, _) do
Logger.info "adding and resetting timer"
{:reply, a + b, [], @timeout}
end
def handle_info(:timeout, _) do
Logger.info "shutting down"
{:stop, :normal, []}
end
end
{:ok, p} = Timesout.start_link
Process.sleep(900)
IO.inspect GenServer.call(p, {:add, 10, 20})
Process.sleep(1100)
IO.inspect GenServer.call(p, {:add, 20, 50})
This results in:
> elixir timesout.exs 2646ms Wed Sep 21 10:42:38 2016
10:43:37.778 [info] starting up with timeout 1000
10:43:38.685 [info] adding and resetting timer
30
10:43:39.688 [info] shutting down
** (exit) exited in: GenServer.call(#PID<0.76.0>, {:add, 20, 50}, 5000)
** (EXIT) no process
(elixir) lib/gen_server.ex:604: GenServer.call/3
timesout.exs:38: (file)
(elixir) lib/code.ex:363: Code.require_file/2
Does this timeout includes messages from all call and cast methods? For example in my GenServer I have a few call methods and a few cast methods and I return {:reply, reply, new_state, timeout}
or {:noreply, new_state, timeout}
timeout refers to calls to any of this methods or just to that specific call or cast?
I hope my question is clear.