perf(observatory): bound source destination planning

This commit is contained in:
DCCONSTRUCTIONS
2026-08-31 18:19:04 +03:00
parent 7e59176581
commit def8c71410
2 changed files with 142 additions and 2 deletions
@@ -109,6 +109,38 @@ class _SourceMember:
camera_sequence: int | None
@dataclass(frozen=True, slots=True)
class _SourceDestinationLayout:
root: Path
spatial: Path | None
camera_epoch: int
camera_epoch_root: Path
camera_segments: Path
def destination(self, member: _SourceMember) -> Path:
if member.kind == "source-bundle":
return self.root / "source-bundle.json"
if member.kind == "source-capability":
return self.root / "source-capability.json"
if member.kind == "spatial-replay":
if member.primary:
return self.root / "mqtt.raw.k1mqtt"
if self.spatial is None:
raise ObservatoryWorkerHttpError(
"spatial source destination is unavailable"
)
return self.spatial / member.member_id
if member.kind == "spatial-replay-metadata":
return self.root / "mqtt.metadata.jsonl"
if member.camera_epoch != self.camera_epoch:
raise ObservatoryWorkerHttpError("camera source member has another epoch")
if member.kind == "camera-init":
return self.camera_epoch_root / "init.mp4"
if member.camera_sequence is None:
raise ObservatoryWorkerHttpError("camera segment has no sequence")
return self.camera_segments / f"{member.camera_sequence}.m4s"
@dataclass(frozen=True, slots=True)
class _UploadMember:
member_id: str
@@ -305,9 +337,10 @@ class ObservatoryWorkerHttpGateway(ObservatoryWorkerTransport):
/ f"generation-{job.claim_generation}"
/ job.source_bundle_sha256
)
layout = _prepare_source_destination_layout(root, members)
destinations: dict[Path, _SourceMember] = {}
for member in members:
destination = _source_destination(root, member)
destination = layout.destination(member)
if destination in destinations:
raise ObservatoryWorkerHttpError(
"source materialization members select the same local role"
@@ -316,7 +349,7 @@ class ObservatoryWorkerHttpGateway(ObservatoryWorkerTransport):
camera_members = _ordered_camera_epoch_members(members)
if not all(
_matches_file(
_source_destination(root, member),
layout.destination(member),
member.sha256,
member.byte_length,
)
@@ -1217,6 +1250,51 @@ def _copy_camera_archive_member(
destination.unlink()
def _prepare_source_destination_layout(
root: Path,
members: tuple[_SourceMember, ...],
) -> _SourceDestinationLayout:
camera_inits = tuple(
member for member in members if member.kind == "camera-init"
)
if len(camera_inits) != 1 or camera_inits[0].camera_epoch is None:
raise ObservatoryWorkerHttpError(
"source materialization camera epoch is incomplete"
)
camera_epoch = camera_inits[0].camera_epoch
camera_root = _secure_source_subdirectory(root, root / "camera")
camera_epoch_root = _secure_source_subdirectory(
root,
camera_root / f"epoch-{camera_epoch}",
)
camera_segments = _secure_source_subdirectory(
root,
camera_epoch_root / "segments",
)
spatial = None
if any(
member.kind == "spatial-replay" and not member.primary
for member in members
):
spatial = _secure_source_subdirectory(root, root / "spatial")
return _SourceDestinationLayout(
root=root,
spatial=spatial,
camera_epoch=camera_epoch,
camera_epoch_root=camera_epoch_root,
camera_segments=camera_segments,
)
def _secure_source_subdirectory(root: Path, candidate: Path) -> Path:
resolved = _secure_directory(candidate)
if not resolved.is_relative_to(root):
raise ObservatoryWorkerHttpError(
"source materialization destination escapes its root"
)
return resolved
def _source_destination(root: Path, member: _SourceMember) -> Path:
if member.kind == "source-bundle":
return root / "source-bundle.json"