fix(archive): preserve prepared sessions across restarts
This commit is contained in:
@@ -57,22 +57,26 @@ not mutate playback state, so changing accumulation, size, color or visibility
|
||||
does not pause the active replay or replace its camera view.
|
||||
|
||||
Completed and recovered sessions are discovered on startup and by the catalog
|
||||
reconciler, then deduplicated into one bounded, single-worker preparation queue.
|
||||
The worker validates the native source, exports point/pose data, verifies source
|
||||
stability and both SHA-256 digests, finalizes once, and atomically publishes the
|
||||
reconciler. The first scan is only a historical baseline: it never enqueues the
|
||||
existing archive. A session that becomes finalized after that baseline is
|
||||
deduplicated into the bounded, single-worker preparation queue. The worker
|
||||
validates the native source, exports point/pose data, verifies source stability
|
||||
and both SHA-256 digests, finalizes once, and atomically publishes the
|
||||
digest-bound derived RRD plus its cache sidecar. Before the same job becomes
|
||||
`ready`, it also parses and validates every archived camera index and retains
|
||||
the immutable manifest generation in memory. The catalog exposes preparation
|
||||
state and progress while this runs; a recording URL and camera descriptors are
|
||||
returned only after the complete launch generation has passed validation.
|
||||
`ready`, it also parses and validates every archived camera index and publishes
|
||||
the immutable media-manifest sidecar. The catalog exposes preparation state and
|
||||
progress while this runs; a recording URL and camera descriptors are returned
|
||||
only after the complete launch generation has passed validation.
|
||||
|
||||
Preparation is a backend lifecycle, not a viewer action: sealing or recovering
|
||||
a native session makes it eligible for the reconciler, which builds the derived
|
||||
RRD once in the background. Reopening, seeking or changing the workspace reads
|
||||
that prepared artifact and never reruns conversion. A cold process may validate
|
||||
an existing cache and rebuild its in-memory camera manifest in the worker, but
|
||||
no replay, status, RRD or manifest request hashes native evidence or parses a
|
||||
camera index synchronously.
|
||||
Preparation is a backend lifecycle, not a viewer computation. Reopening,
|
||||
seeking, refreshing the catalog or changing the workspace never reruns a
|
||||
published conversion. After a process restart, a catalog/replay read restores a
|
||||
complete compatible RRD and camera package from its durable sidecars using
|
||||
bounded schema and stat-identity checks; it does not hash native evidence, parse
|
||||
camera indexes or invoke the exporter. A historical session whose package is
|
||||
missing, stale or from an incompatible cache schema remains cold. Only an
|
||||
explicit replay/RRD request schedules that one session for preparation; listing
|
||||
the catalog and finalizing another session do not schedule it.
|
||||
|
||||
The session menu uses three operator indicators:
|
||||
|
||||
@@ -80,6 +84,7 @@ The session menu uses three operator indicators:
|
||||
| --- | --- | --- |
|
||||
| Solid green + `Готово` | `ready` | Verified RRD is available. |
|
||||
| Pulsing green + `Обработка` | `queued`, `validating`, `exporting`, `finalizing` | Background preparation is active. |
|
||||
| Solid gray + `Подготовить` | replayable session with no compatible published package | No work is running; choosing the row schedules this session only. |
|
||||
| Dim gray + `Ошибка` | failed, cancelled, non-replayable or invalid session | No launchable recording; inspect the message or retry. |
|
||||
|
||||
Saved-session status never uses yellow or red. Switching sessions aborts only
|
||||
@@ -93,7 +98,8 @@ Later openings reuse a verified, digest-bound cache. Derived RRD cache v9 is
|
||||
intentionally incompatible with v8 and older generations. In addition to plugin
|
||||
and ordered-artifact identity, it binds the durable clock origin and active
|
||||
envelope and materializes real `session_time = 0` origin and sealed completion
|
||||
rows. Older generations are rebuilt once in the background.
|
||||
rows. Older generations remain cold after startup and are rebuilt only when an
|
||||
operator explicitly opens that session.
|
||||
The browser may use the strict `source_url` with `If-Match`, while the embedded
|
||||
Rerun loader uses the canonical `viewer_source_url` whose lowercase SHA-256
|
||||
`generation` query is bound to the same launch descriptor. A missing or stale
|
||||
@@ -194,11 +200,13 @@ Native `.k1mqtt` bytes with aligned metadata, the capture-clock artifacts and
|
||||
canonical camera fMP4 archives are the evidence source of truth. The derived RRD
|
||||
contains every decodable point and pose frame plus every valid `ModelingReport`
|
||||
distance/speed/scan-time sample from that source, but remains a rebuildable view
|
||||
rather than an evidence master. A cache entry is rebuilt only when native source
|
||||
identity/digests change or an incompatible derived-data export revision is
|
||||
introduced. A UI blueprint or workspace-layout revision never invalidates or
|
||||
rewrites the data RRD. Cache v8 and older payloads are not reusable as v9 because
|
||||
they do not bind both real capture-envelope endpoints.
|
||||
rather than an evidence master. A cache entry is eligible for rebuild only when
|
||||
native source identity/digests change or an incompatible derived-data export
|
||||
revision is introduced. Historical entries are not rebuilt during startup or
|
||||
because another session is finalized; an explicit open schedules the affected
|
||||
entry. A UI blueprint or workspace-layout revision never invalidates or rewrites
|
||||
the data RRD. Cache v8 and older payloads are not reusable as v9 because they do
|
||||
not bind both real capture-envelope endpoints.
|
||||
|
||||
`ModelingReport` time is the device's `ScanTime` counter at two ticks per second;
|
||||
distance and speed are the reported `MoveDistance`/`MoveSpeed` values. Live state
|
||||
@@ -318,9 +326,10 @@ written under the private derived cache with a schema, generation and checksum.
|
||||
Publication uses a private temporary file, file and directory `fsync`, and atomic
|
||||
rename; startup scavenges crash-left temporary files. A restart reuses this
|
||||
sidecar after confined O(n) stat validation, without rereading, hashing or parsing
|
||||
media. A missing, corrupt or stale sidecar is rebuilt only by the background
|
||||
worker. No replay, status, manifest or payload request performs conversion or
|
||||
recalculates these intervals.
|
||||
media. A missing, corrupt or stale sidecar remains cold until an explicit open
|
||||
schedules the complete session package in the background worker. No catalog,
|
||||
status, manifest or payload request itself performs conversion or recalculates
|
||||
these intervals.
|
||||
|
||||
Every derived RRD contains a real `session_time = 0` row at the internal
|
||||
`/__mission_core/session_origin` entity. The anchor is deliberately outside
|
||||
|
||||
Reference in New Issue
Block a user