Current section

Files

Jump to
islands_engine lib islands engine proxy.ex
Raw

lib/islands/engine/proxy.ex

defmodule Islands.Engine.Proxy do
@moduledoc """
Runs function `GenServer.call` on behalf of module `Islands.Engine`
while providing increased fault-tolerance capability.
"""
alias Islands.Engine.Game.{Server, Tally}
alias Islands.Engine
require Logger
@timeout_in_ms 10
@times 100
@spec call(tuple, String.t(), tuple) :: Tally.t()
def call(request, game_name, caller) do
game_name
|> Server.via()
|> GenServer.call(request)
catch
:exit, reason ->
Logger.error("""
\n`exit` caught for calling function #{inspect(caller)}...
`exit` reason:
#{inspect(reason)}
""")
game_name
|> wait(caller, @times)
|> Server.via()
|> GenServer.call(request)
end
## Private functions
# On restarts, wait if name not yet registered...
@spec wait(String.t(), tuple, non_neg_integer) :: String.t()
defp wait(game_name, _caller, 0), do: game_name
defp wait(game_name, caller, times_left) do
Logger.info("""
\nGame #{inspect(game_name)} not registered:
• Waiting: #{@timeout_in_ms} ms
• Waits left: #{times_left}
• Calling function: #{inspect(caller)}
""")
Process.sleep(@timeout_in_ms)
case Engine.game_pid(game_name) do
pid when is_pid(pid) ->
Logger.info("""
\nGame #{inspect(game_name)} registered:
• PID: #{inspect(pid)}
• Waits left: #{times_left}
• Calling function: #{inspect(caller)}
""")
game_name
nil ->
wait(game_name, caller, times_left - 1)
end
end
end