import logging from datetime import datetime, timedelta from threading import Timer from time import sleep import pytz # Provides a timed cleanup of the spot list. class CleanupTimer: # Constructor def __init__(self, spots, alerts, cleanup_interval): self.spots = spots self.alerts = alerts self.cleanup_interval = cleanup_interval self.cleanup_timer = None self.last_cleanup_time = datetime.min.replace(tzinfo=pytz.UTC) self.status = "Starting" # Start the cleanup timer def start(self): self.cleanup() # Stop any threads and prepare for application shutdown def stop(self): self.cleanup_timer.cancel() # Perform cleanup and reschedule next timer def cleanup(self): try: # Perform cleanup self.spots.expire() self.alerts.expire() # Alerts can persist in the system for a while, so we want to explicitly clean up any alerts that have # expired for id in list(self.alerts.iterkeys()): alert = self.alerts[id] if alert.expired(): self.alerts.evict(id) self.status = "OK" self.last_cleanup_time = datetime.now(pytz.UTC) except Exception as e: self.status = "Error" logging.exception("Exception in Cleanup thread") sleep(1) self.cleanup_timer = Timer(self.cleanup_interval, self.cleanup) self.cleanup_timer.start()