diff --git a/cron/jobs.py b/cron/jobs.py index 3cc13df1f7..2124340ba8 100644 --- a/cron/jobs.py +++ b/cron/jobs.py @@ -2227,23 +2227,6 @@ def trigger_job(job_id: str, extra_prompt: Optional[str] = None) -> Optional[Dic }) -def _claim_owner_is_dead(claim: Dict[str, Any]) -> bool: - """True when the claim's ``by`` names a process on THIS host that provably no longer exists. - ``_machine_id()`` stamps ``host:pid[:token]``; a foreign host, an explicit HERMES_MACHINE_ID, - or any liveness-probe failure returns False (fail safe: only a proven death shortens the TTL).""" - parts = str(claim.get("by") or "").split(":") - if len(parts) < 2 or not parts[1].isdigit(): - return False - try: - import socket - if parts[0] != socket.gethostname(): - return False - from gateway.status import _pid_exists - return not _pid_exists(int(parts[1])) - except Exception: - return False - - def _claim_is_live(claim: Any, now: datetime, ttl_seconds: float) -> bool: """True for a well-formed claim aged within ``[0, ttl)`` whose owner is not provably dead: future-dated (clock/TZ skew) or malformed claims count as stale so they can never wedge a @@ -2255,6 +2238,7 @@ def _claim_is_live(claim: Any, now: datetime, ttl_seconds: float) -> bool: claimed_at = _parse_aware(claim["at"]) if claimed_at is None or not (0 <= _elapsed_seconds(now, claimed_at) < ttl_seconds): return False + from cron.scheduler_ownership import _claim_owner_is_dead return not _claim_owner_is_dead(claim) diff --git a/cron/scheduler_ownership.py b/cron/scheduler_ownership.py index 3ace2a790f..cf8ff99825 100644 --- a/cron/scheduler_ownership.py +++ b/cron/scheduler_ownership.py @@ -20,7 +20,7 @@ from __future__ import annotations import threading from pathlib import Path -from typing import Any, Optional, Union +from typing import Any, Dict, Optional, Union from hermes_constants import get_hermes_home, hermes_home_key @@ -135,3 +135,20 @@ def live_gateway_ticking(home: Optional[Union[Path, str]] = None) -> Optional[di except Exception: return None return record if record_serves_profile(record, home) else None + + +def _claim_owner_is_dead(claim: Dict[str, Any]) -> bool: + """True when the claim's ``by`` names a process on THIS host that provably no longer exists. + ``_machine_id()`` stamps ``host:pid[:token]``; a foreign host, an explicit HERMES_MACHINE_ID, + or any liveness-probe failure returns False (fail safe: only a proven death shortens the TTL).""" + parts = str(claim.get("by") or "").split(":") + if len(parts) < 2 or not parts[1].isdigit(): + return False + try: + import socket + if parts[0] != socket.gethostname(): + return False + from gateway.status import _pid_exists + return not _pid_exists(int(parts[1])) + except Exception: + return False