backend/worker_health.py
Rama master · réplica de lectura del repositorio original.
"""Container healthcheck for an RQ worker, which has no HTTP listener."""
import os
import socket
from datetime import UTC, datetime
def worker_is_healthy(worker, *, hostname, now):
if worker.hostname != hostname or not worker.pid or not worker.last_heartbeat:
return False
try:
os.kill(worker.pid, 0)
except PermissionError:
# Docker healthchecks can run as root without CAP_KILL while gosu
# runs the worker as PUID. EPERM still proves that the PID exists.
pass
except (OSError, TypeError):
return False
heartbeat = worker.last_heartbeat
if heartbeat.tzinfo is None:
heartbeat = heartbeat.replace(tzinfo=UTC)
# Idle RQ workers block for almost worker_ttl; busy workers heartbeat too.
age = (now - heartbeat).total_seconds()
return 0 <= age <= worker.worker_ttl + 60
def main():
from redis import Redis
from rq import Worker
try:
connection = Redis.from_url(
os.environ["SUBLARR_REDIS_URL"], socket_connect_timeout=3, socket_timeout=3
)
workers = Worker.all(connection=connection)
healthy = any(
worker_is_healthy(w, hostname=socket.gethostname(), now=datetime.now(UTC))
for w in workers
)
except Exception:
# Do not log the connection URL: it can contain a Redis password.
healthy = False
print("RQ worker healthy" if healthy else "RQ worker unavailable or heartbeat stale")
return 0 if healthy else 1
if __name__ == "__main__":
raise SystemExit(main())