workers: land host/pid/address columns with idempotent migration and pid_verified stale classification

- ensure_workers_table: new tables include host TEXT, pid BIGINT,
  address TEXT; old tables gain them via _ensure_hostpid_columns
  (PRAGMA column check, missing-only ALTER, old rows keep NULL,
  never fabricates host/pid). SQLite and Postgres share this path
  (PG via the db adapter's PRAGMA translation); POSTGRES_SCHEMA
  deliberately still excludes workers, which is volatile heartbeat
  data in UNMIGRATED_TABLES (adding it broke the P2 migration
  alignment tests, verified and reverted).
- heartbeat/register: given host/pid/address refresh, omitted
  values preserve the old row; address has no derived source.
  Local worker passes host_name + own pid; HTTP heartbeat only
  stores caller-supplied values, never the server's own.
- classify_stale_workers: kill only when age strictly exceeds the
  threshold AND host matches local host AND pid is proven dead;
  equal threshold, foreign host, missing pid, or live/unknown pid
  are list_only. Classification only, never kills, never matches
  by name/prefix, never touches infra containers.
This commit is contained in:
host committed 2026-11-03 02:48:55 +00:00
1 parent 452fc8ea7e
commit 8ea54cf66b
4 files changed
+524 -24

No files matched your search

+11 -3
View File
@@ -699,18 +699,26 @@ class Worker:
register_worker(
self.db_path, self.worker_id,
executor=self._executor_name(), capacity=self.capacity,
running=self._running_count())
running=self._running_count(),
host=self.host_name, pid=os.getpid())
except Exception as exc:
log_event(self.logger, "worker_register_failed",
message="worker register failed: %s" % exc)
def _registry_heartbeat(self):
"""向控制面写注册表心跳(与文件心跳并行,失败只记日志)。"""
"""向控制面写注册表心跳(与文件心跳并行,失败只记日志)。
host 用 self.host_name(autoscaler 显式传的宿主名;未传
时退化为 socket.gethostname(),容器内即容器名,与
worktree_host 同款 caveat),pid 用本进程号;两者每轮
刷新,供失联判定做本机 + pid 已死的 pid_verified 校验。
"""
try:
heartbeat_worker(
self.db_path, self.worker_id,
executor=self._executor_name(), capacity=self.capacity,
running=self._running_count())
running=self._running_count(),
host=self.host_name, pid=os.getpid())
except Exception as exc:
log_event(self.logger, "worker_registry_heartbeat_failed",
message="worker registry heartbeat failed: %s" % exc)