feat: complete transfer and eviction execution

This commit is contained in:
2026-07-23 09:14:40 +00:00
parent 884aed9921
commit b6de490b7e
17 changed files with 1445 additions and 81 deletions
+66 -1
View File
@@ -11,7 +11,7 @@ from dataclasses import dataclass
from pathlib import Path
SCHEMA_VERSION = 2
SCHEMA_VERSION = 3
class CommandConflict(RuntimeError):
@@ -58,6 +58,10 @@ class ClientStore:
if version == 1:
connection.executescript(_SCHEMA_V2)
connection.execute("PRAGMA user_version = 2")
version = 2
if version == 2:
connection.executescript(_SCHEMA_V3)
connection.execute("PRAGMA user_version = 3")
if connection.execute("PRAGMA foreign_key_check").fetchall():
raise RuntimeError("client database foreign-key check failed")
if not existed:
@@ -268,6 +272,57 @@ class ClientStore:
).fetchall()
return [dict(row) for row in rows]
def put_job_artifact(
self, job_id: str, kind: str, value: dict[str, object]
) -> dict[str, object]:
encoded = _canonical(value)
with self._connect() as connection:
connection.execute("BEGIN IMMEDIATE")
existing = connection.execute(
"""
SELECT value_json FROM job_artifacts
WHERE job_id = ? AND kind = ?
""",
(job_id, kind),
).fetchone()
if existing is not None and existing["value_json"] != encoded:
raise JobConflict(f"job artifact {kind} is immutable")
connection.execute(
"""
INSERT INTO job_artifacts (job_id, kind, value_json)
VALUES (?, ?, ?)
ON CONFLICT(job_id, kind) DO NOTHING
""",
(job_id, kind, encoded),
)
row = connection.execute(
"""
SELECT job_id, kind, value_json FROM job_artifacts
WHERE job_id = ? AND kind = ?
""",
(job_id, kind),
).fetchone()
result = dict(row)
result["value"] = json.loads(str(result.pop("value_json")))
return result
def get_job_artifact(
self, job_id: str, kind: str
) -> dict[str, object] | None:
with self._connect() as connection:
row = connection.execute(
"""
SELECT job_id, kind, value_json FROM job_artifacts
WHERE job_id = ? AND kind = ?
""",
(job_id, kind),
).fetchone()
if row is None:
return None
result = dict(row)
result["value"] = json.loads(str(result.pop("value_json")))
return result
def record_job_event(
self,
*,
@@ -567,3 +622,13 @@ CREATE TABLE route_attempt_updates (
PRIMARY KEY(command_id, sequence)
);
"""
_SCHEMA_V3 = """
CREATE TABLE job_artifacts (
job_id TEXT NOT NULL REFERENCES jobs(job_id),
kind TEXT NOT NULL,
value_json TEXT NOT NULL,
PRIMARY KEY(job_id, kind)
);
"""