7d6d0709cd
Capture the exact UTC scheduled instant before either due scanning or the external fire claim advances jobs.json. Bind it to the durable attempt before worker handoff; manual and unclassified direct attempts stay null. Consult any retained completed matching row, independently of stale stamps, claim-time windows, and newer failed attempts. Preserve unknown and legacy attempt eligibility rather than guessing that a side effect completed. Real isolated restart probes reproduce duplicate script writes on base and suppress them on the fix for builtin tick and provider fire. Distinct and manual occurrences still execute. The campaign-serialized cron suite is queued; this progressive commit preserves the verified integration step. Credit holny's issue #104790 and guard proposal #104323; exact identity replaces the approximation rather than importing its legacy heuristic. Co-authored-by: holny <holny@foxmail.com>
37 lines
1.2 KiB
Python
37 lines
1.2 KiB
Python
"""Exact scheduled identities, independent of mutable jobs.json dispatch stamps."""
|
|
from datetime import datetime, timezone
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def scheduled_instant(value):
|
|
"""Canonicalize aware instants; legacy/ambiguous values carry no exact identity."""
|
|
if not isinstance(value, str):
|
|
return None
|
|
try:
|
|
instant = datetime.fromisoformat(value)
|
|
if instant.tzinfo is None:
|
|
return None
|
|
return instant.astimezone(timezone.utc).isoformat()
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def completed_occurrence(job, instant):
|
|
"""Unknown/failed/pruned attempts cannot prove completion: keep them eligible."""
|
|
from cron.executions import _transaction
|
|
|
|
instant = scheduled_instant(instant)
|
|
if instant is None:
|
|
return False
|
|
try:
|
|
with _transaction() as conn:
|
|
return conn.execute(
|
|
"SELECT 1 FROM executions WHERE job_id=? AND scheduled_instant=? "
|
|
"AND status='completed' LIMIT 1", (str(job['id']), instant)
|
|
).fetchone() is not None
|
|
except Exception:
|
|
logger.warning("Cannot check completed occurrence for job %s", job['id'], exc_info=True)
|
|
return False
|