Skip to content

Commit 93473d8

Browse files
committed
A variety of fixes
1 parent 67b5a76 commit 93473d8

File tree

17 files changed

+148
-89
lines changed

17 files changed

+148
-89
lines changed

.dockerignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
/apps/tanx_web/priv/static/
55
/apps/tanx_web/test/
66
/deps/
7-
/kube/
87
/test/
8+
/tmp/

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ Now we'll set up Google Kubernetes Engine to host an online tanx server.
148148
3. Configure gcloud to use your cluster as default so you don't have to
149149
specify it every time for the remaining gcloud commands.
150150

151+
gcloud container clusters get-credentials tanx-cluster-1
151152
gcloud config set container/cluster tanx-cluster-1
152153

153154
Replace the name if you named your cluster differently.

apps/tanx/lib/tanx/cluster.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ defmodule Tanx.Cluster do
1313
Supervisor.stop(Tanx.Cluster.Supervisor)
1414
end
1515

16+
def connect_node(:""), do: nil
17+
1618
def connect_node(node) do
1719
Horde.Cluster.join_hordes(Tanx.HordeHandoff, {Tanx.HordeHandoff, node})
1820
Horde.Cluster.join_hordes(Tanx.HordeSupervisor, {Tanx.HordeSupervisor, node})

apps/tanx/lib/tanx/continuous_game/impl.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
defmodule Tanx.ContinuousGame.Impl do
2-
@default_player_timeout 7200.0
2+
@default_player_timeout 3600.0
33

44
defstruct(
55
maze: nil,
@@ -373,6 +373,10 @@ defimpl Tanx.Game.Variant, for: Tanx.ContinuousGame.Impl do
373373
{data, [], []}
374374
end
375375

376+
def stats(data, _arena, _time) do
377+
%{player_count: Enum.count(data.player_handles)}
378+
end
379+
376380
def stop(_data, _arena, _time) do
377381
%{}
378382
end

apps/tanx/lib/tanx/game/main.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ defmodule Tanx.Game do
3636
defstruct(
3737
id: nil,
3838
running: false,
39-
display_name: "",
4039
node: nil,
41-
data: nil
40+
settings: %{},
41+
stats: %{}
4242
)
4343
end
4444

apps/tanx/lib/tanx/game/manager.ex

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
defmodule Tanx.Game.Manager do
22
def start_link(game_id, opts \\ []) do
3-
process_opts =
4-
case Keyword.fetch(opts, :game_address) do
5-
{:ok, addr} -> [name: addr]
6-
:error -> []
7-
end
8-
9-
GenServer.start(__MODULE__, {game_id, opts}, process_opts)
3+
GenServer.start(__MODULE__, {game_id, opts})
104
end
115

126
use GenServer
@@ -29,13 +23,13 @@ defmodule Tanx.Game.Manager do
2923
handoff: nil,
3024
opts: [],
3125
node: nil,
32-
display_name: "",
3326
data: nil,
3427
arena: nil,
3528
commands: [],
3629
sent_commands: [],
3730
callbacks: %{},
38-
time: 0.0
31+
time: 0.0,
32+
settings: %{}
3933
)
4034
end
4135

@@ -62,11 +56,13 @@ defmodule Tanx.Game.Manager do
6256
end
6357

6458
def handle_call({:meta}, _from, state) do
59+
stats = Tanx.Game.Variant.stats(state.data, state.arena, state.time)
6560
meta = %Tanx.Game.Meta{
6661
id: state.game_id,
6762
running: state.running,
68-
display_name: state.display_name,
69-
node: Node.self()
63+
node: Node.self(),
64+
settings: state.settings,
65+
stats: stats
7066
}
7167

7268
{:reply, {:ok, meta}, state}
@@ -182,6 +178,8 @@ defmodule Tanx.Game.Manager do
182178
def flatten_and_reverse(output, cmd), do: [cmd | output]
183179

