From 17eac90a47ed9735a06c84d544abd32e306e3e90 Mon Sep 17 00:00:00 2001 From: JustAnotherArchivist Date: Sun, 11 Oct 2020 18:07:52 +0000 Subject: [PATCH] Bypass send queue for PONG and QUIT, and disable processing it at all after the latter --- irclog.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/irclog.py b/irclog.py index 92b11d2..02363ca 100644 --- a/irclog.py +++ b/irclog.py @@ -13,6 +13,7 @@ import ircstates import irctokens import itertools import logging +import math import os.path import signal import ssl @@ -323,6 +324,13 @@ class IRCClientProtocol(asyncio.Protocol): raise RuntimeError(f'IRC message too long ({len(data)} > 510): {data!r}') self.sendQueue.put_nowait(data) + def _direct_send(self, data): + self.logger.debug(f'Send: {data!r}') + time_ = time.time() + self.transport.write(data + b'\r\n') + self.messageQueue.put_nowait((time_, b'> ' + data, None, None)) + return time_ + async def send_queue(self): while True: self.logger.debug(f'Trying to get data from send queue') @@ -339,10 +347,7 @@ class IRCClientProtocol(asyncio.Protocol): await asyncio.wait({self.connectionClosedEvent.wait()}, timeout = self.lastSentTime + 1 - now) if self.connectionClosedEvent.is_set(): break - self.logger.debug(f'Send: {data!r}') - time_ = time.time() - self.transport.write(data + b'\r\n') - self.messageQueue.put_nowait((time_, b'> ' + data, None, None)) + time_ = self._direct_send(data) if self.lastSentTime is not None: self.lastSentTime = time_ @@ -374,7 +379,7 @@ class IRCClientProtocol(asyncio.Protocol): maybeTriggerWhox = False # PING/PONG if line.command == 'PING': - self.send(irctokens.build('PONG', line.params).format().encode('utf-8')) + self._direct_send(irctokens.build('PONG', line.params).format().encode('utf-8')) # IRCv3 and SASL elif line.command == 'CAP': @@ -552,7 +557,8 @@ class IRCClientProtocol(asyncio.Protocol): async def quit(self): # 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.send(b'QUIT :Bye') + self.lastSentTime = 1.67e34 * math.pi * 1e7 # Disable sending any further messages in send_queue + self._direct_send(b'QUIT :Bye') await asyncio.wait({self.connectionClosedEvent.wait()}, timeout = 10) if not self.connectionClosedEvent.is_set(): self.logger.error('Quitting cleanly did not work, closing connection forcefully')