Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Loader and driver changes for Data Virtualization #19314

Merged
merged 11 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/four-tables-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@fluidframework/container-definitions": minor
"@fluidframework/container-loader": minor
"@fluidframework/driver-definitions": minor
"@fluidframework/driver-utils": minor
"@fluidframework/file-driver": minor
"@fluidframework/odsp-driver": minor
---

Deprecate `ISnapshotContents`

`ISnapshotContents` is deprecated. It has been replaced with `ISnapshot`.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { IResolvedUrl } from '@fluidframework/driver-definitions';
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
import { ISequencedProposal } from '@fluidframework/protocol-definitions';
import { ISignalMessage } from '@fluidframework/protocol-definitions';
import { ISnapshot } from '@fluidframework/driver-definitions';
import { ISnapshotTree } from '@fluidframework/protocol-definitions';
import { ISummaryContent } from '@fluidframework/protocol-definitions';
import { ISummaryTree } from '@fluidframework/protocol-definitions';
Expand Down Expand Up @@ -176,6 +177,7 @@ export interface IContainerContext {
// (undocumented)
readonly quorum: IQuorumClients;
readonly scope: FluidObject;
readonly snapshotWithContents?: ISnapshot;
// (undocumented)
readonly storage: IDocumentStorageService;
// (undocumented)
Expand Down
7 changes: 6 additions & 1 deletion packages/common/container-definitions/src/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { ITelemetryBaseLogger, IDisposable, FluidObject } from "@fluidframework/core-interfaces";

import { IDocumentStorageService } from "@fluidframework/driver-definitions";
import { IDocumentStorageService, ISnapshot } from "@fluidframework/driver-definitions";
import {
IClientDetails,
ISequencedDocumentMessage,
Expand Down Expand Up @@ -198,6 +198,11 @@ export interface IContainerContext {
* @privateremarks Tracking in AB#5714
*/
readonly id: string;

/**
* This contains all parts of a snapshot like blobContents, ops etc.
*/
readonly snapshotWithContents?: ISnapshot;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,14 @@ export interface IDocumentServiceFactory {
export interface IDocumentServicePolicies {
readonly storageOnly?: boolean;
readonly summarizeProtocolTree?: boolean;
readonly supportGetSnapshotApi?: boolean;
}

// @alpha
export interface IDocumentStorageService extends Partial<IDisposable> {
createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse>;
downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree>;
getSnapshot?(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot>;
getSnapshotTree(version?: IVersion, scenarioName?: string): Promise<ISnapshotTree | null>;
getVersions(versionId: string | null, count: number, scenarioName?: string, fetchSource?: FetchSource): Promise<IVersion[]>;
readonly policies?: IDocumentStorageServicePolicies;
Expand Down Expand Up @@ -255,6 +257,27 @@ export interface IResolvedUrl {
url: string;
}

// @alpha (undocumented)
jatgarg marked this conversation as resolved.
Show resolved Hide resolved
export interface ISnapshot {
// (undocumented)
blobContents: Map<string, ArrayBuffer>;
latestSequenceNumber: number | undefined;
// (undocumented)
ops: ISequencedDocumentMessage[];
sequenceNumber: number | undefined;
// (undocumented)
snapshotFormatV: 1;
// (undocumented)
snapshotTree: ISnapshotTree;
}

// @alpha
export interface ISnapshotFetchOptions {
cacheSnapshot?: boolean;
scenarioName?: string;
versionId?: string;
}

// @alpha
export interface IStream<T> {
// (undocumented)
Expand Down
2 changes: 2 additions & 0 deletions packages/common/driver-definitions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export {
IDocumentServicePolicies,
IDocumentStorageService,
IDocumentStorageServicePolicies,
ISnapshot,
ISnapshotFetchOptions,
IStream,
IStreamResult,
ISummaryContext,
Expand Down
60 changes: 60 additions & 0 deletions packages/common/driver-definitions/src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ export interface IDocumentStorageService extends Partial<IDisposable> {
// eslint-disable-next-line @rushstack/no-new-null
getSnapshotTree(version?: IVersion, scenarioName?: string): Promise<ISnapshotTree | null>;

/**
* Returns the snapshot which can contain other artifacts too like blob contents, ops etc. It is different from
* `getSnapshotTree` api in that, that API only returns the snapshot tree from the snapshot.
* @param snapshotFetchOptions - Options specified by the caller to specify and want certain behavior from the
* driver when fetching the snapshot.
*/
getSnapshot?(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot>;

/**
* Retrieves all versions of the document starting at the specified versionId - or null if from the head
* @param versionId - Version id of the requested version.
Expand Down Expand Up @@ -341,6 +349,13 @@ export interface IDocumentServicePolicies {
* Summarizer uploads the protocol tree too when summarizing.
*/
readonly summarizeProtocolTree?: boolean;

/**
* Whether the driver supports the new getSnapshot api which returns snapshot which
* contains all contents along with the snapshot tree. Enable this by default when the
* driver can fully support the api.
*/
readonly supportGetSnapshotApi?: boolean;
}

/**
Expand Down Expand Up @@ -450,3 +465,48 @@ export enum FetchSource {
default = "default",
noCache = "noCache",
}

/**
* @alpha
*/
export interface ISnapshot {
snapshotTree: ISnapshotTree;
blobContents: Map<string, ArrayBuffer>;
ops: ISequencedDocumentMessage[];

/**
* Sequence number of the snapshot
*/
sequenceNumber: number | undefined;

/**
* Sequence number for the latest op/snapshot for the file in ODSP
*/
latestSequenceNumber: number | undefined;

snapshotFormatV: 1;
}

/**
* Snapshot fetch options which are used to communicate different things to the driver
* when fetching the snapshot.
* @alpha
*/
export interface ISnapshotFetchOptions {
jatgarg marked this conversation as resolved.
Show resolved Hide resolved
/**
* Indicates scenario in which the snapshot is fetched. It is a free form string mostly
* used for telemetry purposes.
*/
scenarioName?: string;
/**
* Tell driver to cache the fetched snapshot. Driver is supposed to cache the fetched snapshot if this is
* set to true. If undefined, then it is upto the driver, to cache it or not.
*/
cacheSnapshot?: boolean;

/**
* Version of the snapshot to be fetched. Certain storage services just keep 1 snapshot for the
* container, so specifying version is not necessary for storage services.
*/
versionId?: string;
}
4 changes: 4 additions & 0 deletions packages/drivers/file-driver/api-report/file-driver.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { IResolvedUrl } from '@fluidframework/driver-definitions';
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
import { ISignalClient } from '@fluidframework/protocol-definitions';
import { ISignalMessage } from '@fluidframework/protocol-definitions';
import { ISnapshot } from '@fluidframework/driver-definitions';
import { ISnapshotFetchOptions } from '@fluidframework/driver-definitions';
import { IStream } from '@fluidframework/driver-definitions';
import { ISummaryContext } from '@fluidframework/driver-definitions';
import { ISummaryTree } from '@fluidframework/protocol-definitions';
Expand Down Expand Up @@ -63,6 +65,7 @@ export const FileSnapshotWriterClassFactory: <TBase extends ReaderConstructor>(B
buildTree(snapshotTree: api.ISnapshotTree): Promise<api.ITree>;
repositoryUrl: string;
readonly policies?: IDocumentStorageServicePolicies | undefined;
getSnapshot?(snapshotFetchOptions?: ISnapshotFetchOptions | undefined): Promise<ISnapshot>;
createBlob(file: ArrayBufferLike): Promise<api.ICreateBlobResponse>;
downloadSummary(handle: api.ISummaryHandle): Promise<api.ISummaryTree>;
readonly disposed?: boolean | undefined;
Expand Down Expand Up @@ -99,6 +102,7 @@ export const FluidFetchReaderFileSnapshotWriter: {
buildTree(snapshotTree: api.ISnapshotTree): Promise<api.ITree>;
repositoryUrl: string;
readonly policies?: IDocumentStorageServicePolicies | undefined;
getSnapshot?(snapshotFetchOptions?: ISnapshotFetchOptions | undefined): Promise<ISnapshot>;
createBlob(file: ArrayBufferLike): Promise<api.ICreateBlobResponse>;
downloadSummary(handle: api.ISummaryHandle): Promise<api.ISummaryTree>;
readonly disposed?: boolean | undefined;
Expand Down
7 changes: 4 additions & 3 deletions packages/drivers/odsp-driver/api-report/odsp-driver.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IRequest } from '@fluidframework/core-interfaces';
import { IResolvedUrl } from '@fluidframework/driver-definitions';
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
import { ISharingLinkKind } from '@fluidframework/odsp-driver-definitions';
import { ISnapshot } from '@fluidframework/driver-definitions';
import { ISnapshotOptions } from '@fluidframework/odsp-driver-definitions';
import { ISnapshotTree } from '@fluidframework/protocol-definitions';
import { ISocketStorageDiscovery } from '@fluidframework/odsp-driver-definitions';
Expand Down Expand Up @@ -159,7 +160,7 @@ export interface IPersistedFileCache {
}

// @alpha (undocumented)
export interface IPrefetchSnapshotContents extends ISnapshotContents {
export interface IPrefetchSnapshotContents extends ISnapshot {
// (undocumented)
fluidEpoch: string;
// (undocumented)
Expand All @@ -172,7 +173,7 @@ export interface ISharingLinkHeader {
[SharingLinkHeader.isSharingLinkToRedeem]: boolean;
}

// @alpha (undocumented)
// @alpha @deprecated (undocumented)
export interface ISnapshotContents {
// (undocumented)
blobs: Map<string, ArrayBuffer>;
Expand All @@ -185,7 +186,7 @@ export interface ISnapshotContents {
}

// @internal
export interface ISnapshotContentsWithProps extends ISnapshotContents {
export interface ISnapshotContentsWithProps extends ISnapshot {
// (undocumented)
telemetryProps: Record<string, number>;
}
Expand Down
11 changes: 10 additions & 1 deletion packages/drivers/odsp-driver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@
}
},
"typeValidation": {
"broken": {}
"broken": {
"InterfaceDeclaration_ISnapshotContentsWithProps": {
"backCompat": false,
"forwardCompat": false
},
"InterfaceDeclaration_IPrefetchSnapshotContents": {
"backCompat": false,
"forwardCompat": false
}
}
}
}
19 changes: 10 additions & 9 deletions packages/drivers/odsp-driver/src/compactSnapshotParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { assert } from "@fluidframework/core-utils";
import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
import { ISnapshotContents } from "./odspPublicUtils";
import { ISnapshot } from "@fluidframework/driver-definitions";
import { ReadBuffer } from "./ReadBufferUtils";
import {
assertBlobCoreInstance,
Expand All @@ -29,7 +29,7 @@ export const currentReadVersion = "1.0";
* represents how many times slower parsing path is executed. This will be then logged into telemetry.
* @internal
*/
export interface ISnapshotContentsWithProps extends ISnapshotContents {
export interface ISnapshotContentsWithProps extends ISnapshot {
telemetryProps: Record<string, number>;
}

Expand All @@ -40,7 +40,7 @@ export interface ISnapshotContentsWithProps extends ISnapshotContents {
function readBlobSection(node: NodeTypes) {
assertNodeCoreInstance(node, "TreeBlobs should be of type NodeCore");
let slowBlobStructureCount = 0;
const blobs: Map<string, ArrayBuffer> = new Map();
const blobContents: Map<string, ArrayBuffer> = new Map();
for (const blob of node) {
assertNodeCoreInstance(blob, "blob should be node");

Expand All @@ -56,7 +56,7 @@ function readBlobSection(node: NodeTypes) {
) {
// "id": <node name>
// "data": <blob>
blobs.set(blob.getString(1), blob.getBlob(3).arrayBuffer);
blobContents.set(blob.getString(1), blob.getBlob(3).arrayBuffer);
continue;
}

Expand All @@ -67,9 +67,9 @@ function readBlobSection(node: NodeTypes) {
const records = getNodeProps(blob);
assertBlobCoreInstance(records.data, "data should be of BlobCore type");
const id = getStringInstance(records.id, "blob id should be string");
blobs.set(id, records.data.arrayBuffer);
blobContents.set(id, records.data.arrayBuffer);
}
return { blobs, slowBlobStructureCount };
return { blobContents, slowBlobStructureCount };
}

/**
Expand Down Expand Up @@ -249,19 +249,20 @@ export function parseCompactSnapshotResponse(
);

const [snapshot, durationSnapshotTree] = measure(() => readSnapshotSection(records.snapshot));
const [blobs, durationBlobs] = measure(() => readBlobSection(records.blobs));
const [blobContents, durationBlobs] = measure(() => readBlobSection(records.blobs));

return {
...snapshot,
...blobs,
...blobContents,
ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],
latestSequenceNumber: records.lsn,
snapshotFormatV: 1,
telemetryProps: {
...telemetryProps,
durationSnapshotTree,
durationBlobs,
slowTreeStructureCount: snapshot.slowTreeStructureCount,
slowBlobStructureCount: blobs.slowBlobStructureCount,
slowBlobStructureCount: blobContents.slowBlobStructureCount,
},
};
}
6 changes: 3 additions & 3 deletions packages/drivers/odsp-driver/src/compactSnapshotWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
ISequencedDocumentMessage,
ISnapshotTree,
} from "@fluidframework/protocol-definitions";
import { ISnapshot } from "@fluidframework/driver-definitions";
import { snapshotMinReadVersion } from "./compactSnapshotParser";
import { ISnapshotContents } from "./odspPublicUtils";
import { TreeBuilderSerializer } from "./WriteBufferUtils";
import {
addBoolProperty,
Expand Down Expand Up @@ -144,7 +144,7 @@ function writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {
* @param snapshotContents - snapshot tree contents to serialize
* @returns ReadBuffer - binary representation of the data.
*/
export function convertToCompactSnapshot(snapshotContents: ISnapshotContents): Uint8Array {
export function convertToCompactSnapshot(snapshotContents: ISnapshot): Uint8Array {
const builder = new TreeBuilderSerializer();
// Create the root node.
const rootNode = builder.addNode();
Expand All @@ -166,7 +166,7 @@ export function convertToCompactSnapshot(snapshotContents: ISnapshotContents): U
writeSnapshotSection(rootNode, snapshotContents.snapshotTree, snapshotContents.sequenceNumber);

// Add Blobs
writeBlobsSection(rootNode, snapshotContents.blobs);
writeBlobsSection(rootNode, snapshotContents.blobContents);

// Then write the ops node.
writeOpsSection(rootNode, snapshotContents.ops);
Expand Down
12 changes: 12 additions & 0 deletions packages/drivers/odsp-driver/src/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import * as api from "@fluidframework/protocol-definitions";
import { HostStoragePolicy } from "@fluidframework/odsp-driver-definitions";
import { ISnapshot } from "@fluidframework/driver-definitions";
import { ISnapshotContents } from "./odspPublicUtils";

/**
Expand Down Expand Up @@ -165,6 +166,8 @@ export interface IOdspSnapshot {
*/
export interface HostStoragePolicyInternal extends HostStoragePolicy {
summarizerClient?: boolean;

supportGetSnapshotApi?: boolean;
}

export interface ICreateFileResponse {
Expand Down Expand Up @@ -207,11 +210,20 @@ export interface IFlushOpsResponse {

/**
* Represents the cached snapshot value.
* @deprecated - This will be replaced with ISnapshotCachedEntry2 which wraps the new ISnapshot interface.
* For now, to support back compat from cache, we need to keep it for now.
*/
export interface ISnapshotCachedEntry extends ISnapshotContents {
cacheEntryTime: number;
}

/**
* Represents the cached snapshot value.
*/
export interface ISnapshotCachedEntry2 extends ISnapshot {
cacheEntryTime: number;
}

/**
* Represents the type of signal containing the sensitivity policy labels for the container.
*/
Expand Down
Loading
Loading