import logging from datetime import datetime from threading import Event, Thread import pytz from core.data_store import DATA_STORE class CleanupTimer: """Provides a timed cleanup of the spot list.""" def __init__(self): """Constructor""" self._cleanup_interval = None self.last_cleanup_time = datetime.min.replace(tzinfo=pytz.UTC) self.status = "Starting" self._thread = None self._stop_event = Event() def setup(self, cleanup_interval): self._cleanup_interval = cleanup_interval def start(self): """Start the cleanup timer""" self._thread = Thread(target=self._run, daemon=True) self._thread.start() def stop(self): """Stop any threads and prepare for application shutdown""" self._stop_event.set() def _run(self): while not self._stop_event.wait(timeout=self._cleanup_interval): self._cleanup() def _cleanup(self): """Perform cleanup and reschedule next timer""" try: for i in list(DATA_STORE.spots.keys()): try: spot = DATA_STORE.spots[i] if spot.expired(): DATA_STORE.spots.delete(i) except KeyError: # Must have already been deleted, OK with that pass for i in list(DATA_STORE.alerts.keys()): try: alert = DATA_STORE.alerts[i] if alert.expired(): DATA_STORE.alerts.delete(i) except KeyError: # Must have already been deleted, OK with that pass self.status = "OK" self.last_cleanup_time = datetime.now(pytz.UTC) except Exception: self.status = "Error" logging.exception("Exception in Cleanup thread") self._stop_event.wait(timeout=1) # Global object CLEANUP_TIMER = CleanupTimer()