Packages
islands_engine
0.1.63
0.2.65
0.2.64
0.2.63
0.2.62
0.2.61
0.2.60
0.2.59
0.2.58
0.2.56
0.2.55
0.2.54
0.2.53
0.2.52
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.43
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.34
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.27
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.13
0.2.12
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.81
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.73
0.1.72
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.0
Models the Game of Islands.
Current section
Files
Jump to
Current section
Files
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 __MODULE__.{Error, GameNotStarted, Info}
alias Islands.Engine.Game.{Server, Tally}
alias Islands.Engine
@timeout 10
@times 5
@spec call(tuple, String.t()) :: Tally.t() | :ok
def call(request, game_name) do
game_name |> Server.via() |> GenServer.call(request)
catch
:exit, reason ->
Error.log(:exit, reason)
case wait(game_name, reason, @times) do
{:registered, game_name} ->
game_name |> Server.via() |> GenServer.call(request)
{:unregistered, game_name} ->
Info.log(:game_not_started, game_name)
game_name |> GameNotStarted.message() |> IO.puts()
end
end
@spec stop(atom, String.t()) :: :ok
def stop(reason, game_name) do
game_name |> Server.via() |> GenServer.stop(reason)
catch
:exit, exit_reason ->
Error.log(:exit, exit_reason)
case wait(game_name, reason, @times) do
{:registered, game_name} ->
game_name |> Server.via() |> GenServer.stop(reason)
{:unregistered, game_name} ->
Info.log(:game_not_started, game_name)
game_name |> GameNotStarted.message() |> IO.puts()
end
end
## Private functions
# On restarts, wait if name not yet registered...
@spec wait(String.t(), term, non_neg_integer) :: {atom, String.t()}
defp wait(game_name, _reason, 0), do: {:unregistered, game_name}
defp wait(game_name, reason, times_left) do
Info.log(:game_not_registered, game_name, @timeout, times_left, reason)
Process.sleep(@timeout)
case Engine.game_pid(game_name) do
pid when is_pid(pid) ->
Info.log(:game_registered, game_name, pid, times_left, reason)
{:registered, game_name}
nil ->
wait(game_name, reason, times_left - 1)
end
end
end