Skip to content
This repository has been archived by the owner on Dec 26, 2022. It is now read-only.

🐛 gateway no longer starts multiple instances #354

Merged
merged 6 commits into from
Jan 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pincer/core/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class GatewayDispatch:
def __init__(
self,
op: int,
data: Optional[Union[int, Dict[str, Any]]] = None,
data: Optional[Union[int, bool, Dict[str, Any]]] = None,
seq: Optional[int] = None,
name: Optional[str] = None
):
self.op: int = op
self.data: Optional[Union[int, Dict[str, Any]]] = data
self.data: Optional[Union[int, bool, Dict[str, Any]]] = data
self.seq: Optional[int] = seq
self.event_name: Optional[str] = name

Expand Down
36 changes: 20 additions & 16 deletions pincer/core/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def __init__(
}

# 4000 and 4009 are not included. The client will reconnect when receiving
# either.
# either. Code 4000 is also used for internal disconnects that will lead to a
# reconnect.
self.__close_codes: Dict[int, GatewayError] = {
4001: GatewayError("Invalid opcode was sent"),
4002: GatewayError("Invalid payload was sent."),
Expand Down Expand Up @@ -140,7 +141,7 @@ def __init__(

# The gateway can be disconnected from Discord. This variable stores if the
# gateway should send a hello or reconnect.
self.__should_reconnect: bool = False
self.__should_resume: bool = False

# The sequence number for the last received payload. This is used reconnecting.
self.__sequence_number: int = 0
Expand Down Expand Up @@ -258,8 +259,8 @@ async def event_loop(self):
"%s Disconnected from Gateway due without any errors. Reconnecting.",
self.shard_key
)
self.__should_reconnect = True
await self.start_loop()
# ensure_future prevents a stack overflow
ensure_future(self.start_loop())

async def handle_data(self, data: Dict[Any]):
"""|coro|
Expand Down Expand Up @@ -310,19 +311,25 @@ async def handle_reconnect(self, payload: GatewayDispatch):
self.shard_key
)

self.__should_resume = True
await self.__socket.close()
self.__should_reconnect = True
await self.start_loop()

async def handle_invalid_session(self, payload: GatewayDispatch):
"""|coro|
Opcode 9 - Invalid connection
Attempt to relog. This is probably because the session was already invalidated
when we tried to reconnect.
"""
_log.debug("%s Invalid session, attempting to relog...", self.shard_key)
self.__should_reconnect = False
await self.start_loop()

_log.debug(
"%s Invalid session, attempting to %s...",
self.shard_key,
"reconnect" if payload.data else "relog"
)

self.__should_resume = payload.data
Lunarmagpie marked this conversation as resolved.
Show resolved Hide resolved
self.stop_heartbeat()
await self.__socket.close()

async def identify_and_handle_hello(self, payload: GatewayDispatch):
"""|coro|
Expand All @@ -334,7 +341,7 @@ async def identify_and_handle_hello(self, payload: GatewayDispatch):

Successful reconnects are handled in the `resumed` middleware.
"""
if self.__should_reconnect:
if self.__should_resume:
_log.debug("%s Resuming connection with Discord", self.shard_key)

await self.send(str(GatewayDispatch(
Expand Down Expand Up @@ -363,8 +370,6 @@ async def identify_and_handle_hello(self, payload: GatewayDispatch):
))
self.__heartbeat_interval = payload.data["heartbeat_interval"]

# This process should already be forked to the background so there is no need to
# `ensure_future()` here.
self.start_heartbeat()

async def handle_heartbeat(self, payload: GatewayDispatch):
Expand Down Expand Up @@ -452,14 +457,13 @@ async def __heartbeat_loop(self):
# Close code is specified to be anything that is not 1000 in the docs.
_log.debug(
"%s %s ack not received. Attempting to reconnect."
" Closing socket with close code 1001. \U0001f480",
" Closing socket with close code 4000. \U0001f480",
datetime.now(),
self.shard_key
)
await self.__socket.close(code=1001)
self.__should_reconnect = True
await self.__socket.close(code=4000)
self.__should_resume = True
# A new loop is started in the background while this one is stopped.
ensure_future(self.start_loop())
self.stop_heartbeat()
return

Expand Down