getSnapshot method
Loads a snapshot either by its snapshotId or by sessionId.
Exactly one of snapshotId / sessionId must be provided. A sessionId
resolves to the session's latest leaf snapshot (the most recent snapshot
that no other snapshot points to as its parent). A branched history (more
than one leaf) resolves to the most-recently created leaf by default, or
is rejected with StatusCodes.FAILED_PRECONDITION when the store is
configured to reject branching.
context carries the ambient request/action context (e.g. the
authenticated user) so multi-tenant stores can route reads.
Implementation
@override
Future<SessionSnapshot?> getSnapshot({
String? snapshotId,
String? sessionId,
Map<String, dynamic>? context,
}) {
final normalized = _normalizeGetSnapshotOptions(snapshotId, sessionId);
// Reconstruct inside a read-only transaction so the pointer read and the
// batched shard/diff reads all observe a single, consistent point in time.
// Without this, a concurrent checkpoint write - which overwrites a
// checkpoint's shards in place and may delete now-stale trailing shards
// (see `_writeShards`) - could let a reader stitch together a mix of old
// and new chunks, yielding a `DATA_LOSS` (missing shard) error or a corrupt
// JSON decode. A read-only transaction also avoids the contention/retries
// of a read-write one.
return db.runTransaction((tx) async {
final reader = _Reader(tx);
if (normalized.sessionId != null) {
final pointerSnap = await tx.get(
_pointersCol(context).doc(normalized.sessionId!),
);
if (!pointerSnap.exists) return null;
final pointer = _PointerDoc.fromData(pointerSnap.data()!);
// Reconstruct straight from the pointer's checkpoint metadata - one
// batched round-trip, no extra read of the leaf document.
final reconstructed = await _reconstructFrom(
reader,
pointer.checkpointId,
pointer.checkpointShardCount,
pointer.segmentPath,
pointer.currentSnapshotId,
context,
);
if (reconstructed == null) return null;
return _toSnapshot(reconstructed.doc, reconstructed.state);
}
final reconstructed = await _reconstruct(
reader,
normalized.snapshotId!,
context,
);
if (reconstructed == null) return null;
return _toSnapshot(reconstructed.doc, reconstructed.state);
}, transactionOptions: ReadOnlyTransactionOptions());
}