defmodule Hangman.Engine.GameRecovery do
@moduledoc """
Makes processes under the top supervisor fault-tolerant. If any crashes (or
is killed), it is immediately restarted and the system remains undisturbed.
"""
use GenServer
use PersistConfig
alias __MODULE__
alias Hangman.Engine.{DynGameSup, GameServer}
@ets get_env(:ets_name)
@spec start_link(term) :: GenServer.on_start()
def start_link(:ok = _init_arg),
do: GenServer.start_link(GameRecovery, :ok, name: GameRecovery)
## Private functions
@spec restart_servers :: :ok
defp restart_servers do
@ets
|> :ets.match_object({{GameServer, :_}, :_})
|> Enum.each(fn {{GameServer, game_name}, _game} ->
# Child may already be started...
DynamicSupervisor.start_child(DynGameSup, {GameServer, game_name})
end)
end
## Callbacks
@spec init(term) :: {:ok, term}
def init(:ok = _init_arg), do: {:ok, restart_servers()}
end