Updated for automatic pushing back - pulling already works via webhook

This commit is contained in:
2026-01-13 20:03:36 +01:00
parent e5ba624aa9
commit 424c20923b
5 changed files with 404 additions and 125 deletions

View File

@@ -10,8 +10,11 @@ loglevel = "info"
logger = logging.getLogger(__name__)
# Track if file watcher has been started
_watcher_started = False
# Track which worker has the file watcher (using a file-based flag)
import os
import tempfile
WATCHER_LOCK_FILE = os.path.join(tempfile.gettempdir(), 'esphome_watcher.lock')
def on_starting(server):
@@ -21,6 +24,14 @@ def on_starting(server):
"""
logger.info("Gunicorn master process starting - initializing git repository")
# Clean up any stale lock file from previous runs
if os.path.exists(WATCHER_LOCK_FILE):
try:
os.remove(WATCHER_LOCK_FILE)
logger.info("Removed stale watcher lock file")
except Exception as e:
logger.warning(f"Could not remove stale lock file: {e}")
# Import here to avoid circular imports
from app import initialize_git_repo
@@ -36,12 +47,15 @@ def post_fork(server, worker):
Called after a worker has been forked.
Start the file watcher only in the first worker to avoid duplicates.
"""
global _watcher_started
# Use a file-based lock to ensure only one worker starts the watcher
# This works across process boundaries unlike global variables
try:
# Try to create the lock file (exclusive creation)
fd = os.open(WATCHER_LOCK_FILE, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
os.write(fd, str(worker.pid).encode())
os.close(fd)
# Only start the file watcher in the first worker (age/number would be 0)
# Check worker.age which is the worker's sequential number
if worker.age == 0 and not _watcher_started:
_watcher_started = True
# This worker won the race, start the file watcher
logger.info(f"Starting file watcher in worker {worker.pid}")
# Import here to avoid circular imports
@@ -54,5 +68,13 @@ def post_fork(server, worker):
logger.info("File watcher started successfully")
except Exception as e:
logger.error(f"Failed to start file watcher: {e}")
else:
# Clean up lock file on failure
try:
os.remove(WATCHER_LOCK_FILE)
except:
pass
except FileExistsError:
# Another worker already started the watcher
logger.info(f"Worker {worker.pid} started (file watcher already running in another worker)")
except Exception as e:
logger.error(f"Error in post_fork for worker {worker.pid}: {e}")