chore: checkpoint deploy loop updates

This commit is contained in:
Nick Sweeting 2026-05-28 07:15:20 -07:00
parent 66e5e06c7f
commit e15fc42e43
No known key found for this signature in database
3 changed files with 60 additions and 4 deletions

View File

@ -206,12 +206,11 @@ def update(
from archivebox.machine.models import Process
from archivebox.core.shutdown_util import foreground_parent_watchdog, foreground_shutdown_signals
from archivebox.services.supervision_service import (
command_owns_runtime_stack,
current_command,
ensure_daemon_stack,
standby_until_runtime_stack_needed,
)
from archivebox.workers.supervisord_util import stop_existing_supervisord_process
from archivebox.workers.supervisord_util import stop_existing_supervisord_process, stop_own_supervisord_process
command = current_command(Process.TypeChoices.UPDATE, data_dir=CONSTANTS.DATA_DIR)
@ -414,8 +413,8 @@ def update(
raise SystemExit(130)
finally:
command.mark_exited()
if stop_daemon_stack and command_owns_runtime_stack(command, data_dir=CONSTANTS.DATA_DIR):
stop_existing_supervisord_process()
if stop_daemon_stack:
stop_own_supervisord_process()
def drain_old_archive_dirs(resume_from: str | None = None, batch_size: int = 100) -> dict[str, int]:

View File

@ -506,6 +506,54 @@ def stop_existing_supervisord_process():
pass
def stop_own_supervisord_process():
"""Stop only the supervisord child started by this Python process."""
global _supervisord_proc
stop_grace_seconds = configured_stopwaitsecs(tuple(_desired_supervisord_workers.values()))
if not _supervisord_proc or _supervisord_proc.poll() is not None:
reap_foreground_supervisord_process()
return False
stopped_pid = _supervisord_proc.pid
try:
print(f"[🦸‍♂️] Stopping supervisord process (pid={stopped_pid})...")
try:
psutil_proc = psutil.Process(stopped_pid)
children = psutil_proc.children(recursive=True)
except psutil.NoSuchProcess:
children = []
_supervisord_proc.terminate()
wait_popen_and_kill_children(_supervisord_proc, children, timeout=stop_grace_seconds)
try:
from archivebox.machine.models import Machine, Process
for process in Process.objects.filter(
machine=Machine.current(),
process_type=Process.TypeChoices.SUPERVISORD,
status=Process.StatusChoices.RUNNING,
pwd=str(CONSTANTS.DATA_DIR),
pid=stopped_pid,
).iterator(chunk_size=10):
process.mark_exited(exit_code=0)
except Exception:
pass
except (BrokenPipeError, OSError, psutil.TimeoutExpired):
pass
finally:
try:
SOCK_FILE = get_sock_file()
PID_FILE = SOCK_FILE.parent / PID_FILE_NAME
if PID_FILE.exists() and PID_FILE.read_text().strip() == str(stopped_pid):
PID_FILE.unlink(missing_ok=True)
SOCK_FILE.unlink(missing_ok=True)
except Exception:
pass
_supervisord_proc = None
return True
def reap_foreground_supervisord_process() -> None:
"""Reap the supervisord child owned by this foreground parent if it exited."""

View File

@ -23,6 +23,8 @@ Environment:
SCREENSHOT_FULL_PAGE Set to 1 to capture the full page, defaults to viewport only
SCREENSHOT_SCROLL_SELECTOR Scroll this selector into view before capture
SCREENSHOT_WAIT_SELECTOR Wait for this selector before capture
SCREENSHOT_CLICK_SELECTOR Click this selector before capture
SCREENSHOT_AFTER_CLICK_WAIT_SELECTOR Wait for this selector after clicking
SCREENSHOT_HOST_RESOLVER_RULES Chrome host resolver rules
SCREENSHOT_SNAPSHOT_VIEW Set to list or grid before loading the page
SCREENSHOT_RESET_FILTERS Set to 1 to clear the admin filter collapsed preference
@ -102,6 +104,13 @@ async function main() {
if (process.env.SCREENSHOT_WAIT_SELECTOR) {
await page.waitForSelector(process.env.SCREENSHOT_WAIT_SELECTOR, { timeout: 45000 });
}
if (process.env.SCREENSHOT_CLICK_SELECTOR) {
await page.waitForSelector(process.env.SCREENSHOT_CLICK_SELECTOR, { timeout: 45000 });
await page.click(process.env.SCREENSHOT_CLICK_SELECTOR);
}
if (process.env.SCREENSHOT_AFTER_CLICK_WAIT_SELECTOR) {
await page.waitForSelector(process.env.SCREENSHOT_AFTER_CLICK_WAIT_SELECTOR, { timeout: 45000 });
}
if (process.env.SCREENSHOT_SCROLL_SELECTOR) {
await page.waitForSelector(process.env.SCREENSHOT_SCROLL_SELECTOR, { timeout: 45000 }).catch(() => {});
await page.evaluate((selector) => {