I am using OTP for managing a queue of events:
defmodule ParrotApi.MatchingSupervisor do
use Supervisor
## Callbacks
def start_link() do
Supervisor.start_link(__MODULE__, [])
end
def init(_) do
children = [
worker(ParrotApi.MatchingServer, []), # TODO: State is gone if this crashes
# Supervise connections
supervisor(Registry, [:unique, :connection_registry]),
supervisor(ParrotApi.ConnectionSupervisor, []),
]
supervise(children, strategy: :one_for_one)
end
end
My question is, if the server restarts, what happens to my queue? I need it to persist after restarting. To my knowledge it is stored in memory so it is wiped if the server restarts.
I create a separate Agent to track the state in the GenServer. The Agent is very simple, with an API to update the state, and fetch it upon request.
I create reply(state, result)
and noreply(state)
functions in the GenServer and call them at the end of the handle_call
, handle_cast
, and handle_info
functions.
The reply
and no_reply
functions put the state
in the Agent and then return the {:no_reply, state}
and {:reply, result, state}
tuples. I also update the agent on terminate.
When the server restarts, I check to see if its a restart and if so, pull the state from the agent in the genservers init
callback. I just check the agent. If it does not have data, I know is a the original startup.
The idea here is that the Agent is a very simple value store. Its very simple and unlikely to fail.
You should be careful with this approach though. The idea behind the restart strategy is that the GenServer is restarted with its initial state. If your GenServer restarted because of an issue with its state, it may get into a continuous restart state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With