Make cycle show classify progress and prevent overlapping runs

- cycle now prints per-article classify progress (flushed) so the long step is
  clearly alive rather than appearing hung.
- An exclusive flock guards the cycle so a manual run and the systemd timer (or
  two timer ticks) cannot overlap and contend on the database and model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jay
2026-05-30 16:15:03 +00:00
parent b1530e4a4f
commit 470e9ecbf8
2 changed files with 41 additions and 7 deletions
+5 -1
View File
@@ -5,6 +5,7 @@ import os
import sqlite3
import urllib.error
import urllib.request
from collections.abc import Callable
from dataclasses import dataclass
from .taxonomy import (
@@ -226,12 +227,13 @@ def classify_articles(
include_rejected: bool = False,
dry_run: bool = False,
only_unclassified: bool = False,
progress: "Callable[[int, int, int], None] | None" = None,
) -> list[tuple[int, dict]]:
rows = _classification_candidates(
conn, limit=limit, include_rejected=include_rejected, only_unclassified=only_unclassified
)
results = []
for row in rows:
for index, row in enumerate(rows, start=1):
try:
scores = client.classify(row)
except RuntimeError as exc:
@@ -244,6 +246,8 @@ def classify_articles(
if not dry_run:
upsert_article_score(conn, row["id"], scores)
conn.commit()
if progress is not None:
progress(index, len(rows), row["id"])
return results