home · contact · privacy
Also start exponentially delayed connection retry on connecting timeout.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 2 Oct 2025 18:21:21 +0000 (20:21 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 2 Oct 2025 18:21:21 +0000 (20:21 +0200)
src/ircplom/client.py
src/ircplom/irc_conn.py

index bf8c28b763c753e415e9f97c683344f3d8c5dc0f..2714cccd4d50d71d65227edfd2ddbd344ed53b96 100644 (file)
@@ -820,7 +820,7 @@ class Client(ABC, ClientQueueMixin):
     conn: Optional[IrcConnection] = None
     _cls_conn: type[IrcConnection] = IrcConnection
     _expected_pong: str
-    _retry_connect_in_s: int
+    _retry_connect_in_s: int = -1
     _retry_connect_id: Optional[UUID] = None
 
     def __init__(self, conn_setup: IrcConnSetup, channels: set[str], **kwargs
@@ -849,8 +849,12 @@ class Client(ABC, ClientQueueMixin):
                 self.conn = self._cls_conn(
                     hostname=self.db.hostname, port=self.db.port,
                     _q_out=self._q_out, client_id=self.client_id)
-            except IrcConnAbortException as e:
+            except IrcConnException as e:
                 self.db.connection_state = f'failed to connect: {e}'
+                if isinstance(e, IrcConnTimeoutException):
+                    if not self._retry_connect_in_s > 0:
+                        self._retry_connect_in_s = 1
+                    self._client_trigger('_delayed_retry_connect')
             except Exception as e:  # pylint: disable=broad-exception-caught
                 self._put(ExceptionEvent(CrashingException(e)))
             else:
@@ -865,6 +869,21 @@ class Client(ABC, ClientQueueMixin):
         # Do this in a thread, not to block flow of other (e.g. TUI) events.
         Thread(target=connect, daemon=True, args=(self,)).start()
 
+    def _delayed_retry_connect(self) -> None:
+        def delayed_connect(self, wait_s: int, retry_connect_id: UUID
+                            ) -> None:
+            sleep(wait_s)
+            if self._retry_connect_id == retry_connect_id:
+                self._client_trigger('connect')
+
+        self._retry_connect_id = uuid4()
+        self._alert(
+                f'will retry connecting in {self._retry_connect_in_s} seconds')
+        Thread(target=delayed_connect, daemon=True,
+               args=(self, self._retry_connect_in_s, self._retry_connect_id)
+               ).start()
+        self._retry_connect_in_s *= 2
+
     def close(self) -> None:
         'Close connection, wipe memory of its states, reconnect if indicated.'
         if not self._autojoins:
@@ -875,20 +894,7 @@ class Client(ABC, ClientQueueMixin):
             self.conn.close()
         self.conn = None
         if self._retry_connect_in_s > 0:
-            def delayed_connect(self, wait_s: int, retry_connect_id: UUID
-                                ) -> None:
-                sleep(wait_s)
-                if self._retry_connect_id == retry_connect_id:
-                    self._client_trigger('connect')
-
-            self._retry_connect_id = uuid4()
-            self._alert(
-                f'will retry connecting in {self._retry_connect_in_s} seconds')
-            Thread(target=delayed_connect, daemon=True,
-                   args=(self, self._retry_connect_in_s,
-                         self._retry_connect_id)
-                   ).start()
-            self._retry_connect_in_s *= 2
+            self._delayed_retry_connect()
 
     def on_handled_loop_exception(self, e: IrcConnException) -> None:
         'On …AbortException, call .close(), on …Timeout… first (!) try PING.'
index e7f7010b3062f2697d4bef641775619bd584b352..2605e9474ee3a68d793131cd0110640fdf636e4a 100644 (file)
@@ -159,7 +159,9 @@ class BaseIrcConnection(QueueMixin, ABC):
         self._socket.settimeout(_TIMEOUT_CONNECT)
         try:
             self._socket.connect((hostname, port))
-        except (TimeoutError, socket_gaierror) as e:
+        except TimeoutError as e:
+            raise IrcConnTimeoutException(e) from e
+        except socket_gaierror as e:
             raise IrcConnAbortException(e) from e
         self._socket.settimeout(_TIMEOUT_RECV_LOOP)