Skip to content

Commit 88961b1

Browse files
authored
Merge pull request #503 from Kraigie/gateway-state-machine
Convert shard sessions into state machines
2 parents a75914b + 0b66b26 commit 88961b1

File tree

5 files changed

+252
-127
lines changed

5 files changed

+252
-127
lines changed

Diff for: appup.ex

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
# Upgrade instructions
77
{'0.9.0-alpha1',
88
[
9-
{:load_module, Nostrum.Cache.GuildCache}
9+
# Top shard supervisor was not registered, so could not restart shard
10+
# supervisor to load new gateway logic
11+
{:restart_application, :nostrum}
1012
]},
1113
{'0.8.0',
1214
[
@@ -17,7 +19,7 @@
1719
# Downgrade instructions
1820
{'0.9.0-alpha1',
1921
[
20-
{:load_module, Nostrum.Cache.GuildCache}
22+
{:restart_application, :nostrum}
2123
]},
2224
{'0.8.0',
2325
[

Diff for: lib/nostrum/application.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ defmodule Nostrum.Application do
3636

3737
if Application.get_env(:nostrum, :dev),
3838
do: Supervisor.start_link(children ++ [DummySupervisor], strategy: :one_for_one),
39-
else: Supervisor.start_link(children, strategy: :one_for_one)
39+
else: Supervisor.start_link(children, strategy: :one_for_one, name: Nostrum.Supervisor)
4040
end
4141

4242
defp check_executables do

Diff for: lib/nostrum/shard/event.ex

+14-14
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,42 @@ defmodule Nostrum.Shard.Event do
2020

2121
if payload.t == :READY do
2222
Logger.info("READY")
23-
%{state | session: payload.d.session_id}
23+
24+
{%{state | session: payload.d.session_id, resume_gateway: payload.d.resume_gateway_url}, []}
2425
else
25-
state
26+
{state, []}
2627
end
2728
end
2829

2930
def handle(:heartbeat, _payload, state) do
3031
Logger.debug("HEARTBEAT PING")
31-
{state, Payload.heartbeat_payload(state.seq)}
32+
{{state, Payload.heartbeat_payload(state.seq)}, []}
3233
end
3334

3435
def handle(:heartbeat_ack, _payload, state) do
3536
Logger.debug("HEARTBEAT_ACK")
36-
%{state | last_heartbeat_ack: DateTime.utc_now(), heartbeat_ack: true}
37+
{%{state | last_heartbeat_ack: DateTime.utc_now(), heartbeat_ack: true}, []}
3738
end
3839

39-
def handle(:hello, payload, state) do
40-
state = %{
41-
state
42-
| heartbeat_interval: payload.d.heartbeat_interval
43-
}
44-
45-
GenServer.cast(state.conn_pid, :heartbeat)
40+
def handle(:hello, payload, old_state) do
41+
state = Map.put(old_state, :heartbeat_interval, payload.d.heartbeat_interval)
42+
# Jitter it as documented. But only for Hello - the subsequent timeouts
43+
# must not jitter it anymore, but send out at this interval.
44+
heartbeat_next = :rand.uniform(state.heartbeat_interval)
45+
heartbeat_action = {:state_timeout, heartbeat_next, :send_heartbeat}
4646

4747
if session_exists?(state) do
4848
Logger.info("RESUMING")
49-
{state, Payload.resume_payload(state)}
49+
{{state, Payload.resume_payload(state)}, heartbeat_action}
5050
else
5151
Logger.info("IDENTIFYING")
52-
{state, Payload.identity_payload(state)}
52+
{{state, Payload.identity_payload(state)}, heartbeat_action}
5353
end
5454
end
5555

5656
def handle(:invalid_session, _payload, state) do
5757
Logger.info("INVALID_SESSION")
58-
{state, Payload.identity_payload(state)}
58+
{{state, Payload.identity_payload(state)}, []}
5959
end
6060

6161
def handle(:reconnect, _payload, state) do

0 commit comments

Comments
 (0)