resident P0+P1: DNS-level SSRF pin, batch budget, daily cap/cooldown/retention, PG schema/migration, dual-connection deadlock isolation, retarget baseline reset, proxy and structured failures, metrics
- DNS 级 SSRF pin:解析后 pin IP 建连,防 DNS 重绑定 - 批量总预算与每日上限/抖动冷却/保留期 - PG schema 与迁移清单 - 双连接死锁隔离 - 改目标重置基线 - 显式代理配置与结构化失败原因 - /metrics resident 口径
This commit is contained in:
1 parent
60997b138f
commit
b391fe9320
9 files changed
+1906
-74
No files matched your search
+32
-5
@@ -112,10 +112,12 @@ from cloud.automations import ensure_automations_tables as _auto_ensure
|
||||
from cloud.automations import list_automations as _auto_list
|
||||
from cloud.resident import create_watch as _res_create
|
||||
from cloud.resident import end_watch as _res_end
|
||||
from cloud.resident import ensure_resident_tables as _res_ensure
|
||||
from cloud.resident import get_watch as _res_get
|
||||
from cloud.resident import list_polls as _res_polls
|
||||
from cloud.resident import list_watches as _res_list
|
||||
from cloud.resident import pause_watch as _res_pause
|
||||
from cloud.resident import resident_metrics as _res_metrics
|
||||
from cloud.resident import resume_watch as _res_resume
|
||||
from cloud.resident import update_watch as _res_update
|
||||
from cloud.todos import create_todo as _todo_create
|
||||
@@ -1739,6 +1741,10 @@ def init_db(db_path):
|
||||
_ensure_task_checkpoints_table(conn)
|
||||
_ensure_task_steps_table(conn)
|
||||
ensure_kill_requests_table(conn)
|
||||
# 常驻监听表(P0 S3 的 SQLite 侧):启动时建一次,
|
||||
# 热路径(claim/run_due/批量)不再逐条 ensure,
|
||||
# 详见 cloud/resident.py ensure 的调用约定。
|
||||
_res_ensure(conn)
|
||||
# worker 每轮 poll 都按 status 取任务(见 load_tasks 的
|
||||
# WHERE status IN (...)),无索引时是全表扫描;任务表随
|
||||
# 时间变大后索引是必须的。IF NOT EXISTS 保证老库幂等。
|
||||
@@ -8901,6 +8907,13 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
else:
|
||||
unpriced_tokens += row["total_tokens"] or 0
|
||||
all_tokens = actual_tokens + estimated_tokens
|
||||
# 常驻监听口径(P1 G5):只统计调用者是成员的项目,
|
||||
# 与任务计数同款成员过滤;表缺失时 resident_metrics
|
||||
# 回 available=False,不炸 /metrics。
|
||||
try:
|
||||
resident_stats = _res_metrics(conn, member_ids, now)
|
||||
except Exception: # noqa: BLE001 - 观测端点不因 resident 失败
|
||||
resident_stats = {"available": False}
|
||||
finally:
|
||||
conn.close()
|
||||
try:
|
||||
@@ -8928,6 +8941,7 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
"by_model": sorted(by_model.values(),
|
||||
key=lambda e: -e["total_tokens"]),
|
||||
},
|
||||
"resident": resident_stats,
|
||||
"queue_depth": {
|
||||
"queued": by_status.get("queued", 0),
|
||||
"running": by_status.get("running", 0),
|
||||
@@ -10147,7 +10161,10 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
self._send_json(400, {"error": str(exc)})
|
||||
return
|
||||
except Exception as exc:
|
||||
self._send_json(502, {"error": str(exc)[:500]})
|
||||
# P2:502 不再透传异常文本(可能含表名/列名等
|
||||
# DB 细节),统一固定错误码,详情只记服务端日志。
|
||||
_server_log.warning("resident create failed: %s", exc)
|
||||
self._send_json(502, {"error": "resident_operation_failed"})
|
||||
return
|
||||
finally:
|
||||
conn.close()
|
||||
@@ -10162,7 +10179,8 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
try:
|
||||
watches = _res_list(conn, project_id)
|
||||
except Exception as exc:
|
||||
self._send_json(502, {"error": str(exc)[:500]})
|
||||
_server_log.warning("resident list failed: %s", exc)
|
||||
self._send_json(502, {"error": "resident_operation_failed"})
|
||||
return
|
||||
conn.commit()
|
||||
finally:
|
||||
@@ -10180,7 +10198,13 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
if watch is not None:
|
||||
try:
|
||||
polls = _res_polls(conn, watch_id)
|
||||
except Exception:
|
||||
except Exception as exc:
|
||||
# P2:polls 异常不再静默吞成空串,至少记
|
||||
# 服务端日志;响应仍保持 polls=[] + note
|
||||
# 的兼容形态(排障信号在日志里,不在响应里丢)。
|
||||
_server_log.warning(
|
||||
"resident polls unavailable for %s: %s",
|
||||
watch_id, exc)
|
||||
polls_note = "polls unavailable"
|
||||
finally:
|
||||
conn.close()
|
||||
@@ -10203,7 +10227,8 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
self._send_json(400, {"error": str(exc)})
|
||||
return
|
||||
except Exception as exc:
|
||||
self._send_json(502, {"error": str(exc)[:500]})
|
||||
_server_log.warning("resident update failed: %s", exc)
|
||||
self._send_json(502, {"error": "resident_operation_failed"})
|
||||
return
|
||||
finally:
|
||||
conn.close()
|
||||
@@ -10228,7 +10253,9 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
try:
|
||||
ok, watch = fn(conn, watch_id)
|
||||
except Exception as exc:
|
||||
self._send_json(502, {"error": str(exc)[:500]})
|
||||
_server_log.warning(
|
||||
"resident %s failed: %s", action, exc)
|
||||
self._send_json(502, {"error": "resident_operation_failed"})
|
||||
return
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
Reference in new issue
Block a user