Thank you @kokolegorille for your GenServer example!
Ha ha I am sorry I do not know what this is like. Maybe there is a good explanation somewhere?
My GenServer is a simple map – I mostly copied from the “KV” example in the docs.
defmodule MyApp.Registry do
# Simple map to keep state
@moduledoc false
use GenServer
require Logger
def start_link(_args \\ %{}), do: GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
@doc """
Checks to see if the given key exists.
"""
def exists?(key) when is_atom(key) do
GenServer.call(__MODULE__, {:exists?})
end
@doc """
Lists all registered keys.
"""
def list() do
GenServer.call(__MODULE__, {:list})
end
@doc """
Looks up the info for the given `key`.
"""
def lookup(key) when is_atom(key) do
GenServer.call(__MODULE__, {:lookup, key})
end
@doc """
Registers the `info` for the given `key`.
"""
def register(key, info) when is_atom(key) do
GenServer.call(__MODULE__, {:register, key, info})
end
def stop(), do: GenServer.cast(__MODULE__, :stop)
@doc """
Unregisters the given `key`
"""
def unregister(key) when is_atom(key) do
GenServer.call(__MODULE__, {:unregister, key})
end
@impl GenServer
def init(state) do
{:ok, state}
end
@impl true
def handle_call({:exists?, key}, _from, state) do
{:reply, Map.has_key?(state, key), state}
end
@impl true
def handle_call({:list}, _from, state) do
{:reply, Map.keys(state), state}
end
@impl true
def handle_call({:lookup, key}, _from, state) do
{:reply, Map.get(state, key), state}
end
@impl true
def handle_call({:register, key, info}, _from, state) do
{:reply, :ok, Map.put(state, key, info)}
end
@impl true
def handle_call({:unregister, key}, _from, state) do
{:reply, :ok, Map.delete(state, key)}
end
@impl true
def handle_cast(:stop, state) do
File.write!("/tmp/genserver_stop.txt", ":stop")
{:stop, :normal, state}
end
end
I have been exploring :dets
tables, and I keep getting errors that the files were not closed properly, so this is why I want to implement some cleanup functionality when my application stops. I also tried adding some functions (callbacks?) to my application.ex
– stop/1
and `prep_stop/``:
defmodule MyApp.Application do
@moduledoc false
use Application
def start(_type, _args) do
IO.puts("Starting up myapp")
children = [
{Pockets.Registry, []}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
def prep_stop(_) do
File.write!("/tmp/prep_stop.txt", "prep_stop")
end
def stop(_) do
File.write!("/tmp/stop.txt", "stop")
end
end
but those functions never seem to get called. When close iex
for example, I want to run some cleanup code somewhere but so far I cannot figure out how to do this. Sorry if I am slow in understanding this. Actors and models seems very foreign for me.