0

I am fetching data from a websocket using a script which contains the following code inside a class:


from websocket import WebSocketApp # library: websocket-client

class WebsocketManager:

    _CONNECT_TIMEOUT_S = 5

    # some code here
    # ...

    def _connect(self):
        assert not self.ws, "ws should be closed before attempting to connect"

        self.ws = WebSocketApp(
            self.url,
            on_message=self._wrap_callback(self._on_message),
            on_close=self._wrap_callback(self._on_close),
            on_error=self._wrap_callback(self._on_error),
        )

        wst = Thread(target=self._run_websocket, args=(self.ws,))
        wst.daemon = False # True
        wst.start()

        # Wait for socket to connect
        ts = time.time()
        while self.ws and (not self.ws.sock or not self.ws.sock.connected):
            if time.time() - ts > self._CONNECT_TIMEOUT_S:
                self.ws = None
                return
            time.sleep(0.1)

    def _on_message(self, ws, message):
        self.process_message(message)
        return

    def _run_websocket(self, ws):
        try:
            ws.run_forever()
        except Exception as e:
            raise Exception(f'Unexpected error while running websocket: {e}')
        finally:
            self._reconnect(ws)

I am just listing the (I think) relevant methods here. Inside the function self.process_message(), I tried printing the message. When I had wst.daemon=True, this led to the script regularly stopping after a short time with the following exit:

Fatal Python error: _enter_buffered_busy: could not acquire lock for <_io.BufferedWriter name='<stdout>'> at interpreter shutdown, possibly due to daemon threads

This message led me to set wst.daemon = False and suddenly the script works fine. From another post, I read that daemonized threads are threads that are automatically turned off once other non-daemon threads have exited (Daemon Threads Explanation). From yet another post, I found that often daemonized threads cause issues when trying to print stuff during the execution of the script (How to fix a 'fatal Python error: _enter_buffered_busy: could not aquire lock for <_io.BufferedWriter name='<stdout>'> at interpreter shutdown' error?).

However, I am obviously not 100% comfortable with threads, so I am wondering whether just setting wst.daemon=False could have any bad effects, such as my PC using excessive resources to run this code in the background, or the script regularly crashing after longer times (so far I am running it for 20mins uninterrupted). Do I have to insert extra code to shutdown the now non-daemonized threads after they have finished?

Thanks!

user101893
  • 129
  • 11

0 Answers0