184180
defp state_from_handoff(base_state, handoff_state) do
181+
Horde.Registry.register(Tanx.HordeRegistry, handoff_state.game_id)
182+
185183
opts =
186184
Keyword.update!(handoff_state.opts, :time_config, fn
187185
tc when is_integer(tc) -> Tanx.Util.SystemTime.updated_offset(handoff_state.time)
@@ -228,7 +226,7 @@ defmodule Tanx.Game.Manager do
228226
running: false,
229227
handoff: handoff,
230228
opts: opts,
231-
display_name: display_name,
229+
settings: %{display_name: display_name},
232230
node: Node.self()
233231
}
234232
end
@@ -250,6 +248,8 @@ defmodule Tanx.Game.Manager do
250248
Tanx.Util.Handoff.unrequest(base_state.handoff, base_state.game_id)
251249
end
252250

251+
Horde.Registry.register(Tanx.HordeRegistry, base_state.game_id)
252+
253253
opts = base_state.opts
254254
time_config = Keyword.get(opts, :time_config, Tanx.Util.SystemTime.cur_offset())
255255
opts = Keyword.put(opts, :time_config, time_config)
@@ -308,7 +308,7 @@ defmodule Tanx.Game.Manager do
308308
running: false,
309309
handoff: state.handoff,
310310
opts: state.opts,
311-
display_name: state.display_name,
311+
settings: state.settings,
312312
node: Node.self()
313313
}
314314
end

apps/tanx/lib/tanx/game/variant.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ defprotocol Tanx.Game.Variant do
22
def init_arena(data, time)
33
def control(data, arena, time, params)
44
def event(data, event)
5+
def stats(data, arena, time)
56
def stop(data, arena, time)
67
end

apps/tanx/lib/tanx/util/handoff.ex

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule Tanx.Util.Handoff do
1818
end
1919

2020
def store(handoff, name, data) do
21-
GenServer.cast(handoff, {:store, name, data})
21+
GenServer.call(handoff, {:store, name, data})
2222
end
2323

2424
use GenServer
@@ -84,6 +84,7 @@ defmodule Tanx.Util.Handoff do
8484
end
8585

8686
def handle_call({:join_hordes, other_horde}, from, state) do
87+
Logger.info("**** Handoff requesting join hordes")
8788
GenServer.cast(
8889
other_horde,
8990
{:request_to_join_hordes, {state.node_id, state.members_pid, from}}
@@ -104,10 +105,12 @@ defmodule Tanx.Util.Handoff do
104105
{:operation, {:remove, [name]}}
105106
)
106107

108+
Logger.info("**** Handoff fulfilling request for: #{inspect(name)}")
107109
:ets.delete(state.ets_table, name)
108110
{:reply, {:ok, :data, data}, state}
109111

110112
_ ->
113+
Logger.info("**** Handoff deferring request for: #{inspect(name)}")
111114
requests = Map.put(state.requests, name, {pid, message})
112115
{:reply, {:ok, :requested}, %State{state | requests: requests}}
113116
end
@@ -118,10 +121,11 @@ defmodule Tanx.Util.Handoff do
118121
{:reply, :ok, %State{state | requests: requests}}
119122
end
120123

