From: Christian Heller <c.heller@plomlompom.de>
Date: Sat, 7 Jun 2025 17:42:09 +0000 (+0200)
Subject: Don't block main loop for duration of connecting attempt.
X-Git-Url: https://plomlompom.com/repos/%22https:/validator.w3.org/blog?a=commitdiff_plain;h=a6d1eb40edd3534ea11a92bd10d72eae3787e117;p=ircplom

Don't block main loop for duration of connecting attempt.
---

diff --git a/ircplom.py b/ircplom.py
index 86c3b6c..62ad515 100755
--- a/ircplom.py
+++ b/ircplom.py
@@ -157,23 +157,27 @@ class IrcConnection:
                  ) -> None:
         self._idx = idx
         self._q_to_main = q_to_main
+        self._login = login
         self._assumed_open = False
         self._recv_loop: Optional[SocketRecvLoop] = None
         self._socket = socket()
         self._socket.settimeout(TIMEOUT_CONNECT)
         self._broadcast('CONNECTION_WINDOW', self._idx)
-        try:
-            self._socket.connect((hostname, PORT))
-        except socket_gaierror as e:
-            self._broadcast('CONN_ALERT', str(e))
-            return
-        self._assumed_open = True
-        self._socket.settimeout(TIMEOUT_LOOP)
-        self._recv_loop = SocketRecvLoop(self._idx, self._q_to_main,
-                                         self._read_lines())
-        self._broadcast('SEND', IrcMessage('USER', [login[0], '0', '*',
-                                                    login[2]]))
-        self._broadcast('SEND', IrcMessage('NICK', [login[1]]))
+
+        def connect(self):
+            self._broadcast('CONN_ALERT', f'Connecting to {hostname} …')
+            try:
+                self._socket.connect((hostname, PORT))
+            except (TimeoutError, socket_gaierror) as e:
+                self._broadcast('CONN_ALERT', str(e))
+                return
+            self._socket.settimeout(TIMEOUT_LOOP)
+            self._assumed_open = True
+            self._broadcast('CONNECTED')
+            self._recv_loop = SocketRecvLoop(self._idx, self._q_to_main,
+                                             self._read_lines())
+
+        Thread(target=connect, args=(self,)).start()
 
     def close(self):
         'Close both SocketRecvLoop and socket.'
@@ -226,6 +230,11 @@ class IrcConnection:
 
     def handle(self, event: Event) -> None:
         'Process connection-directed Event into further steps.'
+        if event.type_ == 'CONNECTED':
+            self._broadcast('SEND', IrcMessage('USER', [self._login[0], '0',
+                                                        '*', self._login[2]]))
+            self._broadcast('SEND', IrcMessage('NICK', [self._login[1]]))
+            return
         msg: IrcMessage = event.payload[1]
         if event.type_ == 'SEND':
             self._write_line(msg.raw)
@@ -795,7 +804,7 @@ def run() -> None:
                 if event.type_ == 'INIT_CONNECTION':
                     connections += [IrcConnection(q_to_main, len(connections),
                                                   *event.payload)]
-                elif event.type_ in {'RECV', 'SEND'}:
+                elif event.type_ in {'CONNECTED', 'RECV', 'SEND'}:
                     connections[event.payload[0]].handle(event)
     finally:
         for conn in connections: