Fix API calls by all workers
Quite a complex commit by GPT. I'll rewrite it somewhen
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
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
|
||||
Reference in New Issue
Block a user