home · contact · privacy
Remembered why the Client connecting had been a thread in the first place …
authorChristian Heller <c.heller@plomlompom.de>
Thu, 18 Sep 2025 06:15:39 +0000 (08:15 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 18 Sep 2025 06:15:39 +0000 (08:15 +0200)
ircplom/client.py

index 3e2c9469eb63310c4ea7ee6e6e7aa93b1d15dc03..224ccdbb30cf41d13ef68a28881508b2ed2ae07e 100644 (file)
@@ -5,10 +5,12 @@ from base64 import b64encode
 from dataclasses import dataclass, InitVar
 from enum import Enum, auto
 from getpass import getuser
+from threading import Thread
 from typing import (Any, Callable, Collection, Generic, Iterable, Iterator,
                     Optional, Self, Set, TypeVar)
 # ourselves
-from ircplom.events import AffectiveEvent, QueueMixin
+from ircplom.events import (
+    AffectiveEvent, CrashingException, ExceptionEvent, QueueMixin)
 from ircplom.irc_conn import (
     BaseIrcConnection, IrcConnAbortException, IrcMessage,
     ILLEGAL_NICK_CHARS, ILLEGAL_NICK_FIRSTCHARS, ISUPPORT_DEFAULTS, PORT_SSL)
@@ -768,18 +770,25 @@ class Client(ABC, ClientQueueMixin):
     def connect(self) -> None:
         'Attempt to open connection, on success perform session init steps.'
         self.db.connection_state = 'connecting'
-        try:
-            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:
-            self.db.connection_state = f'failed to connect: {e}'
-            return
-        self.db.connection_state = 'connected'
-        self.caps.start_negotation()
-        self.send('USER', self.db.user_wanted,
-                  '0', '*', self.db.realname)
-        self.send('NICK', self.db.nick_wanted,)
+
+        def connect(self) -> None:
+            try:
+                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:
+                self.db.connection_state = f'failed to connect: {e}'
+            except Exception as e:  # pylint: disable=broad-exception-caught
+                self._put(ExceptionEvent(CrashingException(e)))
+            else:
+                self.db.connection_state = 'connected'
+                self.caps.start_negotation()
+                self.send('USER', self.db.user_wanted,
+                          '0', '*', self.db.realname)
+                self.send('NICK', self.db.nick_wanted,)
+
+        # Do this in a thread, not to block flow of other (e.g. TUI) events.
+        Thread(target=connect, daemon=True, args=(self,)).start()
 
     def close(self) -> None:
         'Close connection and wipe memory of its states.'