feat: P1 补齐(自动评审队列、自动化+分诊、并发 caps、运行时审批队列)
This commit is contained in:
1 parent
29efc6c61f
commit
e0cecd70aa
18 files changed
+3474
-27
No files matched your search
+71
-9
@@ -62,10 +62,12 @@ def ensure_workers_table(db_path):
|
||||
"worker_id TEXT PRIMARY KEY, "
|
||||
"executor TEXT, "
|
||||
"capacity INTEGER, "
|
||||
"running INTEGER, "
|
||||
"last_seen DOUBLE PRECISION, "
|
||||
"created_at DOUBLE PRECISION)"
|
||||
)
|
||||
conn.commit()
|
||||
_ensure_running_column(conn)
|
||||
# 老库升精度只在确实是 Postgres REAL 列时做一次:每次心跳都
|
||||
# ALTER 会反复拿 ACCESS EXCLUSIVE 锁,没必要。先查
|
||||
# information_schema(SQLite 下这张表不存在,查询失败即跳过,
|
||||
@@ -98,7 +100,59 @@ def ensure_workers_table(db_path):
|
||||
conn.close()
|
||||
|
||||
|
||||
def register_worker(db_path, worker_id, executor=None, capacity=1):
|
||||
def _ensure_running_column(conn):
|
||||
"""老库补 running 列(新表建表时已含该列)。
|
||||
|
||||
running 是 worker 上次心跳上报的当前占用槽数(启动中占位
|
||||
也算,见 cloud/caps.py);列缺失时 _worker_to_dict 默认 0,
|
||||
所以补列失败只回滚、不抛,绝不炸注册与心跳。
|
||||
SQLite 用 PRAGMA 查列,Postgres 用 information_schema。
|
||||
"""
|
||||
try:
|
||||
rows = conn.execute("PRAGMA table_info(workers)").fetchall()
|
||||
names = set()
|
||||
for row in rows:
|
||||
try:
|
||||
names.add(row[1])
|
||||
except (IndexError, TypeError):
|
||||
pass
|
||||
if rows and "running" not in names:
|
||||
conn.execute(
|
||||
"ALTER TABLE workers ADD COLUMN running INTEGER DEFAULT 0")
|
||||
conn.commit()
|
||||
return
|
||||
except Exception:
|
||||
try:
|
||||
conn.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
row = conn.execute(
|
||||
"SELECT COUNT(*) FROM information_schema.columns "
|
||||
"WHERE table_name = 'workers' AND column_name = 'running'"
|
||||
).fetchone()
|
||||
exists = bool(row and row[0])
|
||||
except Exception:
|
||||
try:
|
||||
conn.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
if not exists:
|
||||
try:
|
||||
conn.execute(
|
||||
"ALTER TABLE workers ADD COLUMN IF NOT EXISTS "
|
||||
"running INTEGER DEFAULT 0")
|
||||
conn.commit()
|
||||
except Exception:
|
||||
try:
|
||||
conn.rollback()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def register_worker(db_path, worker_id, executor=None, capacity=1,
|
||||
running=None):
|
||||
"""注册(或刷新)一个 worker:不存在 INSERT,存在 UPDATE。
|
||||
|
||||
返回注册行 dict。worker_id 为空时抛 ValueError,调用方
|
||||
@@ -112,14 +166,17 @@ def register_worker(db_path, worker_id, executor=None, capacity=1):
|
||||
try:
|
||||
cur = conn.execute(
|
||||
"UPDATE workers SET executor = ?, capacity = ?,"
|
||||
" last_seen = ? WHERE worker_id = ?",
|
||||
(executor, capacity, now, worker_id),
|
||||
" running = ?, last_seen = ? WHERE worker_id = ?",
|
||||
(executor, capacity, running if running is not None else 0,
|
||||
now, worker_id),
|
||||
)
|
||||
if cur.rowcount == 0:
|
||||
conn.execute(
|
||||
"INSERT INTO workers(worker_id, executor, capacity,"
|
||||
" last_seen, created_at) VALUES(?, ?, ?, ?, ?)",
|
||||
(worker_id, executor, capacity, now, now),
|
||||
" running, last_seen, created_at)"
|
||||
" VALUES(?, ?, ?, ?, ?, ?)",
|
||||
(worker_id, executor, capacity,
|
||||
running if running is not None else 0, now, now),
|
||||
)
|
||||
conn.commit()
|
||||
row = conn.execute(
|
||||
@@ -130,7 +187,8 @@ def register_worker(db_path, worker_id, executor=None, capacity=1):
|
||||
return _worker_to_dict(row)
|
||||
|
||||
|
||||
def heartbeat_worker(db_path, worker_id, executor=None, capacity=None):
|
||||
def heartbeat_worker(db_path, worker_id, executor=None, capacity=None,
|
||||
running=None):
|
||||
"""心跳:就是带 last_seen 刷新的注册。
|
||||
|
||||
executor/capacity 未给时保留旧值(已注册的 worker 只刷时间,
|
||||
@@ -148,17 +206,19 @@ def heartbeat_worker(db_path, worker_id, executor=None, capacity=None):
|
||||
if row is None:
|
||||
conn.execute(
|
||||
"INSERT INTO workers(worker_id, executor, capacity,"
|
||||
" last_seen, created_at) VALUES(?, ?, ?, ?, ?)",
|
||||
" running, last_seen, created_at)"
|
||||
" VALUES(?, ?, ?, ?, ?, ?)",
|
||||
(worker_id, executor, capacity if capacity is not None
|
||||
else 1, now, now),
|
||||
else 1, running if running is not None else 0, now, now),
|
||||
)
|
||||
else:
|
||||
old = _worker_to_dict(row)
|
||||
conn.execute(
|
||||
"UPDATE workers SET executor = ?, capacity = ?,"
|
||||
" last_seen = ? WHERE worker_id = ?",
|
||||
" running = ?, last_seen = ? WHERE worker_id = ?",
|
||||
(executor if executor is not None else old["executor"],
|
||||
capacity if capacity is not None else old["capacity"],
|
||||
running if running is not None else old["running"],
|
||||
now, worker_id),
|
||||
)
|
||||
conn.commit()
|
||||
@@ -197,10 +257,12 @@ def _worker_to_dict(row):
|
||||
return row[name]
|
||||
except (KeyError, IndexError, TypeError):
|
||||
return None
|
||||
running = _get("running")
|
||||
return {
|
||||
"worker_id": _get("worker_id"),
|
||||
"executor": _get("executor"),
|
||||
"capacity": _get("capacity"),
|
||||
"running": running if running is not None else 0,
|
||||
"last_seen": _get("last_seen"),
|
||||
"created_at": _get("created_at"),
|
||||
}
|
||||
Reference in new issue
Block a user