Files

37 lines
1.1 KiB
Python
Raw Permalink Normal View History

"""The worker's heartbeat: a touched beat file for the container healthcheck and a worker_heartbeat row."""
from __future__ import annotations
import os
import time
from collections.abc import Iterable
from pathlib import Path
from typing import Any
BEAT_SECONDS = 30
STALE_SECONDS = 90
def touch(path: Path) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.touch(exist_ok=True)
now = time.time()
os.utime(path, (now, now))
def beat_age(beat_file: Path) -> float | None:
try:
return time.time() - beat_file.stat().st_mtime
except OSError:
return None
def write_row(conn: Any, *, build: str, host: str, pid: int, running: Iterable[str]) -> None:
"""Upsert the single worker_heartbeat row."""
conn.execute(
"INSERT INTO worker_heartbeat (id, at, build, host, pid, running) VALUES (1, now(), %s, %s, %s, %s)"
" ON CONFLICT (id) DO UPDATE SET at = EXCLUDED.at, build = EXCLUDED.build, host = EXCLUDED.host,"
" pid = EXCLUDED.pid, running = EXCLUDED.running",
(build, host, pid, sorted(running)),
)