@fluidframework/datastore 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.2.0.153917
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +38 -0
- package/dist/channelContext.d.ts +2 -2
- package/dist/channelContext.d.ts.map +1 -1
- package/dist/channelContext.js +2 -2
- package/dist/channelContext.js.map +1 -1
- package/dist/dataStoreRuntime.d.ts +14 -9
- package/dist/dataStoreRuntime.d.ts.map +1 -1
- package/dist/dataStoreRuntime.js +47 -48
- package/dist/dataStoreRuntime.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/remoteChannelContext.d.ts +2 -2
- package/dist/remoteChannelContext.d.ts.map +1 -1
- package/dist/remoteChannelContext.js +41 -60
- package/dist/remoteChannelContext.js.map +1 -1
- package/lib/channelContext.d.ts +2 -2
- package/lib/channelContext.d.ts.map +1 -1
- package/lib/channelContext.js +2 -2
- package/lib/channelContext.js.map +1 -1
- package/lib/dataStoreRuntime.d.ts +14 -9
- package/lib/dataStoreRuntime.d.ts.map +1 -1
- package/lib/dataStoreRuntime.js +48 -49
- package/lib/dataStoreRuntime.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/remoteChannelContext.d.ts +2 -2
- package/lib/remoteChannelContext.d.ts.map +1 -1
- package/lib/remoteChannelContext.js +41 -60
- package/lib/remoteChannelContext.js.map +1 -1
- package/package.json +58 -59
- package/src/channelContext.ts +8 -1
- package/src/dataStoreRuntime.ts +77 -68
- package/src/packageVersion.ts +1 -1
- package/src/remoteChannelContext.ts +49 -60
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteChannelContext.js","sourceRoot":"","sources":["../src/remoteChannelContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { DataCorruptionError } from \"@fluidframework/container-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelFactory,\n} from \"@fluidframework/datastore-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tCreateChildSummarizerNodeFn,\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeInternalResult,\n\tISummarizeResult,\n\tISummarizerNodeWithGC,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { ChildLogger, TelemetryDataTag, ThresholdCounter } from \"@fluidframework/telemetry-utils\";\nimport {\n\tattributesBlobKey,\n\tcreateServiceEndpoints,\n\tIChannelContext,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ChannelDeltaConnection } from \"./channelDeltaConnection\";\nimport { ChannelStorageService } from \"./channelStorageService\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\nexport class RemoteChannelContext implements IChannelContext {\n\tprivate isLoaded = false;\n\tprivate pending: ISequencedDocumentMessage[] | undefined = [];\n\tprivate channelP: Promise<IChannel> | undefined;\n\tprivate channel: IChannel | undefined;\n\tprivate readonly services: {\n\t\treadonly deltaConnection: ChannelDeltaConnection;\n\t\treadonly objectStorage: ChannelStorageService;\n\t};\n\tprivate readonly summarizerNode: ISummarizerNodeWithGC;\n\tprivate readonly subLogger: ITelemetryLogger;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\tprivate readonly dataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly id: string,\n\t\tbaseSnapshot: ISnapshotTree,\n\t\tprivate readonly registry: ISharedObjectRegistry,\n\t\textraBlobs: Map<string, ArrayBufferLike> | undefined,\n\t\tcreateSummarizerNode: CreateChildSummarizerNodeFn,\n\t\tgetBaseGCDetails: () => Promise<IGarbageCollectionDetailsBase>,\n\t\tprivate readonly attachMessageType?: string,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x310 /* Channel context ID cannot contain slashes */);\n\n\t\tthis.subLogger = ChildLogger.create(this.runtime.logger, \"RemoteChannelContext\");\n\n\t\tthis.services = createServiceEndpoints(\n\t\t\tthis.id,\n\t\t\tthis.dataStoreContext.connected,\n\t\t\tsubmitFn,\n\t\t\t() => dirtyFn(this.id),\n\t\t\taddedGCOutboundReferenceFn,\n\t\t\tstorageService,\n\t\t\tthis.subLogger,\n\t\t\tbaseSnapshot,\n\t\t\textraBlobs,\n\t\t);\n\n\t\tconst thisSummarizeInternal = async (\n\t\t\tfullTree: boolean,\n\t\t\ttrackState: boolean,\n\t\t\ttelemetryContext?: ITelemetryContext,\n\t\t) => this.summarizeInternal(fullTree, trackState, telemetryContext);\n\n\t\tthis.summarizerNode = createSummarizerNode(\n\t\t\tthisSummarizeInternal,\n\t\t\tasync (fullGC?: boolean) => this.getGCDataInternal(fullGC),\n\t\t\tasync () => getBaseGCDetails(),\n\t\t);\n\n\t\tthis.thresholdOpsCounter = new ThresholdCounter(\n\t\t\tRemoteChannelContext.pendingOpsCountThreshold,\n\t\t\tthis.subLogger,\n\t\t);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\tpublic getChannel(): Promise<IChannel> {\n\t\tif (this.channelP === undefined) {\n\t\t\tthis.channelP = this.loadChannel();\n\t\t}\n\n\t\treturn this.channelP;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet loaded\n\t\tif (!this.isLoaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.services.deltaConnection.setConnectionState(connected);\n\t}\n\n\tpublic applyStashedOp(message: ISequencedDocumentMessage): unknown {\n\t\tassert(this.isLoaded, 0x194 /* \"Remote channel must be loaded when rebasing op\" */);\n\t\treturn this.services.deltaConnection.applyStashedOp(message);\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tthis.summarizerNode.invalidate(message.sequenceNumber);\n\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(!local, 0x195 /* \"Remote channel must not be local when processing op\" */);\n\t\t\tassert(this.pending !== undefined, 0x23e /* \"pending is undefined\" */);\n\t\t\tthis.pending.push(message);\n\t\t\tthis.thresholdOpsCounter.sendIfMultiple(\"StorePendingOps\", this.pending.length);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x196 /* \"Remote channel must be loaded when resubmitting op\" */);\n\n\t\tthis.services.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2f0 /* \"Remote channel must be loaded when rolling back op\" */);\n\n\t\tthis.services.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = true,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\treturn this.summarizerNode.summarize(fullTree, trackState, telemetryContext);\n\t}\n\n\tprivate async summarizeInternal(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeInternalResult> {\n\t\tconst channel = await this.getChannel();\n\t\tconst summarizeResult = await summarizeChannelAsync(\n\t\t\tchannel,\n\t\t\tfullTree,\n\t\t\ttrackState,\n\t\t\ttelemetryContext,\n\t\t);\n\t\treturn { ...summarizeResult, id: this.id };\n\t}\n\n\tprivate async loadChannel(): Promise<IChannel> {\n\t\tassert(\n\t\t\t!this.isLoaded,\n\t\t\t0x197 /* \"Remote channel must not already be loaded when loading\" */,\n\t\t);\n\n\t\tlet attributes: IChannelAttributes | undefined;\n\t\tif (await this.services.objectStorage.contains(attributesBlobKey)) {\n\t\t\tattributes = await readAndParse<IChannelAttributes | undefined>(\n\t\t\t\tthis.services.objectStorage,\n\t\t\t\tattributesBlobKey,\n\t\t\t);\n\t\t}\n\n\t\tlet factory: IChannelFactory | undefined;\n\t\t// this is a backward compatibility case where\n\t\t// the attach message doesn't include\n\t\t// the attributes. Since old attach messages\n\t\t// will not have attributes we need to keep\n\t\t// this as long as we support old attach messages\n\t\tif (attributes === undefined) {\n\t\t\tif (this.attachMessageType === undefined) {\n\t\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\t\tthrow new DataCorruptionError(\"channelTypeNotAvailable\", {\n\t\t\t\t\tchannelId: {\n\t\t\t\t\t\tvalue: this.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStoreId: {\n\t\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfactory = this.registry.get(this.attachMessageType);\n\t\t\tif (factory === undefined) {\n\t\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\t\tthrow new DataCorruptionError(\"channelFactoryNotRegisteredForAttachMessageType\", {\n\t\t\t\t\tchannelId: {\n\t\t\t\t\t\tvalue: this.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStoreId: {\n\t\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\t\tchannelFactoryType: this.attachMessageType,\n\t\t\t\t});\n\t\t\t}\n\t\t\tattributes = factory.attributes;\n\t\t} else {\n\t\t\tfactory = this.registry.get(attributes.type);\n\t\t\tif (factory === undefined) {\n\t\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\t\tthrow new DataCorruptionError(\"channelFactoryNotRegisteredForGivenType\", {\n\t\t\t\t\tchannelId: {\n\t\t\t\t\t\tvalue: this.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStoreId: {\n\t\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\t\tchannelFactoryType: attributes.type,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Compare snapshot version to collaborative object version\n\t\tif (\n\t\t\tattributes.snapshotFormatVersion !== undefined &&\n\t\t\tattributes.snapshotFormatVersion !== factory.attributes.snapshotFormatVersion\n\t\t) {\n\t\t\tthis.subLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"ChannelAttributesVersionMismatch\",\n\t\t\t\tchannelType: { value: attributes.type, tag: TelemetryDataTag.CodeArtifact },\n\t\t\t\tchannelSnapshotVersion: {\n\t\t\t\t\tvalue: `${attributes.snapshotFormatVersion}@${attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tchannelCodeVersion: {\n\t\t\t\t\tvalue: `${factory.attributes.snapshotFormatVersion}@${factory.attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconst channel = await factory.load(this.runtime, this.id, this.services, attributes);\n\n\t\t// Send all pending messages to the channel\n\t\tassert(this.pending !== undefined, 0x23f /* \"pending undefined\" */);\n\t\tfor (const message of this.pending) {\n\t\t\tthis.services.deltaConnection.process(message, false, undefined /* localOpMetadata */);\n\t\t}\n\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pending.length);\n\n\t\t// Commit changes.\n\t\tthis.channel = channel;\n\t\tthis.pending = undefined;\n\t\tthis.isLoaded = true;\n\n\t\t// Because have some await between we created the service and here, the connection state might have changed\n\t\t// and we don't propagate the connection state when we are not loaded. So we have to set it again here.\n\t\tthis.services.deltaConnection.setConnectionState(this.dataStoreContext.connected);\n\t\treturn this.channel;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document.\n\t * If there is no new data in this context since the last summary, previous GC data is used.\n\t * If there is new data, the GC data is generated again (by calling getGCDataInternal).\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\treturn this.summarizerNode.getGCData(fullGC);\n\t}\n\n\t/**\n\t * Generates the data used for garbage collection. This is called when there is new data since last summary. It\n\t * loads the context and calls into the channel to get its GC data.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tprivate async getGCDataInternal(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected. Update the summarizer node's\n\t\t * used routes to contain a route to this channel context.\n\t\t * Once we have GC at DDS level, this will be updated to use the passed usedRoutes. See -\n\t\t * https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t\tthis.summarizerNode.updateUsedRoutes([\"\"]);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteChannelContext.js","sourceRoot":"","sources":["../src/remoteChannelContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { DataCorruptionError } from \"@fluidframework/container-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tCreateChildSummarizerNodeFn,\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tIExperimentalIncrementalSummaryContext,\n\tISummarizeInternalResult,\n\tISummarizeResult,\n\tISummarizerNodeWithGC,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { ChildLogger, TelemetryDataTag, ThresholdCounter } from \"@fluidframework/telemetry-utils\";\nimport {\n\tattributesBlobKey,\n\tcreateServiceEndpoints,\n\tIChannelContext,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ChannelDeltaConnection } from \"./channelDeltaConnection\";\nimport { ChannelStorageService } from \"./channelStorageService\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\nexport class RemoteChannelContext implements IChannelContext {\n\tprivate isLoaded = false;\n\tprivate pending: ISequencedDocumentMessage[] | undefined = [];\n\tprivate channelP: Promise<IChannel> | undefined;\n\tprivate channel: IChannel | undefined;\n\tprivate readonly services: {\n\t\treadonly deltaConnection: ChannelDeltaConnection;\n\t\treadonly objectStorage: ChannelStorageService;\n\t};\n\tprivate readonly summarizerNode: ISummarizerNodeWithGC;\n\tprivate readonly subLogger: ITelemetryLogger;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\tprivate readonly dataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly id: string,\n\t\tbaseSnapshot: ISnapshotTree,\n\t\tprivate readonly registry: ISharedObjectRegistry,\n\t\textraBlobs: Map<string, ArrayBufferLike> | undefined,\n\t\tcreateSummarizerNode: CreateChildSummarizerNodeFn,\n\t\tprivate readonly attachMessageType?: string,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x310 /* Channel context ID cannot contain slashes */);\n\n\t\tthis.subLogger = ChildLogger.create(this.runtime.logger, \"RemoteChannelContext\");\n\n\t\tthis.services = createServiceEndpoints(\n\t\t\tthis.id,\n\t\t\tthis.dataStoreContext.connected,\n\t\t\tsubmitFn,\n\t\t\t() => dirtyFn(this.id),\n\t\t\taddedGCOutboundReferenceFn,\n\t\t\tstorageService,\n\t\t\tthis.subLogger,\n\t\t\tbaseSnapshot,\n\t\t\textraBlobs,\n\t\t);\n\n\t\tconst thisSummarizeInternal = async (\n\t\t\tfullTree: boolean,\n\t\t\ttrackState: boolean,\n\t\t\ttelemetryContext?: ITelemetryContext,\n\t\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t\t) =>\n\t\t\tthis.summarizeInternal(\n\t\t\t\tfullTree,\n\t\t\t\ttrackState,\n\t\t\t\ttelemetryContext,\n\t\t\t\tincrementalSummaryContext,\n\t\t\t);\n\n\t\tthis.summarizerNode = createSummarizerNode(\n\t\t\tthisSummarizeInternal,\n\t\t\tasync (fullGC?: boolean) => this.getGCDataInternal(fullGC),\n\t\t);\n\n\t\tthis.thresholdOpsCounter = new ThresholdCounter(\n\t\t\tRemoteChannelContext.pendingOpsCountThreshold,\n\t\t\tthis.subLogger,\n\t\t);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\tpublic getChannel(): Promise<IChannel> {\n\t\tif (this.channelP === undefined) {\n\t\t\tthis.channelP = this.loadChannel();\n\t\t}\n\n\t\treturn this.channelP;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet loaded\n\t\tif (!this.isLoaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.services.deltaConnection.setConnectionState(connected);\n\t}\n\n\tpublic applyStashedOp(message: ISequencedDocumentMessage): unknown {\n\t\tassert(this.isLoaded, 0x194 /* \"Remote channel must be loaded when rebasing op\" */);\n\t\treturn this.services.deltaConnection.applyStashedOp(message);\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tthis.summarizerNode.invalidate(message.sequenceNumber);\n\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(!local, 0x195 /* \"Remote channel must not be local when processing op\" */);\n\t\t\tassert(this.pending !== undefined, 0x23e /* \"pending is undefined\" */);\n\t\t\tthis.pending.push(message);\n\t\t\tthis.thresholdOpsCounter.sendIfMultiple(\"StorePendingOps\", this.pending.length);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x196 /* \"Remote channel must be loaded when resubmitting op\" */);\n\n\t\tthis.services.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2f0 /* \"Remote channel must be loaded when rolling back op\" */);\n\n\t\tthis.services.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = true,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\treturn this.summarizerNode.summarize(fullTree, trackState, telemetryContext);\n\t}\n\n\tprivate async summarizeInternal(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): Promise<ISummarizeInternalResult> {\n\t\tconst channel = await this.getChannel();\n\t\tconst summarizeResult = await summarizeChannelAsync(\n\t\t\tchannel,\n\t\t\tfullTree,\n\t\t\ttrackState,\n\t\t\ttelemetryContext,\n\t\t\tincrementalSummaryContext,\n\t\t);\n\t\treturn { ...summarizeResult, id: this.id };\n\t}\n\n\tprivate async loadChannel(): Promise<IChannel> {\n\t\tassert(\n\t\t\t!this.isLoaded,\n\t\t\t0x197 /* \"Remote channel must not already be loaded when loading\" */,\n\t\t);\n\n\t\tlet attributes: IChannelAttributes | undefined;\n\t\tif (await this.services.objectStorage.contains(attributesBlobKey)) {\n\t\t\tattributes = await readAndParse<IChannelAttributes | undefined>(\n\t\t\t\tthis.services.objectStorage,\n\t\t\t\tattributesBlobKey,\n\t\t\t);\n\t\t}\n\n\t\t// This is a backward compatibility case where the attach message doesn't include attributes. They must\n\t\t// include attach message type.\n\t\t// Since old attach messages will not have attributes, we need to keep this as long as we support old attach\n\t\t// messages.\n\t\tconst channelFactoryType = attributes ? attributes.type : this.attachMessageType;\n\t\tif (channelFactoryType === undefined) {\n\t\t\tthrow new DataCorruptionError(\"channelTypeNotAvailable\", {\n\t\t\t\tchannelId: {\n\t\t\t\t\tvalue: this.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStoreId: {\n\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\tchannelFactoryType: this.attachMessageType,\n\t\t\t});\n\t\t}\n\t\tconst factory = this.registry.get(channelFactoryType);\n\t\tif (factory === undefined) {\n\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\tthrow new DataCorruptionError(\"channelFactoryNotRegisteredForGivenType\", {\n\t\t\t\tchannelId: {\n\t\t\t\t\tvalue: this.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStoreId: {\n\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\tchannelFactoryType,\n\t\t\t});\n\t\t}\n\n\t\t// This is a backward compatibility case where the attach message doesn't include attributes. Get the attributes\n\t\t// from the factory.\n\t\tattributes = attributes ?? factory.attributes;\n\n\t\t// Compare snapshot version to collaborative object version\n\t\tif (\n\t\t\tattributes.snapshotFormatVersion !== undefined &&\n\t\t\tattributes.snapshotFormatVersion !== factory.attributes.snapshotFormatVersion\n\t\t) {\n\t\t\tthis.subLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"ChannelAttributesVersionMismatch\",\n\t\t\t\tchannelType: { value: attributes.type, tag: TelemetryDataTag.CodeArtifact },\n\t\t\t\tchannelSnapshotVersion: {\n\t\t\t\t\tvalue: `${attributes.snapshotFormatVersion}@${attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tchannelCodeVersion: {\n\t\t\t\t\tvalue: `${factory.attributes.snapshotFormatVersion}@${factory.attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconst channel = await factory.load(this.runtime, this.id, this.services, attributes);\n\n\t\t// Send all pending messages to the channel\n\t\tassert(this.pending !== undefined, 0x23f /* \"pending undefined\" */);\n\t\tfor (const message of this.pending) {\n\t\t\tthis.services.deltaConnection.process(message, false, undefined /* localOpMetadata */);\n\t\t}\n\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pending.length);\n\n\t\t// Commit changes.\n\t\tthis.channel = channel;\n\t\tthis.pending = undefined;\n\t\tthis.isLoaded = true;\n\n\t\t// Because have some await between we created the service and here, the connection state might have changed\n\t\t// and we don't propagate the connection state when we are not loaded. So we have to set it again here.\n\t\tthis.services.deltaConnection.setConnectionState(this.dataStoreContext.connected);\n\t\treturn this.channel;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document.\n\t * If there is no new data in this context since the last summary, previous GC data is used.\n\t * If there is new data, the GC data is generated again (by calling getGCDataInternal).\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\treturn this.summarizerNode.getGCData(fullGC);\n\t}\n\n\t/**\n\t * Generates the data used for garbage collection. This is called when there is new data since last summary. It\n\t * loads the context and calls into the channel to get its GC data.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tprivate async getGCDataInternal(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected. Update the summarizer node's\n\t\t * used routes to contain a route to this channel context.\n\t\t * Once we have GC at DDS level, this will be updated to use the passed usedRoutes. See -\n\t\t * https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t\tthis.summarizerNode.updateUsedRoutes([\"\"]);\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/datastore",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.4.2.0.153917",
|
|
4
4
|
"description": "Fluid data store implementation",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -14,34 +14,6 @@
|
|
|
14
14
|
"main": "dist/index.js",
|
|
15
15
|
"module": "lib/index.js",
|
|
16
16
|
"types": "dist/index.d.ts",
|
|
17
|
-
"scripts": {
|
|
18
|
-
"build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
|
|
19
|
-
"build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
|
|
20
|
-
"build:compile": "concurrently npm:build:commonjs npm:build:esnext",
|
|
21
|
-
"build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
|
|
22
|
-
"build:esnext": "tsc --project ./tsconfig.esnext.json",
|
|
23
|
-
"build:full": "npm run build",
|
|
24
|
-
"build:full:compile": "npm run build:compile",
|
|
25
|
-
"build:genver": "gen-version",
|
|
26
|
-
"build:test": "tsc --project ./src/test/tsconfig.json",
|
|
27
|
-
"ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
|
|
28
|
-
"clean": "rimraf dist lib *.tsbuildinfo *.build.log",
|
|
29
|
-
"eslint": "eslint --format stylish src",
|
|
30
|
-
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
31
|
-
"format": "npm run prettier:fix",
|
|
32
|
-
"lint": "npm run prettier && npm run eslint",
|
|
33
|
-
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
|
|
34
|
-
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
|
|
35
|
-
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
|
|
36
|
-
"test": "npm run test:mocha",
|
|
37
|
-
"test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
|
|
38
|
-
"test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test --exit -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
|
|
39
|
-
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
40
|
-
"tsc": "tsc",
|
|
41
|
-
"tsc:watch": "tsc --watch",
|
|
42
|
-
"typetests:gen": "flub generate typetests --generate --dir .",
|
|
43
|
-
"typetests:prepare": "flub generate typetests --prepare --dir . --pin"
|
|
44
|
-
},
|
|
45
17
|
"nyc": {
|
|
46
18
|
"all": true,
|
|
47
19
|
"cache-dir": "nyc/.cache",
|
|
@@ -64,50 +36,77 @@
|
|
|
64
36
|
},
|
|
65
37
|
"dependencies": {
|
|
66
38
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
67
|
-
"@fluidframework/common-utils": "^1.
|
|
68
|
-
"@fluidframework/container-definitions": "
|
|
69
|
-
"@fluidframework/container-utils": "
|
|
70
|
-
"@fluidframework/core-interfaces": "
|
|
71
|
-
"@fluidframework/datastore-definitions": "
|
|
72
|
-
"@fluidframework/driver-definitions": "
|
|
73
|
-
"@fluidframework/driver-utils": "
|
|
74
|
-
"@fluidframework/garbage-collector": "
|
|
75
|
-
"@fluidframework/protocol-base": "^0.
|
|
39
|
+
"@fluidframework/common-utils": "^1.1.1",
|
|
40
|
+
"@fluidframework/container-definitions": "2.0.0-dev.4.2.0.153917",
|
|
41
|
+
"@fluidframework/container-utils": "2.0.0-dev.4.2.0.153917",
|
|
42
|
+
"@fluidframework/core-interfaces": "2.0.0-dev.4.2.0.153917",
|
|
43
|
+
"@fluidframework/datastore-definitions": "2.0.0-dev.4.2.0.153917",
|
|
44
|
+
"@fluidframework/driver-definitions": "2.0.0-dev.4.2.0.153917",
|
|
45
|
+
"@fluidframework/driver-utils": "2.0.0-dev.4.2.0.153917",
|
|
46
|
+
"@fluidframework/garbage-collector": "2.0.0-dev.4.2.0.153917",
|
|
47
|
+
"@fluidframework/protocol-base": "^0.1039.1000",
|
|
76
48
|
"@fluidframework/protocol-definitions": "^1.1.0",
|
|
77
|
-
"@fluidframework/runtime-definitions": "
|
|
78
|
-
"@fluidframework/runtime-utils": "
|
|
79
|
-
"@fluidframework/telemetry-utils": "
|
|
49
|
+
"@fluidframework/runtime-definitions": "2.0.0-dev.4.2.0.153917",
|
|
50
|
+
"@fluidframework/runtime-utils": "2.0.0-dev.4.2.0.153917",
|
|
51
|
+
"@fluidframework/telemetry-utils": "2.0.0-dev.4.2.0.153917",
|
|
80
52
|
"lodash": "^4.17.21",
|
|
81
53
|
"uuid": "^8.3.1"
|
|
82
54
|
},
|
|
83
55
|
"devDependencies": {
|
|
84
|
-
"@fluid-tools/build-cli": "^0.
|
|
56
|
+
"@fluid-tools/build-cli": "^0.15.0",
|
|
85
57
|
"@fluidframework/build-common": "^1.1.0",
|
|
86
|
-
"@fluidframework/build-tools": "^0.
|
|
87
|
-
"@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.
|
|
58
|
+
"@fluidframework/build-tools": "^0.15.0",
|
|
59
|
+
"@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.4.0.0",
|
|
88
60
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
89
|
-
"@fluidframework/mocha-test-setup": "
|
|
90
|
-
"@fluidframework/test-runtime-utils": "
|
|
91
|
-
"@microsoft/api-extractor": "^7.
|
|
92
|
-
"@rushstack/eslint-config": "^2.5.1",
|
|
61
|
+
"@fluidframework/mocha-test-setup": "2.0.0-dev.4.2.0.153917",
|
|
62
|
+
"@fluidframework/test-runtime-utils": "2.0.0-dev.4.2.0.153917",
|
|
63
|
+
"@microsoft/api-extractor": "^7.34.4",
|
|
93
64
|
"@types/mocha": "^9.1.1",
|
|
94
|
-
"@types/node": "^14.18.
|
|
65
|
+
"@types/node": "^14.18.38",
|
|
95
66
|
"@types/uuid": "^8.3.0",
|
|
96
|
-
"concurrently": "^6.
|
|
67
|
+
"concurrently": "^7.6.0",
|
|
97
68
|
"copyfiles": "^2.4.1",
|
|
98
|
-
"cross-env": "^7.0.
|
|
69
|
+
"cross-env": "^7.0.3",
|
|
99
70
|
"eslint": "~8.6.0",
|
|
100
|
-
"mocha": "^10.
|
|
101
|
-
"
|
|
71
|
+
"mocha": "^10.2.0",
|
|
72
|
+
"mocha-json-output-reporter": "^2.0.1",
|
|
73
|
+
"mocha-multi-reporters": "^1.5.1",
|
|
74
|
+
"moment": "^2.21.0",
|
|
75
|
+
"nyc": "^15.1.0",
|
|
102
76
|
"prettier": "~2.6.2",
|
|
103
|
-
"rimraf": "^
|
|
77
|
+
"rimraf": "^4.4.0",
|
|
104
78
|
"typescript": "~4.5.5"
|
|
105
79
|
},
|
|
106
80
|
"typeValidation": {
|
|
107
|
-
"version": "2.0.0-internal.3.1.0",
|
|
108
|
-
"previousVersionStyle": "~previousMinor",
|
|
109
|
-
"baselineRange": ">=2.0.0-internal.3.0.0 <2.0.0-internal.3.1.0",
|
|
110
|
-
"baselineVersion": "2.0.0-internal.3.0.0",
|
|
111
81
|
"broken": {}
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
|
|
85
|
+
"build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
|
|
86
|
+
"build:compile": "concurrently npm:build:commonjs npm:build:esnext",
|
|
87
|
+
"build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
|
|
88
|
+
"build:esnext": "tsc --project ./tsconfig.esnext.json",
|
|
89
|
+
"build:full": "npm run build",
|
|
90
|
+
"build:full:compile": "npm run build:compile",
|
|
91
|
+
"build:genver": "gen-version",
|
|
92
|
+
"build:test": "tsc --project ./src/test/tsconfig.json",
|
|
93
|
+
"ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
|
|
94
|
+
"clean": "rimraf dist lib *.tsbuildinfo *.build.log",
|
|
95
|
+
"eslint": "eslint --format stylish src",
|
|
96
|
+
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
97
|
+
"format": "npm run prettier:fix",
|
|
98
|
+
"lint": "npm run prettier && npm run eslint",
|
|
99
|
+
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
|
|
100
|
+
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
|
|
101
|
+
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
|
|
102
|
+
"test": "npm run test:mocha",
|
|
103
|
+
"test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
|
|
104
|
+
"test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test --exit -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
|
|
105
|
+
"test:mocha:multireport": "cross-env FLUID_TEST_MULTIREPORT=1 npm run test:mocha",
|
|
106
|
+
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
107
|
+
"tsc": "tsc",
|
|
108
|
+
"tsc:watch": "tsc --watch",
|
|
109
|
+
"typetests:gen": "fluid-type-test-generator",
|
|
110
|
+
"typetests:prepare": "flub generate typetests --prepare --dir . --pin"
|
|
112
111
|
}
|
|
113
|
-
}
|
|
112
|
+
}
|
package/src/channelContext.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { IDocumentStorageService } from "@fluidframework/driver-definitions";
|
|
|
10
10
|
import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
11
11
|
import {
|
|
12
12
|
IGarbageCollectionData,
|
|
13
|
+
IExperimentalIncrementalSummaryContext,
|
|
13
14
|
ISummarizeResult,
|
|
14
15
|
ISummaryTreeWithStats,
|
|
15
16
|
ITelemetryContext,
|
|
@@ -99,8 +100,14 @@ export async function summarizeChannelAsync(
|
|
|
99
100
|
fullTree: boolean = false,
|
|
100
101
|
trackState: boolean = false,
|
|
101
102
|
telemetryContext?: ITelemetryContext,
|
|
103
|
+
incrementalSummaryContext?: IExperimentalIncrementalSummaryContext,
|
|
102
104
|
): Promise<ISummaryTreeWithStats> {
|
|
103
|
-
const summarizeResult = await channel.summarize(
|
|
105
|
+
const summarizeResult = await channel.summarize(
|
|
106
|
+
fullTree,
|
|
107
|
+
trackState,
|
|
108
|
+
telemetryContext,
|
|
109
|
+
incrementalSummaryContext,
|
|
110
|
+
);
|
|
104
111
|
|
|
105
112
|
// Add the channel attributes to the returned result.
|
|
106
113
|
addBlobToSummary(summarizeResult, attributesBlobKey, JSON.stringify(channel.attributes));
|
package/src/dataStoreRuntime.ts
CHANGED
|
@@ -25,7 +25,15 @@ import {
|
|
|
25
25
|
TypedEventEmitter,
|
|
26
26
|
unreachableCase,
|
|
27
27
|
} from "@fluidframework/common-utils";
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
ChildLogger,
|
|
30
|
+
generateStack,
|
|
31
|
+
LoggingError,
|
|
32
|
+
loggerToMonitoringContext,
|
|
33
|
+
MonitoringContext,
|
|
34
|
+
raiseConnectedEvent,
|
|
35
|
+
TelemetryDataTag,
|
|
36
|
+
} from "@fluidframework/telemetry-utils";
|
|
29
37
|
import { buildSnapshotTree } from "@fluidframework/driver-utils";
|
|
30
38
|
import {
|
|
31
39
|
IClientDetails,
|
|
@@ -37,14 +45,12 @@ import {
|
|
|
37
45
|
IQuorumClients,
|
|
38
46
|
} from "@fluidframework/protocol-definitions";
|
|
39
47
|
import {
|
|
40
|
-
BindState,
|
|
41
48
|
CreateSummarizerNodeSource,
|
|
42
49
|
IAttachMessage,
|
|
43
50
|
IEnvelope,
|
|
44
51
|
IFluidDataStoreContext,
|
|
45
52
|
IFluidDataStoreChannel,
|
|
46
53
|
IGarbageCollectionData,
|
|
47
|
-
IGarbageCollectionDetailsBase,
|
|
48
54
|
IInboundSignalMessage,
|
|
49
55
|
ISummaryTreeWithStats,
|
|
50
56
|
VisibilityState,
|
|
@@ -59,7 +65,10 @@ import {
|
|
|
59
65
|
create404Response,
|
|
60
66
|
createResponseError,
|
|
61
67
|
exceptionToResponse,
|
|
68
|
+
GCDataBuilder,
|
|
62
69
|
requestFluidObject,
|
|
70
|
+
packagePathToTelemetryProperty,
|
|
71
|
+
unpackChildNodesUsedRoutes,
|
|
63
72
|
} from "@fluidframework/runtime-utils";
|
|
64
73
|
import {
|
|
65
74
|
IChannel,
|
|
@@ -67,12 +76,6 @@ import {
|
|
|
67
76
|
IFluidDataStoreRuntimeEvents,
|
|
68
77
|
IChannelFactory,
|
|
69
78
|
} from "@fluidframework/datastore-definitions";
|
|
70
|
-
import {
|
|
71
|
-
GCDataBuilder,
|
|
72
|
-
removeRouteFromAllNodes,
|
|
73
|
-
unpackChildNodesGCDetails,
|
|
74
|
-
unpackChildNodesUsedRoutes,
|
|
75
|
-
} from "@fluidframework/garbage-collector";
|
|
76
79
|
import { v4 as uuid } from "uuid";
|
|
77
80
|
import { IChannelContext, summarizeChannel } from "./channelContext";
|
|
78
81
|
import {
|
|
@@ -183,7 +186,6 @@ export class FluidDataStoreRuntime
|
|
|
183
186
|
private readonly contextsDeferred = new Map<string, Deferred<IChannelContext>>();
|
|
184
187
|
private readonly pendingAttach = new Map<string, IAttachMessage>();
|
|
185
188
|
|
|
186
|
-
private bindState: BindState;
|
|
187
189
|
private readonly deferredAttached = new Deferred<void>();
|
|
188
190
|
private readonly localChannelContextQueue = new Map<string, LocalChannelContextBase>();
|
|
189
191
|
private readonly notBoundedChannelContextSet = new Set<string>();
|
|
@@ -198,11 +200,17 @@ export class FluidDataStoreRuntime
|
|
|
198
200
|
public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
|
|
199
201
|
private readonly quorum: IQuorumClients;
|
|
200
202
|
private readonly audience: IAudience;
|
|
201
|
-
|
|
203
|
+
private readonly mc: MonitoringContext;
|
|
204
|
+
public get logger(): ITelemetryLogger {
|
|
205
|
+
return this.mc.logger;
|
|
206
|
+
}
|
|
202
207
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
/**
|
|
209
|
+
* If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.
|
|
210
|
+
* So, adding a count of how many telemetry events are logged per data store context. This can be
|
|
211
|
+
* controlled via feature flags.
|
|
212
|
+
*/
|
|
213
|
+
private localChangesTelemetryCount: number;
|
|
206
214
|
|
|
207
215
|
/**
|
|
208
216
|
* Invokes the given callback and expects that no ops are submitted
|
|
@@ -243,9 +251,11 @@ export class FluidDataStoreRuntime
|
|
|
243
251
|
0x30e /* Id cannot contain slashes. DataStoreContext should have validated this. */,
|
|
244
252
|
);
|
|
245
253
|
|
|
246
|
-
this.
|
|
247
|
-
|
|
248
|
-
|
|
254
|
+
this.mc = loggerToMonitoringContext(
|
|
255
|
+
ChildLogger.create(dataStoreContext.logger, "FluidDataStoreRuntime", {
|
|
256
|
+
all: { dataStoreId: uuid() },
|
|
257
|
+
}),
|
|
258
|
+
);
|
|
249
259
|
|
|
250
260
|
this.id = dataStoreContext.id;
|
|
251
261
|
this.options = dataStoreContext.options;
|
|
@@ -255,11 +265,6 @@ export class FluidDataStoreRuntime
|
|
|
255
265
|
|
|
256
266
|
const tree = dataStoreContext.baseSnapshot;
|
|
257
267
|
|
|
258
|
-
this.channelsBaseGCDetails = new LazyPromise(async () => {
|
|
259
|
-
const baseGCDetails = await this.dataStoreContext.getBaseGCDetails();
|
|
260
|
-
return unpackChildNodesGCDetails(baseGCDetails);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
268
|
// Must always receive the data store type inside of the attributes
|
|
264
269
|
if (tree?.trees !== undefined) {
|
|
265
270
|
Object.keys(tree.trees).forEach((path) => {
|
|
@@ -316,7 +321,6 @@ export class FluidDataStoreRuntime
|
|
|
316
321
|
this.dataStoreContext.getCreateChildSummarizerNodeFn(path, {
|
|
317
322
|
type: CreateSummarizerNodeSource.FromSummary,
|
|
318
323
|
}),
|
|
319
|
-
async () => this.getChannelBaseGCDetails(path),
|
|
320
324
|
);
|
|
321
325
|
}
|
|
322
326
|
const deferred = new Deferred<IChannelContext>();
|
|
@@ -337,8 +341,6 @@ export class FluidDataStoreRuntime
|
|
|
337
341
|
}
|
|
338
342
|
|
|
339
343
|
this.attachListener();
|
|
340
|
-
// If exists on storage or loaded from a snapshot, it should already be bound.
|
|
341
|
-
this.bindState = existing ? BindState.Bound : BindState.NotBound;
|
|
342
344
|
this._attachState = dataStoreContext.attachState;
|
|
343
345
|
|
|
344
346
|
/**
|
|
@@ -364,6 +366,10 @@ export class FluidDataStoreRuntime
|
|
|
364
366
|
if (existing) {
|
|
365
367
|
this.deferredAttached.resolve();
|
|
366
368
|
}
|
|
369
|
+
|
|
370
|
+
// By default, a data store can log maximum 10 local changes telemetry in summarizer.
|
|
371
|
+
this.localChangesTelemetryCount =
|
|
372
|
+
this.mc.config.getNumber("Fluid.Telemetry.LocalChangesTelemetryCount") ?? 10;
|
|
367
373
|
}
|
|
368
374
|
|
|
369
375
|
public dispose(): void {
|
|
@@ -398,7 +404,10 @@ export class FluidDataStoreRuntime
|
|
|
398
404
|
|
|
399
405
|
return { mimeType: "fluid/object", status: 200, value: channel };
|
|
400
406
|
} catch (error) {
|
|
401
|
-
this.logger.sendErrorEvent(
|
|
407
|
+
this.mc.logger.sendErrorEvent(
|
|
408
|
+
{ eventName: "GetChannelFailedInRequest" },
|
|
409
|
+
error,
|
|
410
|
+
);
|
|
402
411
|
|
|
403
412
|
return createResponseError(500, `Failed to get Channel: ${error}`, request);
|
|
404
413
|
}
|
|
@@ -461,6 +470,9 @@ export class FluidDataStoreRuntime
|
|
|
461
470
|
this.contextsDeferred.set(id, deferred);
|
|
462
471
|
}
|
|
463
472
|
|
|
473
|
+
// Channels (DDS) should not be created in summarizer client.
|
|
474
|
+
this.identifyLocalChangeInSummarizer("DDSCreatedInSummarizer", id, type);
|
|
475
|
+
|
|
464
476
|
assert(!!context.channel, 0x17a /* "Channel should be loaded when created!!" */);
|
|
465
477
|
return context.channel;
|
|
466
478
|
}
|
|
@@ -522,7 +534,7 @@ export class FluidDataStoreRuntime
|
|
|
522
534
|
handle.attachGraph();
|
|
523
535
|
});
|
|
524
536
|
this.pendingHandlesToMakeVisible.clear();
|
|
525
|
-
this.
|
|
537
|
+
this.dataStoreContext.makeLocallyVisible();
|
|
526
538
|
}
|
|
527
539
|
|
|
528
540
|
/**
|
|
@@ -540,12 +552,7 @@ export class FluidDataStoreRuntime
|
|
|
540
552
|
* 2. Attaching the graph if the data store becomes attached.
|
|
541
553
|
*/
|
|
542
554
|
public bindToContext() {
|
|
543
|
-
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
this.bindState = BindState.Binding;
|
|
547
|
-
this.dataStoreContext.bindToContext();
|
|
548
|
-
this.bindState = BindState.Bound;
|
|
555
|
+
this.makeVisibleAndAttachGraph();
|
|
549
556
|
}
|
|
550
557
|
|
|
551
558
|
public bind(handle: IFluidHandle): void {
|
|
@@ -600,12 +607,7 @@ export class FluidDataStoreRuntime
|
|
|
600
607
|
);
|
|
601
608
|
this.pendingAttach.delete(id);
|
|
602
609
|
} else {
|
|
603
|
-
assert(
|
|
604
|
-
!this.contexts.has(id),
|
|
605
|
-
0x17d /* `Unexpected attach channel OP,
|
|
606
|
-
is in pendingAttach set: ${this.pendingAttach.has(id)},
|
|
607
|
-
is local channel contexts: ${this.contexts.get(id) instanceof LocalChannelContextBase}` */,
|
|
608
|
-
);
|
|
610
|
+
assert(!this.contexts.has(id), 0x17d /* "Unexpected attach channel OP" */);
|
|
609
611
|
|
|
610
612
|
const flatBlobs = new Map<string, ArrayBufferLike>();
|
|
611
613
|
const snapshotTree = buildSnapshotTree(
|
|
@@ -631,7 +633,6 @@ export class FluidDataStoreRuntime
|
|
|
631
633
|
sequenceNumber: message.sequenceNumber,
|
|
632
634
|
snapshot: attachMessage.snapshot,
|
|
633
635
|
}),
|
|
634
|
-
async () => this.getChannelBaseGCDetails(id),
|
|
635
636
|
attachMessage.type,
|
|
636
637
|
);
|
|
637
638
|
|
|
@@ -780,34 +781,6 @@ export class FluidDataStoreRuntime
|
|
|
780
781
|
this.dataStoreContext.addedGCOutboundReference?.(srcHandle, outboundHandle);
|
|
781
782
|
}
|
|
782
783
|
|
|
783
|
-
/**
|
|
784
|
-
* Returns the base GC details for the channel with the given id. This is used to initialize its GC state.
|
|
785
|
-
* @param channelId - The id of the channel context that is asked for the initial GC details.
|
|
786
|
-
* @returns the requested channel's base GC details.
|
|
787
|
-
*/
|
|
788
|
-
private async getChannelBaseGCDetails(
|
|
789
|
-
channelId: string,
|
|
790
|
-
): Promise<IGarbageCollectionDetailsBase> {
|
|
791
|
-
let channelBaseGCDetails = (await this.channelsBaseGCDetails).get(channelId);
|
|
792
|
-
if (channelBaseGCDetails === undefined) {
|
|
793
|
-
channelBaseGCDetails = {};
|
|
794
|
-
} else if (channelBaseGCDetails.gcData?.gcNodes !== undefined) {
|
|
795
|
-
// Note: if the child channel has an explicit handle route to its parent, it will be removed here and
|
|
796
|
-
// expected to be added back by the parent when getGCData is called.
|
|
797
|
-
removeRouteFromAllNodes(channelBaseGCDetails.gcData.gcNodes, this.absolutePath);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
// Currently, channel context's are always considered used. So, it there are no used routes for it, we still
|
|
801
|
-
// need to mark it as used. Add self-route (empty string) to the channel context's used routes.
|
|
802
|
-
if (
|
|
803
|
-
channelBaseGCDetails.usedRoutes === undefined ||
|
|
804
|
-
channelBaseGCDetails.usedRoutes.length === 0
|
|
805
|
-
) {
|
|
806
|
-
channelBaseGCDetails.usedRoutes = [""];
|
|
807
|
-
}
|
|
808
|
-
return channelBaseGCDetails;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
784
|
/**
|
|
812
785
|
* Returns a summary at the current sequence number.
|
|
813
786
|
* @param fullTree - true to bypass optimizations and force a full summary tree
|
|
@@ -1109,6 +1082,42 @@ export class FluidDataStoreRuntime
|
|
|
1109
1082
|
throw new LoggingError("Runtime is closed");
|
|
1110
1083
|
}
|
|
1111
1084
|
}
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* Summarizer client should not have local changes. These changes can become part of the summary and can break
|
|
1088
|
+
* eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas
|
|
1089
|
+
* other clients that are up-to-date till seq# 100 may not have them yet.
|
|
1090
|
+
*/
|
|
1091
|
+
private identifyLocalChangeInSummarizer(
|
|
1092
|
+
eventName: string,
|
|
1093
|
+
channelId: string,
|
|
1094
|
+
channelType: string,
|
|
1095
|
+
) {
|
|
1096
|
+
if (this.clientDetails.type !== "summarizer" || this.localChangesTelemetryCount <= 0) {
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// Log a telemetry if there are local changes in the summarizer. This will give us data on how often
|
|
1101
|
+
// this is happening and which data stores do this. The eventual goal is to disallow local changes
|
|
1102
|
+
// in the summarizer and the data will help us plan this.
|
|
1103
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1104
|
+
eventName,
|
|
1105
|
+
channelType,
|
|
1106
|
+
channelId: {
|
|
1107
|
+
value: channelId,
|
|
1108
|
+
tag: TelemetryDataTag.CodeArtifact,
|
|
1109
|
+
},
|
|
1110
|
+
fluidDataStoreId: {
|
|
1111
|
+
value: this.id,
|
|
1112
|
+
tag: TelemetryDataTag.CodeArtifact,
|
|
1113
|
+
},
|
|
1114
|
+
fluidDataStorePackagePath: packagePathToTelemetryProperty(
|
|
1115
|
+
this.dataStoreContext.packagePath,
|
|
1116
|
+
),
|
|
1117
|
+
stack: generateStack(),
|
|
1118
|
+
});
|
|
1119
|
+
this.localChangesTelemetryCount--;
|
|
1120
|
+
}
|
|
1112
1121
|
}
|
|
1113
1122
|
|
|
1114
1123
|
/**
|
package/src/packageVersion.ts
CHANGED