Packages
islands_engine
0.1.60
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, Info}
alias Islands.Engine.Game.{Server, Tally}
alias Islands.Engine
@timeout 10
@times 5
@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 ->
Error.log(:exit, reason, caller)
game_name
|> wait(caller, @times)
|> Server.via()
|> GenServer.call(request)
end
@spec stop(atom, String.t(), tuple) :: :ok
def stop(reason, game_name, caller) do
game_name |> Server.via() |> GenServer.stop(reason)
catch
:exit, exit_reason ->
Error.log(:exit, exit_reason, caller)
game_name
|> wait(caller, @times)
|> Server.via()
|> GenServer.stop(reason)
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
Info.log(:game_not_registered, game_name, @timeout, times_left, caller)
Process.sleep(@timeout)
case Engine.game_pid(game_name) do
pid when is_pid(pid) ->
Info.log(:game_registered, game_name, pid, times_left, caller)
game_name
nil ->
wait(game_name, caller, times_left - 1)
end
end
end