home · contact · privacy
Auto-reconnect on during-connection timeout.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 1 Oct 2025 08:46:22 +0000 (10:46 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 1 Oct 2025 08:46:22 +0000 (10:46 +0200)
src/ircplom/client.py
src/tests/pingpong.txt

index ed522194d96865fbfa797efeb5322ae4971d6e62..b27f72fa77082e739c1e91114df800c51ebe1664 100644 (file)
@@ -818,6 +818,7 @@ class Client(ABC, ClientQueueMixin):
     conn: Optional[IrcConnection] = None
     _cls_conn: type[IrcConnection] = IrcConnection
     _expected_pong: str
+    _retry_in_s: int
 
     def __init__(self, conn_setup: IrcConnSetup, channels: set[str], **kwargs
                  ) -> None:
@@ -850,6 +851,7 @@ class Client(ABC, ClientQueueMixin):
                 self._put(ExceptionEvent(CrashingException(e)))
             else:
                 self._expected_pong = ''
+                self._retry_in_s = -1
                 self.db.connection_state = 'connected'
                 self.caps.start_negotation()
                 self.send('USER', self.db.user_wanted,
@@ -860,7 +862,7 @@ class Client(ABC, ClientQueueMixin):
         Thread(target=connect, daemon=True, args=(self,)).start()
 
     def close(self) -> None:
-        'Close connection and wipe memory of its states.'
+        'Close connection, wipe memory of its states, reconnect if indicated.'
         if not self._autojoins:
             for name in self.db.channels.keys():
                 self._autojoins.add(name)
@@ -868,6 +870,9 @@ class Client(ABC, ClientQueueMixin):
         if self.conn:
             self.conn.close()
         self.conn = None
+        if self._retry_in_s > 0:
+            self._retry_in_s *= 2
+            self.connect()
 
     def on_handled_loop_exception(self, e: IrcConnException) -> None:
         'On …AbortException, call .close(), on …Timeout… first (!) try PING.'
@@ -876,6 +881,7 @@ class Client(ABC, ClientQueueMixin):
             self.close()
         elif isinstance(e, IrcConnTimeoutException):
             if self._expected_pong:
+                self._retry_in_s = 1
                 self.on_handled_loop_exception(
                         IrcConnAbortException('no timely PONG from server'))
             else:
index 6f554688904549385f9bb414f46922141d4f5252..1811cd45f9ca0b7ee929f40786c9e31e7e892616 100644 (file)
@@ -50,13 +50,16 @@ repeat isupport-clear-in isupport-clear-out
 2 .$ DISCONNECTED
 | full-timeout-out
 
-# on re-connect, ensure timer cleared, so won't trigger already on 1st timeout
-> /window 1
-> /reconnect
+# on (automatic!) re-connect, ensure timer cleared, so won't trigger already on 1st timeout
+| conn2-in
 repeat conn0-in conn0-out
 2 .$ CONNECTED
 repeat conn1-in conn1-out
+| conn2-out
 repeat full-timeout-in full-timeout-out
 
+# after proof that a full double-timeout was necessary, we again automatically re-connect before our /quit gets processed …
+repeat conn2-in conn2-out
+
 > /quit
 0 .<