fix(replay): stream sealed perception overlays

This commit is contained in:
DCCONSTRUCTIONS
2026-07-30 00:51:14 +03:00
parent 091ab2671e
commit 2ab9e45548
10 changed files with 380 additions and 44 deletions
+69 -7
View File
@@ -22,7 +22,10 @@ from k1link.sessions import SessionIntegrityError
from .jobs import CameraComputeJob, validate_camera_compute_job
from .perception_epoch import validate_recorded_perception_epoch_result
from .results import RecordedPerceptionOverlayError
from .results import (
RecordedPerceptionOverlayArtifact,
RecordedPerceptionOverlayError,
)
FUSION_SCHEMA = "missioncore.recorded-calibrated-fusion/v1"
FUSION_IDENTITY_SCHEMA = "missioncore.recorded-calibrated-fusion-identity/v1"
@@ -188,18 +191,77 @@ class RecordedPerceptionOverlayMux:
application_id: str,
recording_id: str,
) -> bytes | None:
payload = self.primary.render(
materialized = self.materialize(
session_id,
application_id=application_id,
recording_id=recording_id,
)
if not isinstance(materialized, RecordedPerceptionOverlayArtifact):
return materialized
try:
payload = materialized.path.read_bytes()
except OSError as exc:
raise RecordedPerceptionOverlayError(
"recorded perception cache became unavailable"
) from exc
if (
len(payload) != materialized.byte_length
or hashlib.sha256(payload).hexdigest() != materialized.sha256
):
raise RecordedPerceptionOverlayError(
"recorded perception cache changed after validation"
)
return payload
def materialize(
self,
session_id: str,
*,
application_id: str,
recording_id: str,
) -> RecordedPerceptionOverlayArtifact | bytes | None:
primary_materializer = getattr(self.primary, "materialize", None)
payload = (
primary_materializer(
session_id,
application_id=application_id,
recording_id=recording_id,
)
if callable(primary_materializer)
else self.primary.render(
session_id,
application_id=application_id,
recording_id=recording_id,
)
)
if payload is not None and not isinstance(
payload, (bytes, RecordedPerceptionOverlayArtifact)
):
raise RecordedPerceptionOverlayError(
"recorded perception provider returned an invalid artifact"
)
if payload is not None or self.fallback is None:
return payload
return self.fallback.render(
session_id,
application_id=application_id,
recording_id=recording_id,
)
fallback_materializer = getattr(self.fallback, "materialize", None)
if callable(fallback_materializer):
fallback_payload = fallback_materializer(
session_id,
application_id=application_id,
recording_id=recording_id,
)
else:
fallback_payload = self.fallback.render(
session_id,
application_id=application_id,
recording_id=recording_id,
)
if fallback_payload is not None and not isinstance(
fallback_payload, (bytes, RecordedPerceptionOverlayArtifact)
):
raise RecordedPerceptionOverlayError(
"recorded perception fallback returned an invalid artifact"
)
return fallback_payload
def status(self, session_id: str, *, recording_id: str) -> dict[str, Any]:
primary_status = getattr(self.primary, "status", None)