Browse Source

Proper quitting on SIGINT

master
JustAnotherArchivist 3 years ago
parent
commit
8d55780e76
1 changed files with 20 additions and 11 deletions
  1. +20
    -11
      irclog.py

+ 20
- 11
irclog.py View File

@@ -314,13 +314,18 @@ class IRCClientProtocol(asyncio.Protocol):
# Queue message for storage
sendGeneral = True
if line.command in ('QUIT', 'NICK') and line.source:
try:
user = self.server.users[line.hostmask.nickname]
except KeyError:
pass
else:
if line.hostmask.nickname == self.server.nickname:
# Self-quit
sendGeneral = False
self.messageQueue.put_nowait((time_, b'< ' + message, user.channels))
self.messageQueue.put_nowait((time_, b'< ' + message, list(self.channels) + ['general']))
else:
try:
user = self.server.users[line.hostmask.nickname]
except KeyError:
pass
else:
sendGeneral = False
self.messageQueue.put_nowait((time_, b'< ' + message, user.channels))
if sendGeneral:
self.messageQueue.put_nowait((time_, b'< ' + message, None))

@@ -376,13 +381,17 @@ class IRCClientProtocol(asyncio.Protocol):
return
self._send_join_part(b'JOIN', self.channels)

# General fatal ERROR
elif line.command == 'ERROR':
self.logger.error(f'Server sent ERROR: {message!r}')
self.transport.close()

async def quit(self):
# It appears to be hard to impossible to send a clean quit, wait for it to be actually sent, and only then close the transport.
# This is because asyncio.sslproto.SSLTransport doesn't support explicit draining nor waiting for an empty write queue nor write_eof.
# So instead, just close the transport and wait until connection_lost is triggered (which also puts a message in the logs).
# The server acknowledges a QUIT by sending an ERROR and closing the connection. The latter triggers connection_lost, so just wait for the closure event.
self.logger.info('Quitting')
self.transport.close()
self.send(b'QUIT :Bye')
await self.connectionClosedEvent.wait()
self.transport.close()

def connection_lost(self, exc):
time_ = time.time()
@@ -673,7 +682,7 @@ async def main():
messageQueue = asyncio.Queue()
# tuple(time: float, message: bytes or None, channels: list[str] or None)
# message = None indicates a connection loss
# channels = None indicates that IRCClientProtocol did not identify which channels are affected; it is only not None for QUIT or NICK messages.
# channels = None indicates that IRCClientProtocol did not identify which channels are affected; it is a set or list of channel names for QUIT or NICK messages and the connection closed message.

irc = IRCClient(messageQueue, config)
webserver = WebServer(config)


Loading…
Cancel
Save