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!