Skip to content

Instantly share code, notes, and snippets.

@DeedleFake
Last active September 29, 2024 03:18
Show Gist options
  • Select an option

  • Save DeedleFake/795c9026d5c6d6ee08138884dc14ac09 to your computer and use it in GitHub Desktop.

Select an option

Save DeedleFake/795c9026d5c6d6ee08138884dc14ac09 to your computer and use it in GitHub Desktop.
Simple GenServer that can coordinate work to a single duplicate of itself across a cluster.
defmodule Test do
use GenServer
require Logger
def start_link([]) do
GenServer.start_link(__MODULE__, [])
end
def init([]) do
Process.send_after(self(), :test, 10 * 1000)
{:ok, register()}
end
def handle_info({:DOWN, ref, :process, _pid, _reason}, state) when ref == state do
Logger.info("down matched")
{:noreply, register()}
end
def handle_info({:DOWN, _ref, :process, _pid, _reason}, state) do
Logger.info("down didn't match")
{:noreply, state}
end
def handle_info({:global_name_conflict, __MODULE__}, _state) do
Logger.info("unregistered by conflict")
{:noreply, register()}
end
def handle_info(:test, :registered) do
Logger.info("timer while registered")
Process.send_after(self(), :test, 10 * 1000)
{:noreply, :registered}
end
def handle_info(:test, state) do
Logger.info("timer but not registered")
Process.send_after(self(), :test, 10 * 1000)
{:noreply, state}
end
defp register() do
case :global.whereis_name(__MODULE__) do
:undefined ->
case :global.register_name(__MODULE__, self(), &:global.random_notify_name/3) do
:yes -> :registered
:no -> register()
end
pid ->
Process.monitor(pid)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment