@fluidframework/datastore 2.0.0-internal.5.4.0 → 2.0.0-internal.6.1.0
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 +50 -0
- package/dist/channelContext.js +9 -6
- package/dist/channelContext.js.map +1 -1
- package/dist/channelStorageService.js +1 -2
- package/dist/channelStorageService.js.map +1 -1
- package/dist/dataStoreRuntime.d.ts +7 -1
- package/dist/dataStoreRuntime.d.ts.map +1 -1
- package/dist/dataStoreRuntime.js +65 -62
- package/dist/dataStoreRuntime.js.map +1 -1
- package/dist/remoteChannelContext.js +1 -1
- package/dist/remoteChannelContext.js.map +1 -1
- package/lib/channelContext.js +9 -6
- package/lib/channelContext.js.map +1 -1
- package/lib/channelStorageService.js +1 -2
- package/lib/channelStorageService.js.map +1 -1
- package/lib/dataStoreRuntime.d.ts +7 -1
- package/lib/dataStoreRuntime.d.ts.map +1 -1
- package/lib/dataStoreRuntime.js +65 -62
- package/lib/dataStoreRuntime.js.map +1 -1
- package/lib/remoteChannelContext.js +1 -1
- package/lib/remoteChannelContext.js.map +1 -1
- package/package.json +18 -18
- package/src/dataStoreRuntime.ts +82 -69
|
@@ -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 { assert } from \"@fluidframework/common-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { LazyPromise } from \"@fluidframework/core-utils\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\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 {\n\tcreateChildLogger,\n\tITelemetryLoggerExt,\n\tThresholdCounter,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\nexport class RemoteChannelContext implements IChannelContext {\n\tprivate isLoaded = false;\n\tprivate pending: ISequencedDocumentMessage[] | undefined = [];\n\tprivate readonly channelP: Promise<IChannel>;\n\tprivate channel: IChannel | undefined;\n\tprivate readonly services: ChannelServiceEndpoints;\n\tprivate readonly summarizerNode: ISummarizerNodeWithGC;\n\tprivate readonly subLogger: ITelemetryLoggerExt;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\tconstructor(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: 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\tregistry: ISharedObjectRegistry,\n\t\textraBlobs: Map<string, ArrayBufferLike> | undefined,\n\t\tcreateSummarizerNode: CreateChildSummarizerNodeFn,\n\t\tattachMessageType?: string,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x310 /* Channel context ID cannot contain slashes */);\n\n\t\tthis.subLogger = createChildLogger({\n\t\t\tlogger: runtime.logger,\n\t\t\tnamespace: \"RemoteChannelContext\",\n\t\t});\n\n\t\tthis.services = createChannelServiceEndpoints(\n\t\t\tdataStoreContext.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\tthis.channelP = new LazyPromise<IChannel>(async () => {\n\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\tdataStoreContext,\n\t\t\t\tthis.services,\n\t\t\t\tthis.id,\n\t\t\t\tregistry,\n\t\t\t\tattachMessageType,\n\t\t\t);\n\n\t\t\tconst channel = await loadChannel(\n\t\t\t\truntime,\n\t\t\t\tattributes,\n\t\t\t\tfactory,\n\t\t\t\tthis.services,\n\t\t\t\tthis.subLogger,\n\t\t\t\tthis.id,\n\t\t\t);\n\n\t\t\t// Send all pending messages to the channel\n\t\t\tassert(this.pending !== undefined, 0x23f /* \"pending undefined\" */);\n\t\t\tfor (const message of this.pending) {\n\t\t\t\tthis.services.deltaConnection.process(\n\t\t\t\t\tmessage,\n\t\t\t\t\tfalse,\n\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pending.length);\n\n\t\t\t// Commit changes.\n\t\t\tthis.channel = channel;\n\t\t\tthis.pending = undefined;\n\t\t\tthis.isLoaded = true;\n\n\t\t\t// Because have some await between we created the service and here, the connection state might have changed\n\t\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\t\tthis.services.deltaConnection.setConnectionState(dataStoreContext.connected);\n\t\t\treturn this.channel;\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\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(content: any): unknown {\n\t\tassert(this.isLoaded, 0x194 /* \"Remote channel must be loaded when rebasing op\" */);\n\t\treturn this.services.deltaConnection.applyStashedOp(content);\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\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 { assert } from \"@fluidframework/common-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { LazyPromise } from \"@fluidframework/core-utils\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\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 {\n\tcreateChildLogger,\n\tITelemetryLoggerExt,\n\tThresholdCounter,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\nexport class RemoteChannelContext implements IChannelContext {\n\tprivate isLoaded = false;\n\tprivate pending: ISequencedDocumentMessage[] | undefined = [];\n\tprivate readonly channelP: Promise<IChannel>;\n\tprivate channel: IChannel | undefined;\n\tprivate readonly services: ChannelServiceEndpoints;\n\tprivate readonly summarizerNode: ISummarizerNodeWithGC;\n\tprivate readonly subLogger: ITelemetryLoggerExt;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\tconstructor(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: 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\tregistry: ISharedObjectRegistry,\n\t\textraBlobs: Map<string, ArrayBufferLike> | undefined,\n\t\tcreateSummarizerNode: CreateChildSummarizerNodeFn,\n\t\tattachMessageType?: string,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x310 /* Channel context ID cannot contain slashes */);\n\n\t\tthis.subLogger = createChildLogger({\n\t\t\tlogger: runtime.logger,\n\t\t\tnamespace: \"RemoteChannelContext\",\n\t\t});\n\n\t\tthis.services = createChannelServiceEndpoints(\n\t\t\tdataStoreContext.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\tthis.channelP = new LazyPromise<IChannel>(async () => {\n\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\tdataStoreContext,\n\t\t\t\tthis.services,\n\t\t\t\tthis.id,\n\t\t\t\tregistry,\n\t\t\t\tattachMessageType,\n\t\t\t);\n\n\t\t\tconst channel = await loadChannel(\n\t\t\t\truntime,\n\t\t\t\tattributes,\n\t\t\t\tfactory,\n\t\t\t\tthis.services,\n\t\t\t\tthis.subLogger,\n\t\t\t\tthis.id,\n\t\t\t);\n\n\t\t\t// Send all pending messages to the channel\n\t\t\tassert(this.pending !== undefined, 0x23f /* \"pending undefined\" */);\n\t\t\tfor (const message of this.pending) {\n\t\t\t\tthis.services.deltaConnection.process(\n\t\t\t\t\tmessage,\n\t\t\t\t\tfalse,\n\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pending.length);\n\n\t\t\t// Commit changes.\n\t\t\tthis.channel = channel;\n\t\t\tthis.pending = undefined;\n\t\t\tthis.isLoaded = true;\n\n\t\t\t// Because have some await between we created the service and here, the connection state might have changed\n\t\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\t\tthis.services.deltaConnection.setConnectionState(dataStoreContext.connected);\n\t\t\treturn this.channel;\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\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(content: any): unknown {\n\t\tassert(this.isLoaded, 0x194 /* \"Remote channel must be loaded when rebasing op\" */);\n\t\treturn this.services.deltaConnection.applyStashedOp(content);\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\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-internal.
|
|
3
|
+
"version": "2.0.0-internal.6.1.0",
|
|
4
4
|
"description": "Fluid data store implementation",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -37,29 +37,29 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
39
39
|
"@fluidframework/common-utils": "^1.1.1",
|
|
40
|
-
"@fluidframework/container-definitions": ">=2.0.0-internal.
|
|
41
|
-
"@fluidframework/container-utils": ">=2.0.0-internal.
|
|
42
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.
|
|
43
|
-
"@fluidframework/core-utils": ">=2.0.0-internal.
|
|
44
|
-
"@fluidframework/datastore-definitions": ">=2.0.0-internal.
|
|
45
|
-
"@fluidframework/driver-definitions": ">=2.0.0-internal.
|
|
46
|
-
"@fluidframework/driver-utils": ">=2.0.0-internal.
|
|
47
|
-
"@fluidframework/protocol-base": "^0.
|
|
40
|
+
"@fluidframework/container-definitions": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
41
|
+
"@fluidframework/container-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
42
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
43
|
+
"@fluidframework/core-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
44
|
+
"@fluidframework/datastore-definitions": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
45
|
+
"@fluidframework/driver-definitions": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
46
|
+
"@fluidframework/driver-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
47
|
+
"@fluidframework/protocol-base": "^1.0.0",
|
|
48
48
|
"@fluidframework/protocol-definitions": "^1.1.0",
|
|
49
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-internal.
|
|
50
|
-
"@fluidframework/runtime-utils": ">=2.0.0-internal.
|
|
51
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-internal.
|
|
49
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
50
|
+
"@fluidframework/runtime-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
51
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
52
52
|
"lodash": "^4.17.21",
|
|
53
53
|
"uuid": "^8.3.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@fluid-tools/build-cli": "^0.
|
|
57
|
-
"@fluidframework/build-common": "^
|
|
58
|
-
"@fluidframework/build-tools": "^0.
|
|
59
|
-
"@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.
|
|
56
|
+
"@fluid-tools/build-cli": "^0.22.0",
|
|
57
|
+
"@fluidframework/build-common": "^2.0.0",
|
|
58
|
+
"@fluidframework/build-tools": "^0.22.0",
|
|
59
|
+
"@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.6.0.0",
|
|
60
60
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
61
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.
|
|
62
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.
|
|
61
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
62
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
63
63
|
"@microsoft/api-extractor": "^7.34.4",
|
|
64
64
|
"@types/mocha": "^9.1.1",
|
|
65
65
|
"@types/node": "^16.18.38",
|
package/src/dataStoreRuntime.ts
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
IQuorumClients,
|
|
40
40
|
} from "@fluidframework/protocol-definitions";
|
|
41
41
|
import {
|
|
42
|
+
CreateChildSummarizerNodeParam,
|
|
42
43
|
CreateSummarizerNodeSource,
|
|
43
44
|
IAttachMessage,
|
|
44
45
|
IEnvelope,
|
|
@@ -125,6 +126,9 @@ export class FluidDataStoreRuntime
|
|
|
125
126
|
*/
|
|
126
127
|
public readonly entryPoint?: IFluidHandle<FluidObject>;
|
|
127
128
|
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
|
|
131
|
+
*/
|
|
128
132
|
public get IFluidRouter() {
|
|
129
133
|
return this;
|
|
130
134
|
}
|
|
@@ -181,8 +185,7 @@ export class FluidDataStoreRuntime
|
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
private readonly contexts = new Map<string, IChannelContext>();
|
|
184
|
-
private readonly
|
|
185
|
-
private readonly pendingAttach = new Map<string, IAttachMessage>();
|
|
188
|
+
private readonly pendingAttach = new Set<string>();
|
|
186
189
|
|
|
187
190
|
private readonly deferredAttached = new Deferred<void>();
|
|
188
191
|
private readonly localChannelContextQueue = new Map<string, LocalChannelContextBase>();
|
|
@@ -320,11 +323,8 @@ export class FluidDataStoreRuntime
|
|
|
320
323
|
}),
|
|
321
324
|
);
|
|
322
325
|
}
|
|
323
|
-
const deferred = new Deferred<IChannelContext>();
|
|
324
|
-
deferred.resolve(channelContext);
|
|
325
326
|
|
|
326
327
|
this.contexts.set(path, channelContext);
|
|
327
|
-
this.contextsDeferred.set(path, deferred);
|
|
328
328
|
});
|
|
329
329
|
}
|
|
330
330
|
|
|
@@ -383,6 +383,9 @@ export class FluidDataStoreRuntime
|
|
|
383
383
|
return this.request(request);
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
/**
|
|
387
|
+
* @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
|
|
388
|
+
*/
|
|
386
389
|
public async request(request: IRequest): Promise<IResponse> {
|
|
387
390
|
try {
|
|
388
391
|
const parser = RequestParser.create(request);
|
|
@@ -393,11 +396,10 @@ export class FluidDataStoreRuntime
|
|
|
393
396
|
}
|
|
394
397
|
|
|
395
398
|
// Check for a data type reference first
|
|
396
|
-
|
|
399
|
+
const context = this.contexts.get(id);
|
|
400
|
+
if (context !== undefined && parser.isLeaf(1)) {
|
|
397
401
|
try {
|
|
398
|
-
|
|
399
|
-
const value = await this.contextsDeferred.get(id)!.promise;
|
|
400
|
-
const channel = await value.getChannel();
|
|
402
|
+
const channel = await context.getChannel();
|
|
401
403
|
|
|
402
404
|
return { mimeType: "fluid/object", status: 200, value: channel };
|
|
403
405
|
} catch (error) {
|
|
@@ -420,18 +422,12 @@ export class FluidDataStoreRuntime
|
|
|
420
422
|
public async getChannel(id: string): Promise<IChannel> {
|
|
421
423
|
this.verifyNotClosed();
|
|
422
424
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
if (!this.contextsDeferred.has(id)) {
|
|
427
|
-
this.contextsDeferred.set(id, new Deferred<IChannelContext>());
|
|
425
|
+
const context = this.contexts.get(id);
|
|
426
|
+
if (context === undefined) {
|
|
427
|
+
throw new LoggingError("Channel does not exist");
|
|
428
428
|
}
|
|
429
429
|
|
|
430
|
-
|
|
431
|
-
const context = await this.contextsDeferred.get(id)!.promise;
|
|
432
|
-
const channel = await context.getChannel();
|
|
433
|
-
|
|
434
|
-
return channel;
|
|
430
|
+
return context.getChannel();
|
|
435
431
|
}
|
|
436
432
|
|
|
437
433
|
public createChannel(id: string = uuid(), type: string): IChannel {
|
|
@@ -458,15 +454,6 @@ export class FluidDataStoreRuntime
|
|
|
458
454
|
);
|
|
459
455
|
this.contexts.set(id, context);
|
|
460
456
|
|
|
461
|
-
if (this.contextsDeferred.has(id)) {
|
|
462
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
463
|
-
this.contextsDeferred.get(id)!.resolve(context);
|
|
464
|
-
} else {
|
|
465
|
-
const deferred = new Deferred<IChannelContext>();
|
|
466
|
-
deferred.resolve(context);
|
|
467
|
-
this.contextsDeferred.set(id, deferred);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
457
|
// Channels (DDS) should not be created in summarizer client.
|
|
471
458
|
this.identifyLocalChangeInSummarizer("DDSCreatedInSummarizer", id, type);
|
|
472
459
|
|
|
@@ -587,6 +574,34 @@ export class FluidDataStoreRuntime
|
|
|
587
574
|
return this.dataStoreContext.uploadBlob(blob, signal);
|
|
588
575
|
}
|
|
589
576
|
|
|
577
|
+
private createRemoteChannelContext(
|
|
578
|
+
attachMessage: IAttachMessage,
|
|
579
|
+
summarizerNodeParams: CreateChildSummarizerNodeParam,
|
|
580
|
+
) {
|
|
581
|
+
const flatBlobs = new Map<string, ArrayBufferLike>();
|
|
582
|
+
const snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatBlobs);
|
|
583
|
+
|
|
584
|
+
return new RemoteChannelContext(
|
|
585
|
+
this,
|
|
586
|
+
this.dataStoreContext,
|
|
587
|
+
this.dataStoreContext.storage,
|
|
588
|
+
(content, localContentMetadata) =>
|
|
589
|
+
this.submitChannelOp(attachMessage.id, content, localContentMetadata),
|
|
590
|
+
(address: string) => this.setChannelDirty(address),
|
|
591
|
+
(srcHandle: IFluidHandle, outboundHandle: IFluidHandle) =>
|
|
592
|
+
this.addedGCOutboundReference(srcHandle, outboundHandle),
|
|
593
|
+
attachMessage.id,
|
|
594
|
+
snapshotTree,
|
|
595
|
+
this.sharedObjectRegistry,
|
|
596
|
+
flatBlobs,
|
|
597
|
+
this.dataStoreContext.getCreateChildSummarizerNodeFn(
|
|
598
|
+
attachMessage.id,
|
|
599
|
+
summarizerNodeParams,
|
|
600
|
+
),
|
|
601
|
+
attachMessage.type,
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
|
|
590
605
|
public process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {
|
|
591
606
|
this.verifyNotClosed();
|
|
592
607
|
|
|
@@ -601,49 +616,23 @@ export class FluidDataStoreRuntime
|
|
|
601
616
|
// Otherwise mark it as officially attached.
|
|
602
617
|
if (local) {
|
|
603
618
|
assert(
|
|
604
|
-
this.pendingAttach.
|
|
619
|
+
this.pendingAttach.delete(id),
|
|
605
620
|
0x17c /* "Unexpected attach (local) channel OP" */,
|
|
606
621
|
);
|
|
607
|
-
this.pendingAttach.delete(id);
|
|
608
622
|
} else {
|
|
609
623
|
assert(!this.contexts.has(id), 0x17d /* "Unexpected attach channel OP" */);
|
|
610
624
|
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
625
|
+
const summarizerNodeParams = {
|
|
626
|
+
type: CreateSummarizerNodeSource.FromAttach,
|
|
627
|
+
sequenceNumber: message.sequenceNumber,
|
|
628
|
+
snapshot: attachMessage.snapshot,
|
|
629
|
+
};
|
|
616
630
|
|
|
617
|
-
const remoteChannelContext =
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
this.dataStoreContext.storage,
|
|
621
|
-
(content, localContentMetadata) =>
|
|
622
|
-
this.submitChannelOp(id, content, localContentMetadata),
|
|
623
|
-
(address: string) => this.setChannelDirty(address),
|
|
624
|
-
(srcHandle: IFluidHandle, outboundHandle: IFluidHandle) =>
|
|
625
|
-
this.addedGCOutboundReference(srcHandle, outboundHandle),
|
|
626
|
-
id,
|
|
627
|
-
snapshotTree,
|
|
628
|
-
this.sharedObjectRegistry,
|
|
629
|
-
flatBlobs,
|
|
630
|
-
this.dataStoreContext.getCreateChildSummarizerNodeFn(id, {
|
|
631
|
-
type: CreateSummarizerNodeSource.FromAttach,
|
|
632
|
-
sequenceNumber: message.sequenceNumber,
|
|
633
|
-
snapshot: attachMessage.snapshot,
|
|
634
|
-
}),
|
|
635
|
-
attachMessage.type,
|
|
631
|
+
const remoteChannelContext = this.createRemoteChannelContext(
|
|
632
|
+
attachMessage,
|
|
633
|
+
summarizerNodeParams,
|
|
636
634
|
);
|
|
637
|
-
|
|
638
635
|
this.contexts.set(id, remoteChannelContext);
|
|
639
|
-
if (this.contextsDeferred.has(id)) {
|
|
640
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
641
|
-
this.contextsDeferred.get(id)!.resolve(remoteChannelContext);
|
|
642
|
-
} else {
|
|
643
|
-
const deferred = new Deferred<IChannelContext>();
|
|
644
|
-
deferred.resolve(remoteChannelContext);
|
|
645
|
-
this.contextsDeferred.set(id, deferred);
|
|
646
|
-
}
|
|
647
636
|
}
|
|
648
637
|
break;
|
|
649
638
|
}
|
|
@@ -923,7 +912,7 @@ export class FluidDataStoreRuntime
|
|
|
923
912
|
snapshot,
|
|
924
913
|
type: channel.attributes.type,
|
|
925
914
|
};
|
|
926
|
-
this.pendingAttach.
|
|
915
|
+
this.pendingAttach.add(channel.id);
|
|
927
916
|
this.submit(DataStoreMessageType.Attach, message);
|
|
928
917
|
|
|
929
918
|
const context = this.contexts.get(channel.id) as LocalChannelContextBase;
|
|
@@ -1001,11 +990,35 @@ export class FluidDataStoreRuntime
|
|
|
1001
990
|
}
|
|
1002
991
|
|
|
1003
992
|
public async applyStashedOp(content: any): Promise<unknown> {
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
993
|
+
const type = content?.type as DataStoreMessageType;
|
|
994
|
+
switch (type) {
|
|
995
|
+
case DataStoreMessageType.Attach: {
|
|
996
|
+
const attachMessage = content.content as IAttachMessage;
|
|
997
|
+
// local means this node will throw if summarized; this is fine because only interactive clients will have stashed ops
|
|
998
|
+
const summarizerNodeParams: CreateChildSummarizerNodeParam = {
|
|
999
|
+
type: CreateSummarizerNodeSource.Local,
|
|
1000
|
+
};
|
|
1001
|
+
const context = this.createRemoteChannelContext(
|
|
1002
|
+
attachMessage,
|
|
1003
|
+
summarizerNodeParams,
|
|
1004
|
+
);
|
|
1005
|
+
this.pendingAttach.add(attachMessage.id);
|
|
1006
|
+
this.contexts.set(attachMessage.id, context);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
case DataStoreMessageType.ChannelOp: {
|
|
1010
|
+
const envelope = content.content as IEnvelope;
|
|
1011
|
+
const channelContext = this.contexts.get(envelope.address);
|
|
1012
|
+
assert(
|
|
1013
|
+
!!channelContext,
|
|
1014
|
+
0x184 /* "There should be a channel context for the op" */,
|
|
1015
|
+
);
|
|
1016
|
+
await channelContext.getChannel();
|
|
1017
|
+
return channelContext.applyStashedOp(envelope.contents);
|
|
1018
|
+
}
|
|
1019
|
+
default:
|
|
1020
|
+
unreachableCase(type);
|
|
1021
|
+
}
|
|
1009
1022
|
}
|
|
1010
1023
|
|
|
1011
1024
|
private setChannelDirty(address: string): void {
|