from __future__ import annotations import threading import time import traceback from .enforcement import ( enforce_all_users, ) class Scheduler: def __init__( self, interval_seconds: float = 1.0, ): self.interval_seconds = max( 0.1, float( interval_seconds ), ) self._stop_event = ( threading.Event() ) self._thread = None def start(self): if ( self._thread is not None and self._thread.is_alive() ): return self._stop_event.clear() self._thread = threading.Thread( target=self._run, name="parental-control-scheduler", daemon=True, ) self._thread.start() def stop(self): self._stop_event.set() if self._thread is not None: self._thread.join( timeout=3 ) self._thread = None def run_once(self): return enforce_all_users() def _run(self): while not self._stop_event.is_set(): started = time.monotonic() try: self.run_once() except Exception: traceback.print_exc() elapsed = ( time.monotonic() - started ) remaining = max( 0.0, self.interval_seconds - elapsed, ) self._stop_event.wait( remaining ) _scheduler = Scheduler( interval_seconds=1.0 ) def start_scheduler(): _scheduler.start() def stop_scheduler(): _scheduler.stop() def run_scheduler_once(): return _scheduler.run_once()