feat(cloud-scheduler): record terminal results
This commit is contained in:
@@ -383,6 +383,74 @@ class SQLAlchemyCloudRepository:
|
||||
attempt_row.lease_expires_at = renewed_until
|
||||
return "renewed"
|
||||
|
||||
def record_task_result(
|
||||
self,
|
||||
*,
|
||||
task_id: str,
|
||||
attempt: int,
|
||||
lease_id: str,
|
||||
host_id: str,
|
||||
status: str,
|
||||
failure_reason: str | None,
|
||||
terminal_result: dict[str, Any] | None,
|
||||
completed_at: datetime,
|
||||
) -> str:
|
||||
with self._sessions.begin() as session:
|
||||
task = session.get(
|
||||
ScheduledTaskRow,
|
||||
task_id,
|
||||
with_for_update=self.engine.dialect.name == "postgresql",
|
||||
)
|
||||
if task is None:
|
||||
return "conflict"
|
||||
attempt_row = session.get(
|
||||
TaskAttemptRow,
|
||||
(task_id, attempt),
|
||||
with_for_update=self.engine.dialect.name == "postgresql",
|
||||
)
|
||||
if (
|
||||
attempt_row is None
|
||||
or task.attempt_count != attempt
|
||||
or task.lease_id != lease_id
|
||||
or task.assigned_host_id != host_id
|
||||
or attempt_row.lease_id != lease_id
|
||||
or attempt_row.host_id != host_id
|
||||
):
|
||||
return "conflict"
|
||||
|
||||
if task.status in {"done", "failed"}:
|
||||
if (
|
||||
task.status == status
|
||||
and task.failure_reason == failure_reason
|
||||
and _parse_json_object(task.result_json) == terminal_result
|
||||
and attempt_row.status == status
|
||||
):
|
||||
return "already_recorded"
|
||||
return "conflict"
|
||||
if task.status not in {"assigned", "dispatched"}:
|
||||
return "conflict"
|
||||
current_expiry = _parse_dt(task.lease_expires_at)
|
||||
if current_expiry is None or current_expiry <= completed_at:
|
||||
return "conflict"
|
||||
if status not in {"done", "failed"}:
|
||||
return "conflict"
|
||||
|
||||
result_json = (
|
||||
json.dumps(terminal_result, ensure_ascii=False)
|
||||
if terminal_result is not None
|
||||
else None
|
||||
)
|
||||
completed_at_iso = _iso(completed_at)
|
||||
task.status = status
|
||||
task.failure_reason = failure_reason
|
||||
task.result_json = result_json
|
||||
task.updated_at = completed_at_iso
|
||||
attempt_row.status = status
|
||||
attempt_row.completed_at = completed_at_iso
|
||||
attempt_row.failure_reason = failure_reason
|
||||
attempt_row.result_json = result_json
|
||||
return "recorded"
|
||||
|
||||
def list_task_attempts(self, task_id: str) -> list[Any]:
|
||||
with self._sessions() as session:
|
||||
rows = session.scalars(
|
||||
|
||||
Reference in New Issue
Block a user