mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-20 14:27:42 +00:00
Use _stop_event consistently across all threads as the way to signal that it should stop. Add thread joins with timeouts to allow the program to exit cleanly
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
from threading import Event, Thread
|
||||
|
||||
import pytz
|
||||
from websocket import create_connection
|
||||
@@ -20,22 +19,24 @@ class WebsocketSpotProvider(SpotProvider):
|
||||
self._url = url
|
||||
self._ws = None
|
||||
self._thread = None
|
||||
self._stopped = False
|
||||
self._stop_event = Event()
|
||||
self._last_event_id = None
|
||||
|
||||
def start(self):
|
||||
logger.info(f"Set up websocket connection to {self.name} spot API.")
|
||||
self._stopped = False
|
||||
self._stop_event.clear()
|
||||
self._thread = Thread(target=self._run, name=f"WebsocketSpotProvider-{self.name}")
|
||||
self._thread.daemon = True
|
||||
self._thread.start()
|
||||
|
||||
def stop(self):
|
||||
self._stopped = True
|
||||
self._stop_event.set()
|
||||
if self._ws:
|
||||
self._ws.close()
|
||||
if self._thread:
|
||||
self._thread.join()
|
||||
self._thread.join(timeout=15)
|
||||
if self._thread.is_alive():
|
||||
logger.warning(f"{self.name} websocket worker thread did not exit on time and will be killed.")
|
||||
|
||||
def _on_open(self):
|
||||
self.status = "Waiting for Data"
|
||||
@@ -44,7 +45,7 @@ class WebsocketSpotProvider(SpotProvider):
|
||||
self.status = "Connecting"
|
||||
|
||||
def _run(self):
|
||||
while not self._stopped:
|
||||
while not self._stop_event.is_set():
|
||||
try:
|
||||
logger.debug(f"Connecting to {self.name} spot API...")
|
||||
self.status = "Connecting"
|
||||
@@ -53,7 +54,7 @@ class WebsocketSpotProvider(SpotProvider):
|
||||
|
||||
# Keep reading from this same connection until it drops or we're asked to stop, rather than
|
||||
# reconnecting for every message.
|
||||
while not self._stopped:
|
||||
while not self._stop_event.is_set():
|
||||
data = self._ws.recv()
|
||||
if not data:
|
||||
break
|
||||
@@ -82,8 +83,8 @@ class WebsocketSpotProvider(SpotProvider):
|
||||
# No problem, we were getting rid of this object anyway.
|
||||
pass
|
||||
self._ws = None
|
||||
if not self._stopped:
|
||||
sleep(5) # Wait before trying to reconnect
|
||||
if not self._stop_event.is_set():
|
||||
self._stop_event.wait(timeout=5) # Wait before trying to reconnect
|
||||
|
||||
def _ws_message_to_spot(self, b):
|
||||
"""Convert a WS message received from the API into a spot. The exact message data (in bytes) is provided here so the
|
||||
|
||||
Reference in New Issue
Block a user