Created
July 18, 2018 12:51
-
-
Save minhajuddin/663ae20cad246f1e3b1cf9493c7d8531 to your computer and use it in GitHub Desktop.
Rolling/Sliding timeouts for Elixir GenServers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule SearchWorker do | |
use GenServer | |
@idle_timeout_ms 10 * 60 * 1000 | |
@impl GenServer | |
def init(state) do | |
# send ourselves a message after 10 seconds and cleanup the proc tree when we get this | |
Process.send_after(self(), :idle_timeout, @idle_timeout_ms) | |
{:ok, state} | |
end | |
@impl GenServer | |
def handle_info(:idle_timeout, state) do | |
# do whatever you want to do to cleanup your process tree | |
shutdown_proc_tree(state) | |
{:noreply, state} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule SearchWorker do | |
use GenServer | |
@idle_timeout_ms 10 * 60 * 1000 | |
# client api | |
def touch(pid) do | |
GenServer.cast(pid, :touch) | |
end | |
@impl GenServer | |
def init(_opts) do | |
state = touch_idle_timer(%{}) | |
{:ok, state} | |
end | |
@impl GenServer | |
def handle_cast(:touch, state) do | |
# cancel current timer | |
Process.cancel_timer(state.idle_timer) | |
# create a new timer | |
state = touch_idle_timer(state) | |
{:noreply, state} | |
end | |
def handle_info(:idle_timeout, state) do | |
# do whatever you want to do to cleanup your process tree | |
shutdown_proc_tree(state) | |
{:noreply, state} | |
end | |
defp touch_idle_timer(state) do | |
# send ourselves a message after 10 seconds and cleanup the proc tree when we get this | |
idle_timer = Process.send_after(self(), :idle_timeout, @idle_timeout_ms) | |
%{state | idle_timer: idle_timer} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule SearchWorker do | |
use GenServer | |
@idle_timeout_ms 10 * 60 * 1000 | |
# client api | |
def touch(pid) do | |
GenServer.cast(pid, :touch) | |
end | |
@impl GenServer | |
def init(_opts) do | |
state = touch_idle_timer(%{}) | |
{:ok, state} | |
end | |
@impl GenServer | |
def handle_cast(:touch, state) do | |
state = touch_idle_timer(state) | |
{:noreply, state} | |
end | |
# we got our idle timeout let's clean it up | |
def handle_info({:idle_timeout, idle_timeout_ref}, %{idle_timeout_ref: idle_timeout_ref} = state) do | |
# do whatever you want to do to cleanup your process tree | |
shutdown_proc_tree(state) | |
{:noreply, state} | |
end | |
# we have an old timeout coming through, we should just ignore it | |
def handle_info({:idle_timeout, _ref}, state), do: {:noreply, state} | |
defp touch_idle_timer(state) do | |
idle_timeout_ref = make_ref() | |
# send ourselves a message after 10 seconds and cleanup the proc tree when we get this | |
idle_timer = Process.send_after(self(), {:idle_timeout, idle_timeout_ref}, @idle_timeout_ms) | |
%{state | idle_timer_ref: idle_timer_ref} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment