From 3ac835ab7ed2bf58509664184043eee4d358411d Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Mon, 26 Oct 2026 08:46:50 +0000 Subject: [PATCH] chore: purge checks older than 30 days --- app/cleanup.py | 42 ++++++++++++++++++++++++++++++++++++++++++ entrypoint.sh | 1 + 2 files changed, 43 insertions(+) create mode 100644 app/cleanup.py diff --git a/app/cleanup.py b/app/cleanup.py new file mode 100644 index 0000000..e70b31f --- /dev/null +++ b/app/cleanup.py @@ -0,0 +1,42 @@ +"""Remove Arena check records older than the retention window.""" +from __future__ import annotations + +import os +import sqlite3 +import sys +import time +from datetime import datetime, timedelta, timezone + +DB_PATH = os.environ.get("DB_PATH", "/data/arena.db") +RETENTION_DAYS = int(os.environ.get("CHECK_RETENTION_DAYS", "30")) + + +def cleanup(db_path: str = DB_PATH, retention_days: int = RETENTION_DAYS) -> int: + if retention_days < 1: + raise ValueError("CHECK_RETENTION_DAYS must be >= 1") + cutoff = (datetime.now(timezone.utc) - timedelta(days=retention_days)).isoformat() + db = sqlite3.connect(db_path, timeout=30) + try: + db.execute("PRAGMA busy_timeout=30000") + before = db.total_changes + db.execute("BEGIN IMMEDIATE") + db.execute("DELETE FROM checks WHERE checked_at < ?", (cutoff,)) + removed = db.total_changes - before + db.commit() + # Keep the persistent WAL bounded without a full VACUUM/long lock. + db.execute("PRAGMA wal_checkpoint(PASSIVE)") + print(f"[cleanup] removed={removed} cutoff={cutoff} retention_days={retention_days}") + return removed + except Exception: + db.rollback() + raise + finally: + db.close() + + +if __name__ == "__main__": + try: + cleanup() + except Exception as exc: + print(f"[cleanup] ERROR: {exc}", file=sys.stderr) + raise diff --git a/entrypoint.sh b/entrypoint.sh index 2439086..96a2d3f 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -17,6 +17,7 @@ umask 077 cat <> /proc/1/fd/1 2>&1 +15 3 * * * set -a; . $CRON_ENV; set +a; /usr/local/bin/python3 /app/app/cleanup.py >> /proc/1/fd/1 2>&1 EOF cron