fix: read-only baseline queries skip _runs upsert (register_run flag)
This commit is contained in:
+32
-18
@@ -52,6 +52,9 @@ class HarnessLog:
|
|||||||
run_id: 本次运行的唯一标识。
|
run_id: 本次运行的唯一标识。
|
||||||
git_sha: 代码版本,默认自动获取。
|
git_sha: 代码版本,默认自动获取。
|
||||||
config_snapshot: 本次运行的配置快照。
|
config_snapshot: 本次运行的配置快照。
|
||||||
|
register_run: 是否注册运行(upsert _runs + 退出时同步 status)。默认 True;
|
||||||
|
只读查询已有 run(如基线预测回读)时传 False,避免把该 run 的
|
||||||
|
started_at/config/status 改写、把基线元数据污染成本次进程的运行状态。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -60,27 +63,33 @@ class HarnessLog:
|
|||||||
run_id: str,
|
run_id: str,
|
||||||
git_sha: str | None = None,
|
git_sha: str | None = None,
|
||||||
config_snapshot: dict[str, Any] | None = None,
|
config_snapshot: dict[str, Any] | None = None,
|
||||||
|
*,
|
||||||
|
register_run: bool = True,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._run_id = run_id
|
self._run_id = run_id
|
||||||
|
self._register_run = register_run
|
||||||
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
|
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
|
||||||
self._conn = sqlite3.connect(db_path, check_same_thread=False)
|
self._conn = sqlite3.connect(db_path, check_same_thread=False)
|
||||||
self._lock = threading.Lock()
|
self._lock = threading.Lock()
|
||||||
self._conn.row_factory = sqlite3.Row
|
self._conn.row_factory = sqlite3.Row
|
||||||
self._conn.execute("PRAGMA journal_mode=WAL")
|
self._conn.execute("PRAGMA journal_mode=WAL")
|
||||||
self._init_fixed_tables()
|
self._init_fixed_tables()
|
||||||
resolved_sha = git_sha or _get_git_sha()
|
if register_run:
|
||||||
config_json = json.dumps(config_snapshot, ensure_ascii=False) if config_snapshot else None
|
resolved_sha = git_sha or _get_git_sha()
|
||||||
self._conn.execute(
|
config_json = (
|
||||||
"INSERT INTO _runs"
|
json.dumps(config_snapshot, ensure_ascii=False) if config_snapshot else None
|
||||||
" (run_id, git_sha, started_at, config, status)"
|
)
|
||||||
" VALUES (?, ?, ?, ?, ?)"
|
self._conn.execute(
|
||||||
" ON CONFLICT(run_id) DO UPDATE SET"
|
"INSERT INTO _runs"
|
||||||
" started_at=excluded.started_at,"
|
" (run_id, git_sha, started_at, config, status)"
|
||||||
" config=excluded.config,"
|
" VALUES (?, ?, ?, ?, ?)"
|
||||||
" status=excluded.status",
|
" ON CONFLICT(run_id) DO UPDATE SET"
|
||||||
(run_id, resolved_sha, _now_iso(), config_json, "running"),
|
" started_at=excluded.started_at,"
|
||||||
)
|
" config=excluded.config,"
|
||||||
self._conn.commit()
|
" status=excluded.status",
|
||||||
|
(run_id, resolved_sha, _now_iso(), config_json, "running"),
|
||||||
|
)
|
||||||
|
self._conn.commit()
|
||||||
|
|
||||||
def _init_fixed_tables(self) -> None:
|
def _init_fixed_tables(self) -> None:
|
||||||
"""创建 _runs 和 _events 固定表。"""
|
"""创建 _runs 和 _events 固定表。"""
|
||||||
@@ -217,13 +226,18 @@ class HarnessLog:
|
|||||||
|
|
||||||
参数:
|
参数:
|
||||||
status: 最终状态,"completed" 或 "failed"。
|
status: 最终状态,"completed" 或 "failed"。
|
||||||
|
|
||||||
|
关键实现:
|
||||||
|
register_run=False(只读打开)时跳过 status 更新,仅关闭连接,
|
||||||
|
避免只读回读把已有 run 的 finished_at/status 改写。
|
||||||
"""
|
"""
|
||||||
with self._lock:
|
with self._lock:
|
||||||
self._conn.execute(
|
if self._register_run:
|
||||||
"UPDATE _runs SET finished_at = ?, status = ? WHERE run_id = ?",
|
self._conn.execute(
|
||||||
(_now_iso(), status, self._run_id),
|
"UPDATE _runs SET finished_at = ?, status = ? WHERE run_id = ?",
|
||||||
)
|
(_now_iso(), status, self._run_id),
|
||||||
self._conn.commit()
|
)
|
||||||
|
self._conn.commit()
|
||||||
self._conn.close()
|
self._conn.close()
|
||||||
|
|
||||||
def __enter__(self) -> HarnessLog:
|
def __enter__(self) -> HarnessLog:
|
||||||
|
|||||||
@@ -797,7 +797,9 @@ def build_or_load_pools(
|
|||||||
# 增量构建新类别
|
# 增量构建新类别
|
||||||
paths = resolve_paths(config.workspace_dir)
|
paths = resolve_paths(config.workspace_dir)
|
||||||
questions = load_benchmark(paths.questions_dir)
|
questions = load_benchmark(paths.questions_dir)
|
||||||
with HarnessLog(str(db_path), baseline_run_id) as hlog:
|
with HarnessLog(
|
||||||
|
str(db_path), baseline_run_id, register_run=False
|
||||||
|
) as hlog:
|
||||||
rows = hlog.query(
|
rows = hlog.query(
|
||||||
"SELECT question_id, prediction, answer "
|
"SELECT question_id, prediction, answer "
|
||||||
"FROM predictions WHERE run_id=?",
|
"FROM predictions WHERE run_id=?",
|
||||||
@@ -872,7 +874,7 @@ def build_or_load_pools(
|
|||||||
# ── 全新构建 ──
|
# ── 全新构建 ──
|
||||||
paths = resolve_paths(config.workspace_dir)
|
paths = resolve_paths(config.workspace_dir)
|
||||||
questions = load_benchmark(paths.questions_dir)
|
questions = load_benchmark(paths.questions_dir)
|
||||||
with HarnessLog(str(db_path), baseline_run_id) as hlog:
|
with HarnessLog(str(db_path), baseline_run_id, register_run=False) as hlog:
|
||||||
rows = hlog.query(
|
rows = hlog.query(
|
||||||
"SELECT question_id, prediction, answer FROM predictions WHERE run_id=?",
|
"SELECT question_id, prediction, answer FROM predictions WHERE run_id=?",
|
||||||
(baseline_run_id,),
|
(baseline_run_id,),
|
||||||
|
|||||||
@@ -920,7 +920,9 @@ class Runner:
|
|||||||
self._gate_units_by_id: dict[str, QuestionUnit] = {
|
self._gate_units_by_id: dict[str, QuestionUnit] = {
|
||||||
u.unit_id: u for u in build_units(questions)
|
u.unit_id: u for u in build_units(questions)
|
||||||
}
|
}
|
||||||
with HarnessLog(str(self._paths.db_path), pools.baseline_run_id) as log:
|
with HarnessLog(
|
||||||
|
str(self._paths.db_path), pools.baseline_run_id, register_run=False
|
||||||
|
) as log:
|
||||||
rows = log.query(
|
rows = log.query(
|
||||||
"SELECT question_id, prediction, answer FROM predictions WHERE run_id=?",
|
"SELECT question_id, prediction, answer FROM predictions WHERE run_id=?",
|
||||||
(pools.baseline_run_id,),
|
(pools.baseline_run_id,),
|
||||||
|
|||||||
@@ -215,6 +215,30 @@ class TestHarnessLogUpsert:
|
|||||||
rows = log3.query("SELECT COUNT(*) as cnt FROM _runs WHERE run_id='run_1'")
|
rows = log3.query("SELECT COUNT(*) as cnt FROM _runs WHERE run_id='run_1'")
|
||||||
assert rows[0]["cnt"] == 1
|
assert rows[0]["cnt"] == 1
|
||||||
|
|
||||||
|
def test_register_run_false_skips_upsert(self, tmp_path: Path) -> None:
|
||||||
|
"""register_run=False 时只读打开不改写已有 _runs 行(started_at/status 不变)。"""
|
||||||
|
db = str(tmp_path / "h.db")
|
||||||
|
|
||||||
|
def _read_run_row(run_id: str) -> dict:
|
||||||
|
# 用 register_run=False 只读,避免读取本身污染 _runs
|
||||||
|
with HarnessLog(db, run_id, register_run=False) as log:
|
||||||
|
rows = log.query(
|
||||||
|
"SELECT started_at, status FROM _runs WHERE run_id=?", (run_id,)
|
||||||
|
)
|
||||||
|
return rows[0]
|
||||||
|
|
||||||
|
with HarnessLog(db, "r1"):
|
||||||
|
pass # 初次注册 + 正常退出置 completed
|
||||||
|
row0 = _read_run_row("r1")
|
||||||
|
|
||||||
|
time.sleep(0.02)
|
||||||
|
with HarnessLog(db, "r1", register_run=False) as log:
|
||||||
|
log.query("SELECT 1") # 只读
|
||||||
|
row1 = _read_run_row("r1")
|
||||||
|
|
||||||
|
assert row1["started_at"] == row0["started_at"]
|
||||||
|
assert row1["status"] == row0["status"]
|
||||||
|
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# RunLogImpl 测试
|
# RunLogImpl 测试
|
||||||
|
|||||||
Reference in New Issue
Block a user