fix(archive): preserve prepared sessions across restarts

This commit is contained in:
DCCONSTRUCTIONS
2026-07-18 11:08:27 +03:00
parent aa3680948f
commit 574a494759
13 changed files with 398 additions and 132 deletions
+24 -25
View File
@@ -45,9 +45,7 @@ SAFE_SOURCE_ID = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$")
SAFE_SHA256 = re.compile(r"^[a-f0-9]{64}$")
MAX_SAFE_INTEGER = 9_007_199_254_740_991
REVALIDATED_RECORDING_CACHE_CONTROL = "private, no-cache, no-transform"
IMMUTABLE_RECORDING_CACHE_CONTROL = (
"private, max-age=31536000, immutable, no-transform"
)
IMMUTABLE_RECORDING_CACHE_CONTROL = "private, max-age=31536000, immutable, no-transform"
class _ReleasingFileResponse(FileResponse):
@@ -321,13 +319,17 @@ def build_session_router(
if recording_preparation_manager is not None:
try:
# Enqueue performs only catalog identity/lstat checks. A cold
# RRD cache and every camera index are validated exclusively
# by the process-owned worker.
snapshot = recording_preparation_manager.enqueue(
command,
retry_failed=True,
)
snapshot = recording_preparation_manager.status(command.session_id)
if snapshot is None:
snapshot = await run_in_threadpool(
recording_preparation_manager.restore_published,
command,
)
if snapshot is None:
snapshot = recording_preparation_manager.enqueue(
command,
retry_failed=True,
)
except RecordingPreparationQueueFull as exc:
raise HTTPException(
status_code=503,
@@ -504,7 +506,12 @@ def build_session_router(
False,
False,
)
snapshot = recording_preparation_manager.enqueue(command)
snapshot = await run_in_threadpool(
recording_preparation_manager.restore_published,
command,
)
if snapshot is None:
snapshot = recording_preparation_manager.enqueue(command)
except SessionNotFoundError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
except (SessionNotReplayableError, SessionIntegrityError) as exc:
@@ -1036,15 +1043,16 @@ def _catalog_preparation_document(
snapshot = manager.status(session_id)
if snapshot is None:
try:
snapshot = manager.enqueue(store.prepare_replay(session_id))
snapshot = manager.restore_published(store.prepare_replay(session_id))
except (
RecordingPreparationQueueFull,
SessionNotFoundError,
SessionNotReplayableError,
SessionIntegrityError,
ValueError,
):
return None
if snapshot is None:
return None
document: dict[str, Any] = {
"preparation_id": snapshot.preparation_id,
"state": snapshot.state,
@@ -1165,10 +1173,7 @@ def _recorded_media_manifest_document(
"segments": [
{
"sequence": segment.sequence,
"url": (
f"{base}/epochs/{epoch.ordinal}/segments/"
f"{segment.sequence}.m4s"
),
"url": (f"{base}/epochs/{epoch.ordinal}/segments/{segment.sequence}.m4s"),
"byte_length": segment.byte_length,
"sha256": segment.sha256,
}
@@ -1198,19 +1203,13 @@ def _resolve_recorded_media_manifest(
detail="Некорректный идентификатор записанного медиаканала.",
) from exc
snapshot = manager.status(session_id)
if (
snapshot is None
or snapshot.state != "ready"
or snapshot.recorded_media is None
):
if snapshot is None or snapshot.state != "ready" or snapshot.recorded_media is None:
raise HTTPException(
status_code=409,
detail="Медиаканал ещё не подготовлен.",
)
matches = tuple(
manifest
for manifest in snapshot.recorded_media
if manifest.artifact_id == artifact_id
manifest for manifest in snapshot.recorded_media if manifest.artifact_id == artifact_id
)
if len(matches) != 1:
raise HTTPException(status_code=404, detail="Записанный медиаканал не найден.")