from __future__ import annotations import os import fcntl from typing import Optional _LOCK_FD: Optional[int] = None # keep fd open for process lifetime def should_start_scheduler() -> bool: """Return True in exactly one process (the scheduler owner). Under gunicorn --workers N, code is imported in N processes. If APScheduler starts at import time, you get N schedulers => NĂ— API calls. We prevent that by taking a non-blocking exclusive lock on a lockfile. """ global _LOCK_FD if _LOCK_FD is not None: return True lock_path = os.environ.get("LAIR_SCHED_LOCK", "/tmp/lair-scheduler.lock") fd = os.open(lock_path, os.O_CREAT | os.O_RDWR, 0o644) try: fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) _LOCK_FD = fd return True except BlockingIOError: os.close(fd) return False except Exception: try: os.close(fd) finally: return False