PID_FILE check: make optional

As implied by this comment:

> this implementation is not supposed to be bullet-proof for race conditions (nor is it cross-platform)... it's
> just a small check to prevent the regularly occurring cases:
> * starting a second runsnappea in development
> * running 2 separate instances of bugsink on a single machine without properly distinguishing them

but this "small check" gets in the way sometimes, so it's better to be able to turn it off.

See #99
This commit is contained in:
Klaas van Schelven
2025-07-28 20:46:45 +02:00
parent 530fc7f166
commit 4a73880ea7

View File

@@ -103,6 +103,28 @@ class Foreman:
logger.info("Startup: Can't run Foreman in TASK_ALWAYS_EAGER mode, EXIT")
sys.exit(1)
self.check_pid_file(pid)
logger.info("Startup: pid is %s", pid)
logger.info("Startup: DB-as-MQ location: %s", settings.DATABASES["snappea"]["NAME"])
logger.info("Startup: Wake up calls location: %s", self.settings.WAKEUP_CALLS_DIR)
# Counts the number of "wake up" signals that have not been dealt with yet. The main loop goes to sleep when
# this is 0
self.signal_semaphore = threading.Semaphore(0)
# Counts the number of available worker threads. When this is 0, create_workers will first wait until a worker
# stops. (the value of this semaphore is implicitly NUM_WORKERS - active_workers)
self.worker_semaphore = threading.Semaphore(self.settings.NUM_WORKERS)
def check_pid_file(self, pid):
if self.settings.PID_FILE is None:
# this is useful in setups where the lifecycle of the Foreman is _clearly_ the responsibility of some other
# thing (e.g. systemd), or the whatever is doing container orchestration. In such cases, the PID file is
# only going to get in the way.
logger.warning("Startup: no PID_FILE configured, pid-check disabled")
return
# if the PID_FILE already exists, read it to see whether snappea is already running.
# this implementation is not supposed to be bullet-proof for race conditions (nor is it cross-platform)... it's
# just a small check to prevent the regularly occurring cases:
@@ -126,18 +148,6 @@ class Foreman:
with open(self.settings.PID_FILE, "w") as f:
f.write(str(pid))
logger.info("Startup: pid is %s", pid)
logger.info("Startup: DB-as-MQ location: %s", settings.DATABASES["snappea"]["NAME"])
logger.info("Startup: Wake up calls location: %s", self.settings.WAKEUP_CALLS_DIR)
# Counts the number of "wake up" signals that have not been dealt with yet. The main loop goes to sleep when
# this is 0
self.signal_semaphore = threading.Semaphore(0)
# Counts the number of available worker threads. When this is 0, create_workers will first wait until a worker
# stops. (the value of this semaphore is implicitly NUM_WORKERS - active_workers)
self.worker_semaphore = threading.Semaphore(self.settings.NUM_WORKERS)
def connection_close(self, using="default"):
# (as a method to allow for a single point of documentation)
@@ -416,4 +426,8 @@ class Foreman:
"Stopping: %s did not die in %.1fs, proceeding to kill",
short_id(task_id), self.settings.GRACEFUL_TIMEOUT)
os.remove(self.settings.PID_FILE)
if self.settings.PID_FILE is not None:
logger.info("Stopping: removing PID file %s", self.settings.PID_FILE)
os.remove(self.settings.PID_FILE)
else:
logger.info("Stopping: no PID file to remove")