Skip to content

Commit

Permalink
Merge pull request #503 from Kraigie/gateway-state-machine
Browse files Browse the repository at this point in the history
Convert shard sessions into state machines
  • Loading branch information
jchristgit authored Jun 9, 2023
2 parents a75914b + 0b66b26 commit 88961b1
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 127 deletions.
6 changes: 4 additions & 2 deletions appup.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
# Upgrade instructions
{'0.9.0-alpha1',
[
{:load_module, Nostrum.Cache.GuildCache}
# Top shard supervisor was not registered, so could not restart shard
# supervisor to load new gateway logic
{:restart_application, :nostrum}
]},
{'0.8.0',
[
Expand All @@ -17,7 +19,7 @@
# Downgrade instructions
{'0.9.0-alpha1',
[
{:load_module, Nostrum.Cache.GuildCache}
{:restart_application, :nostrum}
]},
{'0.8.0',
[
Expand Down
2 changes: 1 addition & 1 deletion lib/nostrum/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ defmodule Nostrum.Application do

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

defp check_executables do
Expand Down
28 changes: 14 additions & 14 deletions lib/nostrum/shard/event.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,42 @@ defmodule Nostrum.Shard.Event do

if payload.t == :READY do
Logger.info("READY")
%{state | session: payload.d.session_id}

{%{state | session: payload.d.session_id, resume_gateway: payload.d.resume_gateway_url}, []}
else
state
{state, []}
end
end

def handle(:heartbeat, _payload, state) do
Logger.debug("HEARTBEAT PING")
{state, Payload.heartbeat_payload(state.seq)}
{{state, Payload.heartbeat_payload(state.seq)}, []}
end

def handle(:heartbeat_ack, _payload, state) do
Logger.debug("HEARTBEAT_ACK")
%{state | last_heartbeat_ack: DateTime.utc_now(), heartbeat_ack: true}
{%{state | last_heartbeat_ack: DateTime.utc_now(), heartbeat_ack: true}, []}
end

def handle(:hello, payload, state) do
state = %{
state
| heartbeat_interval: payload.d.heartbeat_interval
}

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

if session_exists?(state) do
Logger.info("RESUMING")
{state, Payload.resume_payload(state)}
{{state, Payload.resume_payload(state)}, heartbeat_action}
else
Logger.info("IDENTIFYING")
{state, Payload.identity_payload(state)}
{{state, Payload.identity_payload(state)}, heartbeat_action}
end
end

def handle(:invalid_session, _payload, state) do
Logger.info("INVALID_SESSION")
{state, Payload.identity_payload(state)}
{{state, Payload.identity_payload(state)}, []}
end

def handle(:reconnect, _payload, state) do
Expand Down
Loading

0 comments on commit 88961b1

Please sign in to comment.