From d50de12834bcb192daf3a3aa25835a5bb0af3662 Mon Sep 17 00:00:00 2001 From: James Lu Date: Tue, 29 Sep 2020 17:43:38 +0000 Subject: [PATCH] Retry when socket.send() fails with BlockingIOError / EAGAIN --- classes.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/classes.py b/classes.py index c8e6a7d..a24b38a 100644 --- a/classes.py +++ b/classes.py @@ -2091,11 +2091,22 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils): log.debug("(%s) -> %s", self.name, data) - try: - self._socket.send(encoded_data) - except: - log.exception("(%s) Failed to send message %r; aborting!", self.name, data) - self.disconnect() + while True: + try: + self._socket.send(encoded_data) + except (BlockingIOError, ssl.SSLWantReadError, ssl.SSLWantWriteError): + # The send attempt failed, wait a little bit. + # I would prefer using a blocking socket and MSG_DONTWAIT in recv()'s flags + # but SSLSocket doesn't support that... + throttle_time = self.serverdata.get('throttle_time', 0) + if self._aborted.wait(throttle_time): + break + continue + except: + log.exception("(%s) Failed to send message %r; aborting!", self.name, data) + self.disconnect() + else: + break def send(self, data, queue=True): """send() wrapper with optional queueing support."""