121-
def handle_cast({:store, name, data}, state) do
124+
def handle_call({:store, name, data}, _from, state) do
125+
Logger.info("**** Handoff storing data for: #{inspect(name)}")
122126
case Map.get(state.requests, name) do
123127
nil ->
124-
GenServer.cast(
128+
GenServer.call(
125129
state.processes_pid,
126130
{:operation, {:add, [name, data]}}
127131
)
@@ -132,25 +136,27 @@ defmodule Tanx.Util.Handoff do
132136
send(pid, {message, data})
133137
end
134138

135-
{:noreply, state}
139+
{:reply, :ok, state}
136140
end
137141

138142
def handle_cast(
139143
{:request_to_join_hordes, {_other_node_id, other_members_pid, reply_to}},
140144
state
141145
) do
146+
Logger.info("**** Handoff receiving join hordes")
142147
Kernel.send(state.members_pid, {:add_neighbours, [other_members_pid]})
143148
GenServer.reply(reply_to, true)
144149
{:noreply, state}
145150
end
146151

147152
def handle_info({:processes_updated, reply_to}, state) do
148-
processes = DeltaCrdt.CausalCrdt.read(state.processes_pid, 30_000)
153+
processes = DeltaCrdt.CausalCrdt.read(state.processes_pid, 2000)
149154

150155
:ets.insert(state.ets_table, Map.to_list(processes))
151156

152157
all_keys = :ets.match(state.ets_table, {:"$1", :_}) |> MapSet.new(fn [x] -> x end)
153158
new_keys = Map.keys(processes) |> MapSet.new()
159+
Logger.info("**** Handoff received data update: #{inspect(MapSet.to_list(new_keys))}")
154160
to_delete_keys = MapSet.difference(all_keys, new_keys)
155161

156162
to_delete_keys |> Enum.each(fn key -> :ets.delete(state.ets_table, key) end)
@@ -166,6 +172,7 @@ defmodule Tanx.Util.Handoff do
166172

167173
data ->
168174
send(pid, {message, data})
175+
Logger.info("**** Handoff sending message for: #{inspect(name)}")
169176

170177
GenServer.cast(
171178
state.processes_pid,
@@ -184,7 +191,7 @@ defmodule Tanx.Util.Handoff do
184191
end
185192

186193
def handle_info({:members_updated, reply_to}, state) do
187-
members = DeltaCrdt.CausalCrdt.read(state.members_pid, 30_000)
194+
members = DeltaCrdt.CausalCrdt.read(state.members_pid, 2000)
188195

189196
member_pids =
190197
MapSet.new(members, fn {_key, {members_pid, _processes_pid}} -> members_pid end)
@@ -194,6 +201,8 @@ defmodule Tanx.Util.Handoff do
194201
MapSet.new(state.members, fn {_key, {members_pid, _processes_pid}} -> members_pid end)
195202
|> MapSet.delete(nil)
196203

204+
Logger.info("**** Handoff received members updated: #{inspect(Enum.count(state_member_pids))} -> #{inspect(Enum.count(member_pids))}")
205+
197206
# if there are any new pids in `member_pids`
198207
if MapSet.difference(member_pids, state_member_pids) |> Enum.any?() do
199208
processes_pids =
@@ -213,14 +222,16 @@ defmodule Tanx.Util.Handoff do
213222
end
214223

215224
def handle_info(whatevah, state) do
216-
Logger.warn("**** Received unexpected message: #{inspect(whatevah)}")
225+
Logger.warn("**** Handoff received unexpected message: #{inspect(whatevah)}")
217226
{:noreply, state}
218227
end
219228

220229
def terminate(reason, state) do
221230
Logger.info("**** Terminating handoff due to #{inspect(reason)}")
222231

223-
GenServer.cast(
232+
GenServer.call(state.processes_pid, :sync)
233+
234+
GenServer.call(
224235
state.members_pid,
225236
{:operation, {:remove, [state.node_id]}}
226237
)

apps/tanx_web/assets/js/arena/animate.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import ArenaRender from "js/arena/render"
33

44
const NUM_TIMESTAMPS = 10;
55
const INITIAL_BUFFER_LEN = 2;
6-
const MAX_BUFFER_LEN = 6;
7-
const TARGET_FPS_LO = 30;
8-
const TARGET_FPS_HI = 50;
6+
const MAX_BUFFER_LEN = 3;
7+
const TARGET_FPS_LO = 20;
8+
const TARGET_FPS_HI = 40;
99
const MEASUREMENT_INTERVAL = 2000;
1010

1111

apps/tanx_web/assets/js/lobby.js

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
const JOIN_RETRY_INTERVAL = 100;
1+
const JOIN_RETRY_INTERVAL = 200;
22
const JOIN_RETRY_COUNT = 10;
3+
const REJOIN_RETRY_COUNT = 20;
34

45

56
class Lobby {
@@ -14,10 +15,15 @@ class Lobby {
1415
this._leaveCallbacks = [];
1516
this._rejoinCallbacks = [];
1617
this._gameInfo = {};
18+
this._rejoinRetries = REJOIN_RETRY_COUNT;
1719

1820
this._setupControls();
1921

2022
this._setupGameList();
23+
24+
$(window).on('beforeunload', () => {
25+
this.leave();
26+
});
2127
}
2228

2329

@@ -44,6 +50,7 @@ class Lobby {
4450
this._leaveCallbacks.forEach(callback => {
4551
callback(gameId, gameChannel);
4652
});
53+
gameChannel.push('leave', {});
4754
gameChannel.leave();
4855
}
4956

@@ -101,8 +108,6 @@ class Lobby {
101108
event.stopPropagation();
102109
});
103110

104-
105-
106111
this.leave();
107112
}
108113

@@ -165,47 +170,61 @@ class Lobby {
165170
let playerName = $('#tanx-name-field').val();
166171
let gameChannel = this._socket.channel("game:" + gameId, {name: playerName});
167172
gameChannel.onError(reason => {
168-
console.log("received error on game channel");
169-
this._gameChannel = null;
173+
console.log("Received error on game channel");
174+
//this._gameChannel = null;
170175
});
171176

172177
let gameJoiner = gameChannel.join();
173178
gameJoiner.receive("ok", reply => {
174179
this._joinPayload = gameJoiner.payload;
175180
this._gameChannel = gameChannel;
176181
if (this._gameId == null) {
177-
gameJoiner.payload.id = reply.i;
178-
this._finishJoin(gameId);
182+
this._joinPayload.id = reply.i;
183+
this._finishJoin(reply.g);
179184
} else {
180-
this._finishRejoin();
185+
this._finishRejoin(reply.g);
181186
}
187+
this._rejoinRetries = REJOIN_RETRY_COUNT;
182188
});
183189
gameJoiner.receive("error", reply => {
184190
if (this._gameId == null) {
191+
console.log("Error on join");
192+
gameChannel.leave();
185193
window.setTimeout(() => {
186194
this._joinGameWithRetry(gameId, remaining - 1);
187195
}, JOIN_RETRY_INTERVAL);
196+
} else {
197+
console.log("Error on rejoin");
198+
this._rejoinRetries--;
199+
if (reply.e == "player_not_found") {
200+
console.log("Leaving due to player not found");
201+
this.leave();
202+
} else if (this._rejoinRetries <= 0) {
203+
console.log("Leaving due to too many failed rejoins");
204+
this.leave();
205+
}
188206
}
189207
});
190208
}
191209

192210

193-
_finishJoin(gameId) {
194-
let game = this._gameInfo[gameId];
211+
_finishJoin(game) {
212+
console.log("Joining game channel for game " + game.i);
195213
$('#game-name-span').text(game.n || "(untitled game)");
196214
$('#game-node-span').text(game.d);
197215

198216
$('#tanx-game-list').hide();
199217
$('#tanx-game-info').show();
200218

201-
this._gameId = gameId;
219+
this._gameId = game.i;
202220
this._joinCallbacks.forEach(callback => {
203-
callback(gameId, this._gameChannel);
221+
callback(game.i, this._gameChannel);
204222
});
205223
}
206224

207225

208-
_finishRejoin() {
226+
_finishRejoin(game) {
227+
console.log("Rejoining game channel for game " + game.i);
209228
this._rejoinCallbacks.forEach(callback => {
210229
callback(this._gameId, this._gameChannel);
211230
});

0 commit comments

Comments
 (0)