@fluidframework/container-runtime 2.20.0 → 2.21.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/.eslintrc.cjs +36 -6
- package/CHANGELOG.md +38 -0
- package/api-report/container-runtime.legacy.alpha.api.md +31 -31
- package/dist/batchTracker.d.ts +1 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +14 -11
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts +1 -0
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js +7 -5
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +63 -41
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +2 -2
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +4 -4
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +14 -30
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +264 -194
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js +6 -3
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +16 -11
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +1 -0
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +5 -5
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +36 -14
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +2 -0
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +8 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +1 -0
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +8 -5
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +2 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +29 -15
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/inboundBatchAggregator.js +3 -3
- package/dist/inboundBatchAggregator.js.map +1 -1
- package/dist/layerCompatState.d.ts +19 -0
- package/dist/layerCompatState.d.ts.map +1 -0
- package/dist/layerCompatState.js +64 -0
- package/dist/layerCompatState.js.map +1 -0
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.js +2 -2
- package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +3 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +13 -19
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +3 -0
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +4 -1
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +5 -3
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +13 -10
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +14 -11
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +3 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +11 -15
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +3 -1
- package/dist/opLifecycle/remoteMessageProcessor.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/pendingStateManager.d.ts +3 -4
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +11 -10
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +7 -0
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +6 -4
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -0
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +13 -11
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +7 -2
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +2 -2
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +38 -17
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +1 -0
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +18 -9
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +1 -0
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/index.d.ts.map +1 -1
- package/dist/summary/summarizerNode/index.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +30 -31
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +7 -0
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +3 -4
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +9 -6
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +4 -1
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +3 -2
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +19 -8
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +12 -9
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -2
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +14 -11
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts +1 -0
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js +7 -5
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +66 -42
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +2 -2
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +5 -5
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +14 -30
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +271 -196
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js +6 -3
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +16 -11
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +1 -0
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +6 -6
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +39 -15
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +2 -0
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +8 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +1 -0
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +8 -5
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +2 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +32 -16
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/inboundBatchAggregator.js +4 -4
- package/lib/inboundBatchAggregator.js.map +1 -1
- package/lib/layerCompatState.d.ts +19 -0
- package/lib/layerCompatState.d.ts.map +1 -0
- package/lib/layerCompatState.js +60 -0
- package/lib/layerCompatState.js.map +1 -0
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.js +2 -2
- package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +3 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +13 -19
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +3 -0
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +4 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +5 -3
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +13 -10
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +14 -11
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +3 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +11 -15
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +3 -1
- package/lib/opLifecycle/remoteMessageProcessor.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/pendingStateManager.d.ts +3 -4
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +12 -11
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +7 -0
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +6 -4
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -0
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +13 -11
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +7 -2
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +2 -2
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +38 -17
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +1 -0
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +18 -9
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +1 -0
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/index.d.ts.map +1 -1
- package/lib/summary/summarizerNode/index.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +30 -31
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +7 -0
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +3 -4
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +9 -6
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +4 -1
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +2 -2
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +19 -8
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +12 -9
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +21 -43
- package/src/batchTracker.ts +3 -3
- package/src/blobManager/blobManager.ts +16 -14
- package/src/blobManager/blobManagerSnapSum.ts +8 -8
- package/src/channelCollection.ts +63 -44
- package/src/connectionTelemetry.ts +12 -6
- package/src/containerRuntime.ts +306 -235
- package/src/dataStore.ts +6 -3
- package/src/dataStoreContext.ts +16 -16
- package/src/dataStoreContexts.ts +1 -0
- package/src/deltaScheduler.ts +6 -6
- package/src/gc/garbageCollection.ts +47 -20
- package/src/gc/gcConfigs.ts +9 -1
- package/src/gc/gcDefinitions.ts +12 -0
- package/src/gc/gcHelpers.ts +9 -4
- package/src/gc/gcSummaryStateTracker.ts +3 -1
- package/src/gc/gcTelemetry.ts +26 -11
- package/src/inboundBatchAggregator.ts +4 -4
- package/src/layerCompatState.ts +75 -0
- package/src/messageTypes.ts +2 -0
- package/src/opLifecycle/README.md +43 -34
- package/src/opLifecycle/duplicateBatchDetector.ts +2 -2
- package/src/opLifecycle/opCompressor.ts +16 -23
- package/src/opLifecycle/opDecompressor.ts +4 -1
- package/src/opLifecycle/opGroupingManager.ts +5 -4
- package/src/opLifecycle/opSplitter.ts +14 -11
- package/src/opLifecycle/outbox.ts +13 -20
- package/src/opLifecycle/remoteMessageProcessor.ts +3 -1
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +15 -10
- package/src/summary/documentSchema.ts +11 -4
- package/src/summary/orderedClientElection.ts +14 -11
- package/src/summary/runWhileConnectedCoordinator.ts +6 -0
- package/src/summary/runningSummarizer.ts +43 -19
- package/src/summary/summarizer.ts +24 -11
- package/src/summary/summarizerClientElection.ts +2 -0
- package/src/summary/summarizerHeuristics.ts +1 -1
- package/src/summary/summarizerNode/index.ts +1 -0
- package/src/summary/summarizerNode/summarizerNode.ts +32 -31
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +4 -4
- package/src/summary/summarizerTypes.ts +7 -0
- package/src/summary/summaryCollection.ts +19 -8
- package/src/summary/summaryFormat.ts +10 -5
- package/src/summary/summaryGenerator.ts +25 -10
- package/src/summary/summaryManager.ts +14 -12
- package/container-runtime.test-files.tar +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreContext.js","sourceRoot":"","sources":["../src/dataStoreContext.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { AttachState, IAudience } from \"@fluidframework/container-definitions\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions/internal\";\nimport {\n\tFluidObject,\n\tIDisposable,\n\tIRequest,\n\tIResponse,\n\tITelemetryBaseProperties,\n\ttype IEvent,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\ttype IFluidHandleContext,\n\ttype IFluidHandleInternal,\n\ttype ITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { assert, LazyPromise, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { IClientDetails, IQuorumClients } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentStorageService,\n\ttype ISnapshot,\n\tIDocumentMessage,\n\tISnapshotTree,\n\tITreeEntry,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tBlobTreeEntry,\n\tisInstanceOfISnapshot,\n\treadAndParse,\n} from \"@fluidframework/driver-utils/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport {\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n\tIGarbageCollectionData,\n\tCreateChildSummarizerNodeFn,\n\tCreateChildSummarizerNodeParam,\n\tFluidDataStoreRegistryEntry,\n\tIContainerRuntimeBase,\n\tIDataStore,\n\tIFluidDataStoreChannel,\n\tIFluidDataStoreContext,\n\tIFluidDataStoreContextDetached,\n\tIFluidDataStoreRegistry,\n\tIFluidParentContext,\n\tIGarbageCollectionDetailsBase,\n\tIProvideFluidDataStoreFactory,\n\tISummarizeInternalResult,\n\tISummarizeResult,\n\tISummarizerNodeWithGC,\n\tSummarizeInternalFn,\n\tchannelsTreeName,\n\tIInboundSignalMessage,\n\ttype IPendingMessagesState,\n\ttype IRuntimeMessageCollection,\n\ttype IFluidDataStoreFactory,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\taddBlobToSummary,\n\tisSnapshotFetchRequiredForLoadingGroupId,\n} from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tDataProcessingError,\n\tLoggingError,\n\tMonitoringContext,\n\tThresholdCounter,\n\tUsageError,\n\tcreateChildMonitoringContext,\n\textractSafePropertiesFromMessage,\n\tgenerateStack,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\t// eslint-disable-next-line import/no-deprecated\n\tReadFluidDataStoreAttributes,\n\tWriteFluidDataStoreAttributes,\n\tdataStoreAttributesBlobName,\n\tgetAttributesFormatVersion,\n\tgetFluidDataStoreAttributes,\n\thasIsolatedChannels,\n\tsummarizerClientType,\n\twrapSummaryInChannelsTree,\n} from \"./summary/index.js\";\n\nfunction createAttributes(\n\tpkg: readonly string[],\n\tisRootDataStore: boolean,\n): WriteFluidDataStoreAttributes {\n\tconst stringifiedPkg = JSON.stringify(pkg);\n\treturn {\n\t\tpkg: stringifiedPkg,\n\t\tsummaryFormatVersion: 2,\n\t\tisRootDataStore,\n\t};\n}\nexport function createAttributesBlob(\n\tpkg: readonly string[],\n\tisRootDataStore: boolean,\n): ITreeEntry {\n\tconst attributes = createAttributes(pkg, isRootDataStore);\n\treturn new BlobTreeEntry(dataStoreAttributesBlobName, JSON.stringify(attributes));\n}\n\n/**\n * @internal\n */\nexport interface ISnapshotDetails {\n\tpkg: readonly string[];\n\tisRootDataStore: boolean;\n\tsnapshot?: ISnapshotTree;\n\tsequenceNumber?: number;\n}\n\n/**\n * This is interface that every context should implement.\n * This interface is used for context's parent - ChannelCollection.\n * It should not be exposed to any other users of context.\n * @internal\n */\nexport interface IFluidDataStoreContextInternal extends IFluidDataStoreContext {\n\tgetAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;\n\n\tgetAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;\n\n\tgetInitialSnapshotDetails(): Promise<ISnapshotDetails>;\n\n\trealize(): Promise<IFluidDataStoreChannel>;\n\n\tisRoot(): Promise<boolean>;\n}\n\n/**\n * Properties necessary for creating a FluidDataStoreContext\n * @internal\n */\nexport interface IFluidDataStoreContextProps {\n\treadonly id: string;\n\treadonly parentContext: IFluidParentContext;\n\treadonly storage: IDocumentStorageService;\n\treadonly scope: FluidObject;\n\treadonly createSummarizerNodeFn: CreateChildSummarizerNodeFn;\n\treadonly pkg?: Readonly<string[]>;\n\treadonly loadingGroupId?: string;\n}\n\n/**\n * Properties necessary for creating a local FluidDataStoreContext\n * @internal\n */\nexport interface ILocalFluidDataStoreContextProps extends IFluidDataStoreContextProps {\n\treadonly pkg: Readonly<string[]> | undefined;\n\treadonly snapshotTree: ISnapshotTree | undefined;\n\treadonly makeLocallyVisibleFn: () => void;\n}\n\n/**\n * Properties necessary for creating a local FluidDataStoreContext\n * @internal\n */\nexport interface ILocalDetachedFluidDataStoreContextProps\n\textends ILocalFluidDataStoreContextProps {\n\treadonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;\n}\n\n/**\n * Properties necessary for creating a remote FluidDataStoreContext\n * @internal\n */\nexport interface IRemoteFluidDataStoreContextProps extends IFluidDataStoreContextProps {\n\treadonly snapshot: ISnapshotTree | ISnapshot | undefined;\n}\n\n// back-compat: To be removed in the future.\n// Added in \"2.0.0-rc.2.0.0\" timeframe (to support older builds).\n/**\n * @internal\n */\nexport interface IFluidDataStoreContextEvents extends IEvent {\n\t(event: \"attaching\" | \"attached\", listener: () => void);\n}\n\n/**\n * Represents the context for the store. This context is passed to the store runtime.\n * @internal\n */\nexport abstract class FluidDataStoreContext\n\textends TypedEventEmitter<IFluidDataStoreContextEvents>\n\timplements IFluidDataStoreContextInternal, IFluidParentContext, IDisposable\n{\n\tpublic get packagePath(): readonly string[] {\n\t\tassert(this.pkg !== undefined, 0x139 /* \"Undefined package path\" */);\n\t\treturn this.pkg;\n\t}\n\n\tpublic get options(): Record<string | number, unknown> {\n\t\treturn this.parentContext.options;\n\t}\n\n\tpublic get clientId(): string | undefined {\n\t\treturn this.parentContext.clientId;\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.parentContext.clientDetails;\n\t}\n\n\tpublic get baseLogger(): ITelemetryBaseLogger {\n\t\treturn this.parentContext.baseLogger;\n\t}\n\n\tpublic get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {\n\t\treturn this.parentContext.deltaManager;\n\t}\n\n\tpublic get connected(): boolean {\n\t\treturn this.parentContext.connected;\n\t}\n\n\tpublic get IFluidHandleContext(): IFluidHandleContext {\n\t\treturn this.parentContext.IFluidHandleContext;\n\t}\n\n\tpublic get containerRuntime(): IContainerRuntimeBase {\n\t\treturn this._containerRuntime;\n\t}\n\tpublic get isLoaded(): boolean {\n\t\treturn this.loaded;\n\t}\n\n\tpublic get baseSnapshot(): ISnapshotTree | undefined {\n\t\treturn this._baseSnapshot;\n\t}\n\n\tpublic get idCompressor(): IIdCompressor | undefined {\n\t\treturn this.parentContext.idCompressor;\n\t}\n\n\tprivate _disposed = false;\n\tpublic get disposed(): boolean {\n\t\treturn this._disposed;\n\t}\n\n\t/**\n\t * A Tombstoned object has been unreferenced long enough that GC knows it won't be referenced again.\n\t * Tombstoned objects are eventually deleted by GC.\n\t */\n\tprivate _tombstoned = false;\n\tpublic get tombstoned(): boolean {\n\t\treturn this._tombstoned;\n\t}\n\t/**\n\t * If true, throw an error when a tombstone data store is used.\n\t * @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.\n\t */\n\tpublic readonly gcThrowOnTombstoneUsage: boolean = false;\n\t/**\n\t * @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.\n\t */\n\tpublic readonly gcTombstoneEnforcementAllowed: boolean = false;\n\n\t/**\n\t * If true, this means that this data store context and its children have been removed from the runtime\n\t */\n\tprotected deleted: boolean = false;\n\n\tpublic get attachState(): AttachState {\n\t\treturn this._attachState;\n\t}\n\n\tpublic get IFluidDataStoreRegistry(): IFluidDataStoreRegistry | undefined {\n\t\treturn this.registry;\n\t}\n\n\tprivate baseSnapshotSequenceNumber: number | undefined;\n\n\t/**\n\t * A datastore is considered as root if it\n\t * 1. is root in memory - see isInMemoryRoot\n\t * 2. is root as part of the base snapshot that the datastore loaded from\n\t * @returns whether a datastore is root\n\t */\n\tpublic async isRoot(aliasedDataStores?: Set<string>): Promise<boolean> {\n\t\tif (this.isInMemoryRoot()) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// This if is a performance optimization.\n\t\t// We know that if the base snapshot is omitted, then the isRootDataStore flag is not set.\n\t\t// That means we can skip the expensive call to getInitialSnapshotDetails for virtualized datastores,\n\t\t// and get the information from the alias map directly.\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n\t\tif (aliasedDataStores !== undefined && (this.baseSnapshot as any)?.omitted === true) {\n\t\t\treturn aliasedDataStores.has(this.id);\n\t\t}\n\n\t\treturn (await this.getInitialSnapshotDetails()).isRootDataStore;\n\t}\n\n\t/**\n\t * There are 3 states where isInMemoryRoot needs to be true\n\t * 1. when a datastore becomes aliased. This can happen for both remote and local datastores\n\t * 2. when a datastore is created locally as root\n\t * 3. when a datastore is created locally as root and is rehydrated\n\t * @returns whether a datastore is root in memory\n\t */\n\tprotected isInMemoryRoot(): boolean {\n\t\treturn this._isInMemoryRoot;\n\t}\n\n\t/**\n\t * Returns the count of pending messages that are stored until the data store is realized.\n\t */\n\tpublic get pendingCount(): number {\n\t\treturn this.pendingMessagesState?.pendingCount ?? 0;\n\t}\n\n\tprotected registry: IFluidDataStoreRegistry | undefined;\n\n\tprotected detachedRuntimeCreation = false;\n\tprotected channel: IFluidDataStoreChannel | undefined;\n\tprivate loaded = false;\n\t/**\n\t * Tracks the messages for this data store that are sent while it's not loaded\n\t */\n\tprivate pendingMessagesState: IPendingMessagesState | undefined = {\n\t\tmessageCollections: [],\n\t\tpendingCount: 0,\n\t};\n\tprotected channelP: Promise<IFluidDataStoreChannel> | undefined;\n\tprotected _baseSnapshot: ISnapshotTree | undefined;\n\tprotected _attachState: AttachState;\n\tprivate _isInMemoryRoot: boolean = false;\n\tprotected readonly summarizerNode: ISummarizerNodeWithGC;\n\tprotected readonly mc: MonitoringContext;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\t/**\n\t * If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.\n\t * So, adding a count of how many telemetry events are logged per data store context. This can be\n\t * controlled via feature flags.\n\t */\n\tprivate localChangesTelemetryCount: number;\n\n\tpublic readonly id: string;\n\tprivate readonly _containerRuntime: IContainerRuntimeBase;\n\tprivate readonly parentContext: IFluidParentContext;\n\tpublic readonly storage: IDocumentStorageService;\n\tpublic readonly scope: FluidObject;\n\t// Represents the group to which the data store belongs too.\n\tpublic readonly loadingGroupId: string | undefined;\n\tprotected pkg?: readonly string[];\n\n\tconstructor(\n\t\tprops: IFluidDataStoreContextProps,\n\t\tprivate readonly existing: boolean,\n\t\tpublic readonly isLocalDataStore: boolean,\n\t\tprivate readonly makeLocallyVisibleFn: () => void,\n\t) {\n\t\tsuper();\n\n\t\tthis._containerRuntime = props.parentContext.containerRuntime;\n\t\tthis.parentContext = props.parentContext;\n\t\tthis.id = props.id;\n\t\tthis.storage = props.storage;\n\t\tthis.scope = props.scope;\n\t\tthis.pkg = props.pkg;\n\t\tthis.loadingGroupId = props.loadingGroupId;\n\n\t\t// URIs use slashes as delimiters. Handles use URIs.\n\t\t// Thus having slashes in types almost guarantees trouble down the road!\n\t\tassert(!this.id.includes(\"/\"), 0x13a /* Data store ID contains slash */);\n\n\t\tthis._attachState =\n\t\t\tthis.parentContext.attachState !== AttachState.Detached && this.existing\n\t\t\t\t? this.parentContext.attachState\n\t\t\t\t: AttachState.Detached;\n\n\t\tconst thisSummarizeInternal = async (\n\t\t\tfullTree: boolean,\n\t\t\ttrackState: boolean,\n\t\t\ttelemetryContext?: ITelemetryContext,\n\t\t): Promise<ISummarizeInternalResult> =>\n\t\t\tthis.summarizeInternal(fullTree, trackState, telemetryContext);\n\n\t\tthis.summarizerNode = props.createSummarizerNodeFn(\n\t\t\tthisSummarizeInternal,\n\t\t\tasync (fullGC?: boolean) => this.getGCDataInternal(fullGC),\n\t\t);\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: this.baseLogger,\n\t\t\tnamespace: \"FluidDataStoreContext\",\n\t\t\tproperties: {\n\t\t\t\tall: tagCodeArtifacts({\n\t\t\t\t\tfluidDataStoreId: this.id,\n\t\t\t\t\t// The package name is a getter because `this.pkg` may not be initialized during construction.\n\t\t\t\t\t// For data stores loaded from summary, it is initialized during data store realization.\n\t\t\t\t\tfullPackageName: () => this.pkg?.join(\"/\"),\n\t\t\t\t}),\n\t\t\t},\n\t\t});\n\t\tthis.thresholdOpsCounter = new ThresholdCounter(\n\t\t\tFluidDataStoreContext.pendingOpsCountThreshold,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// By default, a data store can log maximum 10 local changes telemetry in summarizer.\n\t\tthis.localChangesTelemetryCount =\n\t\t\tthis.mc.config.getNumber(\"Fluid.Telemetry.LocalChangesTelemetryCount\") ?? 10;\n\t}\n\n\tpublic dispose(): void {\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis._disposed = true;\n\n\t\t// Dispose any pending runtime after it gets fulfilled\n\t\t// Errors are logged where this.channelP is consumed/generated (realizeCore(), bindRuntime())\n\t\tif (this.channelP) {\n\t\t\tthis.channelP\n\t\t\t\t.then((runtime) => {\n\t\t\t\t\truntime.dispose();\n\t\t\t\t})\n\t\t\t\t.catch((error) => {});\n\t\t}\n\t}\n\n\t/**\n\t * When delete is called, that means that the data store is permanently removed from the runtime, and will not show up in future summaries\n\t * This function is called to prevent ops from being generated from this data store once it has been deleted. Furthermore, this data store\n\t * should not receive any ops/signals.\n\t */\n\tpublic delete(): void {\n\t\tthis.deleted = true;\n\t}\n\n\tpublic setTombstone(tombstone: boolean): void {\n\t\tif (this.tombstoned === tombstone) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._tombstoned = tombstone;\n\t}\n\n\tpublic abstract setAttachState(\n\t\tattachState: AttachState.Attaching | AttachState.Attached,\n\t): void;\n\n\tprivate rejectDeferredRealize(\n\t\treason: string,\n\t\tfailedPkgPath?: string,\n\t\tfullPackageName?: readonly string[],\n\t): never {\n\t\tthrow new LoggingError(\n\t\t\treason,\n\t\t\ttagCodeArtifacts({\n\t\t\t\tfailedPkgPath,\n\t\t\t\tpackagePath: fullPackageName?.join(\"/\"),\n\t\t\t}),\n\t\t);\n\t}\n\n\tpublic async realize(): Promise<IFluidDataStoreChannel> {\n\t\tassert(\n\t\t\t!this.detachedRuntimeCreation,\n\t\t\t0x13d /* \"Detached runtime creation on realize()\" */,\n\t\t);\n\t\tif (!this.channelP) {\n\t\t\tthis.channelP = this.realizeCore(this.existing).catch((error) => {\n\t\t\t\tconst errorWrapped = DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\terror,\n\t\t\t\t\t\"realizeFluidDataStoreContext\",\n\t\t\t\t);\n\t\t\t\terrorWrapped.addTelemetryProperties(\n\t\t\t\t\ttagCodeArtifacts({\n\t\t\t\t\t\tfullPackageName: this.pkg?.join(\"/\"),\n\t\t\t\t\t\tfluidDataStoreId: this.id,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"RealizeError\" }, errorWrapped);\n\t\t\t\tthrow errorWrapped;\n\t\t\t});\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tprotected async factoryFromPackagePath(): Promise<IFluidDataStoreFactory> {\n\t\tconst packages = this.pkg;\n\t\tif (packages === undefined) {\n\t\t\tthis.rejectDeferredRealize(\"packages is undefined\");\n\t\t}\n\n\t\tlet entry: FluidDataStoreRegistryEntry | undefined;\n\t\tlet registry: IFluidDataStoreRegistry | undefined =\n\t\t\tthis.parentContext.IFluidDataStoreRegistry;\n\t\tlet lastPkg: string | undefined;\n\t\tfor (const pkg of packages) {\n\t\t\tif (!registry) {\n\t\t\t\tthis.rejectDeferredRealize(\"No registry for package\", lastPkg, packages);\n\t\t\t}\n\t\t\tlastPkg = pkg;\n\t\t\tentry = registry.getSync?.(pkg) ?? (await registry.get(pkg));\n\t\t\tif (!entry) {\n\t\t\t\tthis.rejectDeferredRealize(\n\t\t\t\t\t\"Registry does not contain entry for the package\",\n\t\t\t\t\tpkg,\n\t\t\t\t\tpackages,\n\t\t\t\t);\n\t\t\t}\n\t\t\tregistry = entry.IFluidDataStoreRegistry;\n\t\t}\n\t\tconst factory = entry?.IFluidDataStoreFactory;\n\t\tif (factory === undefined) {\n\t\t\tthis.rejectDeferredRealize(\"Can't find factory for package\", lastPkg, packages);\n\t\t}\n\n\t\tassert(this.registry === undefined, 0x157 /* \"datastore registry already attached\" */);\n\t\tthis.registry = registry;\n\n\t\treturn factory;\n\t}\n\n\tcreateChildDataStore<T extends IFluidDataStoreFactory>(\n\t\tchildFactory: T,\n\t): ReturnType<Exclude<T[\"createDataStore\"], undefined>> {\n\t\tconst maybe = this.registry?.getSync?.(childFactory.type);\n\n\t\tconst isUndefined = maybe === undefined;\n\t\tconst diffInstance = maybe?.IFluidDataStoreFactory !== childFactory;\n\n\t\tif (isUndefined || diffInstance) {\n\t\t\tthrow new UsageError(\n\t\t\t\t\"The provided factory instance must be synchronously available as a child of this datastore\",\n\t\t\t\t{ isUndefined, diffInstance },\n\t\t\t);\n\t\t}\n\t\tif (childFactory?.createDataStore === undefined) {\n\t\t\tthrow new UsageError(\"createDataStore must exist on the provided factory\", {\n\t\t\t\tnoCreateDataStore: true,\n\t\t\t});\n\t\t}\n\n\t\tconst context = this._containerRuntime.createDetachedDataStore([\n\t\t\t...this.packagePath,\n\t\t\tchildFactory.type,\n\t\t]);\n\t\tassert(\n\t\t\tcontext instanceof LocalDetachedFluidDataStoreContext,\n\t\t\t0xa89 /* must be a LocalDetachedFluidDataStoreContext */,\n\t\t);\n\n\t\tconst created = childFactory.createDataStore(context) as ReturnType<\n\t\t\tExclude<T[\"createDataStore\"], undefined>\n\t\t>;\n\t\tcontext.unsafe_AttachRuntimeSync(created.runtime);\n\t\treturn created;\n\t}\n\n\tprivate async realizeCore(existing: boolean): Promise<IFluidDataStoreChannel> {\n\t\tconst details = await this.getInitialSnapshotDetails();\n\t\t// Base snapshot is the baseline where pending ops are applied to.\n\t\t// It is important that this be in sync with the pending ops, and also\n\t\t// that it is set here, before bindRuntime is called.\n\t\tthis._baseSnapshot = details.snapshot;\n\t\tthis.baseSnapshotSequenceNumber = details.sequenceNumber;\n\t\tassert(this.pkg === details.pkg, 0x13e /* \"Unexpected package path\" */);\n\n\t\tconst factory = await this.factoryFromPackagePath();\n\n\t\tconst channel = await factory.instantiateDataStore(this, existing);\n\t\tassert(channel !== undefined, 0x140 /* \"undefined channel on datastore context\" */);\n\t\tawait this.bindRuntime(channel, existing);\n\t\t// This data store may have been disposed before the channel is created during realization. If so,\n\t\t// dispose the channel now.\n\t\tif (this.disposed) {\n\t\t\tchannel.dispose();\n\t\t}\n\n\t\treturn channel;\n\t}\n\n\t/**\n\t * Notifies this object about changes in the connection state.\n\t * @param value - New connection state.\n\t * @param clientId - ID of the client. Its old ID when in disconnected state and\n\t * its new client ID when we are connecting or connected.\n\t */\n\tpublic setConnectionState(connected: boolean, clientId?: string): void {\n\t\t// ConnectionState should not fail in tombstone mode as this is internally run\n\t\tthis.verifyNotClosed(\"setConnectionState\", false /* checkTombstone */);\n\n\t\t// Connection events are ignored if the store is not yet loaded\n\t\tif (!this.loaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tassert(this.connected === connected, 0x141 /* \"Unexpected connected state\" */);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tthis.channel!.setConnectionState(connected, clientId);\n\t}\n\n\t/**\n\t * back-compat ADO 21575: This is temporary and will be removed once the compat requirement across Runtime and\n\t * Datastore boundary is satisfied.\n\t * Process the messages to maintain backwards compatibility. The `processMessages` function is added to\n\t * IFluidDataStoreChannel in 2.5.0. For channels before that, call `process` for each message.\n\t */\n\tprivate processMessagesCompat(\n\t\tchannel: IFluidDataStoreChannel,\n\t\tmessageCollection: IRuntimeMessageCollection,\n\t): void {\n\t\tif (channel.processMessages !== undefined) {\n\t\t\tchannel.processMessages(messageCollection);\n\t\t} else {\n\t\t\tconst { envelope, messagesContent, local } = messageCollection;\n\t\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\t\tchannel.process(\n\t\t\t\t\t{ ...envelope, contents, clientSequenceNumber },\n\t\t\t\t\tlocal,\n\t\t\t\t\tlocalOpMetadata,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Process messages for this data store. The messages here are contiguous messages for this data store in a batch.\n\t * @param messageCollection - The collection of messages to process.\n\t */\n\tpublic processMessages(messageCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messageCollection;\n\t\tconst safeTelemetryProps = extractSafePropertiesFromMessage(envelope);\n\t\t// Tombstone error is logged in garbage collector. So, set \"checkTombstone\" to false when calling\n\t\t// \"verifyNotClosed\" which logs tombstone errors.\n\t\tthis.verifyNotClosed(\"process\", false /* checkTombstone */, safeTelemetryProps);\n\n\t\tthis.summarizerNode.recordChange(envelope as ISequencedDocumentMessage);\n\n\t\tif (this.loaded) {\n\t\t\tassert(this.channel !== undefined, 0xa68 /* Channel is not loaded */);\n\t\t\tthis.processMessagesCompat(this.channel, messageCollection);\n\t\t} else {\n\t\t\tassert(!local, 0x142 /* \"local store channel is not loaded\" */);\n\t\t\tassert(\n\t\t\t\tthis.pendingMessagesState !== undefined,\n\t\t\t\t0xa69 /* pending messages queue is undefined */,\n\t\t\t);\n\t\t\tthis.pendingMessagesState.messageCollections.push({\n\t\t\t\t...messageCollection,\n\t\t\t\tmessagesContent: Array.from(messagesContent),\n\t\t\t});\n\t\t\tthis.pendingMessagesState.pendingCount += messagesContent.length;\n\t\t\tthis.thresholdOpsCounter.sendIfMultiple(\n\t\t\t\t\"StorePendingOps\",\n\t\t\t\tthis.pendingMessagesState.pendingCount,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic processSignal(message: IInboundSignalMessage, local: boolean): void {\n\t\tthis.verifyNotClosed(\"processSignal\");\n\n\t\t// Signals are ignored if the store is not yet loaded\n\t\tif (!this.loaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.channel?.processSignal(message, local);\n\t}\n\n\tpublic getQuorum(): IQuorumClients {\n\t\treturn this.parentContext.getQuorum();\n\t}\n\n\tpublic getAudience(): IAudience {\n\t\treturn this.parentContext.getAudience();\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\tawait this.realize();\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst summarizeResult = await this.channel!.summarize(\n\t\t\tfullTree,\n\t\t\ttrackState,\n\t\t\ttelemetryContext,\n\t\t);\n\n\t\t// Wrap dds summaries in .channels subtree.\n\t\twrapSummaryInChannelsTree(summarizeResult);\n\t\tconst pathPartsForChildren = [channelsTreeName];\n\n\t\t// Add data store's attributes to the summary.\n\t\tconst { pkg } = await this.getInitialSnapshotDetails();\n\t\tconst isRoot = await this.isRoot();\n\t\tconst attributes = createAttributes(pkg, isRoot);\n\t\taddBlobToSummary(summarizeResult, dataStoreAttributesBlobName, JSON.stringify(attributes));\n\n\t\t// If we are not referenced, mark the summary tree as unreferenced. Also, update unreferenced blob\n\t\t// size in the summary stats with the blobs size of this data store.\n\t\tif (!this.summarizerNode.isReferenced()) {\n\t\t\tsummarizeResult.summary.unreferenced = true;\n\t\t\tsummarizeResult.stats.unreferencedBlobSize = summarizeResult.stats.totalBlobSize;\n\t\t}\n\n\t\t// Add loadingGroupId to the summary\n\t\tif (this.loadingGroupId !== undefined) {\n\t\t\tsummarizeResult.summary.groupId = this.loadingGroupId;\n\t\t}\n\n\t\treturn {\n\t\t\t...summarizeResult,\n\t\t\tid: this.id,\n\t\t\tpathPartsForChildren,\n\t\t};\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this data store\n\t * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the\n\t * document.\n\t * If there is no new data in this data store 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 data used for garbage collection. This is called when there is new data since last summary. It\n\t * realizes the data store and calls into each channel context 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\tawait this.realize();\n\t\tassert(\n\t\t\tthis.channel !== undefined,\n\t\t\t0x143 /* \"Channel should not be undefined when running GC\" */,\n\t\t);\n\n\t\treturn this.channel.getGCData(fullGC);\n\t}\n\n\t/**\n\t * After GC has run, called to notify the data store of routes used in it. These are used for the following:\n\t * 1. To identify if this data store is being referenced in the document or not.\n\t * 2. To determine if it needs to re-summarize in case used routes changed since last summary.\n\t * 3. To notify child contexts of their used routes. This is done immediately if the data store is loaded.\n\t * Else, it is done by the data stores's summarizer node when child summarizer nodes are created.\n\t *\n\t * @param usedRoutes - The routes that are used in this data store.\n\t */\n\tpublic updateUsedRoutes(usedRoutes: string[]): void {\n\t\t// Update the used routes in this data store's summarizer node.\n\t\tthis.summarizerNode.updateUsedRoutes(usedRoutes);\n\n\t\t// If the channel doesn't exist yet (data store is not realized), the summarizer node will update it\n\t\t// when it creates child nodes.\n\t\tif (!this.channel) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the route to this data store, if it exists.\n\t\tconst usedChannelRoutes = usedRoutes.filter((id: string) => {\n\t\t\treturn id !== \"/\" && id !== \"\";\n\t\t});\n\t\tthis.channel.updateUsedRoutes(usedChannelRoutes);\n\t}\n\n\t/**\n\t * Called when a new outbound reference is added to another node. This is used by garbage collection to identify\n\t * all references added in the system.\n\t *\n\t * @param fromPath - The absolute path of the node that added the reference.\n\t * @param toPath - The absolute path of the outbound node that is referenced.\n\t * @param messageTimestampMs - The timestamp of the message that added the reference.\n\t */\n\tpublic addedGCOutboundRoute(\n\t\tfromPath: string,\n\t\ttoPath: string,\n\t\tmessageTimestampMs?: number,\n\t): void {\n\t\tthis.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);\n\t}\n\n\t// eslint-disable-next-line jsdoc/require-description\n\t/**\n\t * @deprecated 0.18.Should call request on the runtime directly\n\t */\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\tconst runtime = await this.realize();\n\t\treturn runtime.request(request);\n\t}\n\n\tpublic submitMessage(type: string, content: unknown, localOpMetadata: unknown): void {\n\t\tthis.verifyNotClosed(\"submitMessage\");\n\t\tassert(!!this.channel, 0x146 /* \"Channel must exist when submitting message\" */);\n\t\t// Summarizer clients should not submit messages.\n\t\tthis.identifyLocalChangeInSummarizer(\"DataStoreMessageSubmittedInSummarizer\", type);\n\n\t\tthis.parentContext.submitMessage(type, content, localOpMetadata);\n\t}\n\n\t/**\n\t * This is called from a SharedSummaryBlock that does not generate ops but only wants to be part of the summary.\n\t * It indicates that there is data in the object that needs to be summarized.\n\t * We will update the latestSequenceNumber of the summary tracker of this\n\t * store and of the object's channel.\n\t *\n\t * @param address - The address of the channel that is dirty.\n\t *\n\t */\n\tpublic setChannelDirty(address: string): void {\n\t\tthis.verifyNotClosed(\"setChannelDirty\");\n\n\t\t// Get the latest sequence number.\n\t\tconst latestSequenceNumber = this.deltaManager.lastSequenceNumber;\n\n\t\tthis.summarizerNode.invalidate(latestSequenceNumber);\n\n\t\tconst channelSummarizerNode = this.summarizerNode.getChild(address);\n\n\t\tif (channelSummarizerNode) {\n\t\t\tchannelSummarizerNode.invalidate(latestSequenceNumber); // TODO: lazy load problem?\n\t\t}\n\t}\n\n\t/**\n\t * Submits the signal to be sent to other clients.\n\t * @param type - Type of the signal.\n\t * @param content - Content of the signal. Should be a JSON serializable object or primitive.\n\t * @param targetClientId - When specified, the signal is only sent to the provided client id.\n\t */\n\tpublic submitSignal(type: string, content: unknown, targetClientId?: string): void {\n\t\tthis.verifyNotClosed(\"submitSignal\");\n\n\t\tassert(!!this.channel, 0x147 /* \"Channel must exist on submitting signal\" */);\n\t\treturn this.parentContext.submitSignal(type, content, targetClientId);\n\t}\n\n\t/**\n\t * This is called by the data store channel when it becomes locally visible indicating that it is ready to become\n\t * globally visible now.\n\t */\n\tpublic makeLocallyVisible(): void {\n\t\tassert(this.channel !== undefined, 0x2cf /* \"undefined channel on datastore context\" */);\n\t\tthis.makeLocallyVisibleFn();\n\t}\n\n\tprotected processPendingOps(channel: IFluidDataStoreChannel): void {\n\t\tconst baseSequenceNumber = this.baseSnapshotSequenceNumber ?? -1;\n\n\t\tassert(\n\t\t\tthis.pendingMessagesState !== undefined,\n\t\t\t0xa6a /* pending messages queue is undefined */,\n\t\t);\n\t\tfor (const messageCollection of this.pendingMessagesState.messageCollections) {\n\t\t\t// Only process ops whose seq number is greater than snapshot sequence number from which it loaded.\n\t\t\tif (messageCollection.envelope.sequenceNumber > baseSequenceNumber) {\n\t\t\t\tthis.processMessagesCompat(channel, messageCollection);\n\t\t\t}\n\t\t}\n\n\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pendingMessagesState.pendingCount);\n\t\tthis.pendingMessagesState = undefined;\n\t}\n\n\tprotected completeBindingRuntime(channel: IFluidDataStoreChannel): void {\n\t\t// And now mark the runtime active\n\t\tthis.loaded = true;\n\t\tthis.channel = channel;\n\n\t\t// Channel does not know when it's \"live\" (as in - starts to receive events in the system)\n\t\t// It may read current state of the system when channel was created, but it was not getting any updates\n\t\t// through creation process and could have missed events. So update it on current state.\n\t\t// Once this.loaded is set (above), it will stat receiving events.\n\t\tchannel.setConnectionState(this.connected, this.clientId);\n\n\t\t// Freeze the package path to ensure that someone doesn't modify it when it is\n\t\t// returned in packagePath().\n\t\tObject.freeze(this.pkg);\n\t}\n\n\tprotected async bindRuntime(\n\t\tchannel: IFluidDataStoreChannel,\n\t\texisting: boolean,\n\t): Promise<void> {\n\t\tif (this.channel) {\n\t\t\tthrow new Error(\"Runtime already bound\");\n\t\t}\n\n\t\tassert(\n\t\t\t!this.detachedRuntimeCreation,\n\t\t\t0x148 /* \"Detached runtime creation on runtime bind\" */,\n\t\t);\n\t\tassert(this.pkg !== undefined, 0x14a /* \"Undefined package path\" */);\n\n\t\tif (!existing) {\n\t\t\t// Execute data store's entry point to make sure that for a local (aka detached from container) data store, the\n\t\t\t// entryPoint initialization function is called before the data store gets attached and potentially connected to\n\t\t\t// the delta stream, so it gets a chance to do things while the data store is still \"purely local\".\n\t\t\t// This preserves the behavior from before we introduced entryPoints, where the instantiateDataStore method\n\t\t\t// of data store factories tends to construct the data object (at least kick off an async method that returns\n\t\t\t// it); that code moved to the entryPoint initialization function, so we want to ensure it still executes\n\t\t\t// before the data store is attached.\n\t\t\tawait channel.entryPoint.get();\n\t\t}\n\n\t\tthis.processPendingOps(channel);\n\t\tthis.completeBindingRuntime(channel);\n\t}\n\n\tpublic async getAbsoluteUrl(relativeUrl: string): Promise<string | undefined> {\n\t\tif (this.attachState !== AttachState.Attached) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.parentContext.getAbsoluteUrl(relativeUrl);\n\t}\n\n\t/**\n\t * Get the summary required when attaching this context's DataStore.\n\t * Used for both Container Attach and DataStore Attach.\n\t */\n\tpublic abstract getAttachSummary(\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * Get the GC Data for the initial state being attached so remote clients can learn of this DataStore's\n\t * outbound routes.\n\t */\n\tpublic abstract getAttachGCData(\n\t\ttelemetryContext?: ITelemetryContext,\n\t): IGarbageCollectionData;\n\n\tpublic abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;\n\n\t// eslint-disable-next-line jsdoc/require-description\n\t/**\n\t * @deprecated Sets the datastore as root, for aliasing purposes: #7948\n\t * This method should not be used outside of the aliasing context.\n\t * It will be removed, as the source of truth for this flag will be the aliasing blob.\n\t */\n\tpublic setInMemoryRoot(): void {\n\t\tthis._isInMemoryRoot = true;\n\t}\n\n\t// eslint-disable-next-line jsdoc/require-description\n\t/**\n\t * @deprecated The functionality to get base GC details has been moved to summarizer node.\n\t */\n\tpublic async getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase> {\n\t\treturn {};\n\t}\n\n\tpublic reSubmit(type: string, contents: unknown, localOpMetadata: unknown): void {\n\t\tassert(!!this.channel, 0x14b /* \"Channel must exist when resubmitting ops\" */);\n\t\tthis.channel.reSubmit(type, contents, localOpMetadata);\n\t}\n\n\tpublic rollback(type: string, contents: unknown, localOpMetadata: unknown): void {\n\t\tif (!this.channel) {\n\t\t\tthrow new Error(\"Channel must exist when rolling back ops\");\n\t\t}\n\t\tif (!this.channel.rollback) {\n\t\t\tthrow new Error(\"Channel doesn't support rollback\");\n\t\t}\n\t\tthis.channel.rollback(type, contents, localOpMetadata);\n\t}\n\n\tpublic async applyStashedOp(contents: unknown): Promise<unknown> {\n\t\tif (!this.channel) {\n\t\t\tawait this.realize();\n\t\t}\n\t\tassert(!!this.channel, 0x14c /* \"Channel must exist when rebasing ops\" */);\n\t\treturn this.channel.applyStashedOp(contents);\n\t}\n\n\tprivate verifyNotClosed(\n\t\tcallSite: string,\n\t\tcheckTombstone = true,\n\t\tsafeTelemetryProps: ITelemetryBaseProperties = {},\n\t): void {\n\t\tif (this.deleted) {\n\t\t\tconst messageString = `Context is deleted! Call site [${callSite}]`;\n\t\t\tconst error = DataProcessingError.create(\n\t\t\t\tmessageString,\n\t\t\t\tcallSite,\n\t\t\t\tundefined /* sequencedMessage */,\n\t\t\t\tsafeTelemetryProps,\n\t\t\t);\n\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"GC_Deleted_DataStore_Changed\",\n\t\t\t\t\tcallSite,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (this._disposed) {\n\t\t\tthrow new Error(`Context is closed! Call site [${callSite}]`);\n\t\t}\n\n\t\tif (checkTombstone && this.tombstoned) {\n\t\t\tconst messageString = `Context is tombstoned! Call site [${callSite}]`;\n\t\t\tconst error = DataProcessingError.create(\n\t\t\t\tmessageString,\n\t\t\t\tcallSite,\n\t\t\t\tundefined /* sequencedMessage */,\n\t\t\t\tsafeTelemetryProps,\n\t\t\t);\n\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"GC_Tombstone_DataStore_Changed\",\n\t\t\t\t\tcategory: \"generic\",\n\t\t\t\t\tcallSite,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Summarizer client should not have local changes. These changes can become part of the summary and can break\n\t * eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas\n\t * other clients that are up-to-date till seq# 100 may not have them yet.\n\t */\n\tprotected identifyLocalChangeInSummarizer(eventName: string, type?: string): void {\n\t\tif (\n\t\t\tthis.clientDetails.type !== summarizerClientType ||\n\t\t\tthis.localChangesTelemetryCount <= 0\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Log a telemetry if there are local changes in the summarizer. This will give us data on how often\n\t\t// this is happening and which data stores do this. The eventual goal is to disallow local changes\n\t\t// in the summarizer and the data will help us plan this.\n\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\teventName,\n\t\t\ttype,\n\t\t\tisSummaryInProgress: this.summarizerNode.isSummaryInProgress?.(),\n\t\t\tstack: generateStack(30),\n\t\t});\n\t\tthis.localChangesTelemetryCount--;\n\t}\n\n\tpublic getCreateChildSummarizerNodeFn(\n\t\tid: string,\n\t\tcreateParam: CreateChildSummarizerNodeParam,\n\t) {\n\t\treturn (\n\t\t\tsummarizeInternal: SummarizeInternalFn,\n\t\t\tgetGCDataFn: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\t\t): ISummarizerNodeWithGC =>\n\t\t\tthis.summarizerNode.createChild(\n\t\t\t\tsummarizeInternal,\n\t\t\t\tid,\n\t\t\t\tcreateParam,\n\t\t\t\tundefined /* config */,\n\t\t\t\tgetGCDataFn,\n\t\t\t);\n\t}\n\n\tpublic deleteChildSummarizerNode(id: string): void {\n\t\tthis.summarizerNode.deleteChild(id);\n\t}\n\n\tpublic async uploadBlob(\n\t\tblob: ArrayBufferLike,\n\t\tsignal?: AbortSignal,\n\t): Promise<IFluidHandleInternal<ArrayBufferLike>> {\n\t\treturn this.parentContext.uploadBlob(blob, signal);\n\t}\n}\n\n/**\n * @internal\n */\nexport class RemoteFluidDataStoreContext extends FluidDataStoreContext {\n\t// Tells whether we need to fetch the snapshot before use. This is to support Data Virtualization.\n\tprivate snapshotFetchRequired: boolean | undefined;\n\tprivate readonly runtime: IContainerRuntimeBase;\n\tprivate readonly blobContents: Map<string, ArrayBuffer> | undefined;\n\tprivate readonly isSnapshotInISnapshotFormat: boolean | undefined;\n\n\tconstructor(props: IRemoteFluidDataStoreContextProps) {\n\t\tsuper(props, true /* existing */, false /* isLocalDataStore */, () => {\n\t\t\tthrow new Error(\"Already attached\");\n\t\t});\n\n\t\tthis.runtime = props.parentContext.containerRuntime;\n\t\tif (isInstanceOfISnapshot(props.snapshot)) {\n\t\t\tthis.blobContents = props.snapshot.blobContents;\n\t\t\tthis._baseSnapshot = props.snapshot.snapshotTree;\n\t\t\tthis.isSnapshotInISnapshotFormat = true;\n\t\t} else {\n\t\t\tthis._baseSnapshot = props.snapshot;\n\t\t\tthis.isSnapshotInISnapshotFormat = false;\n\t\t}\n\t}\n\n\t/**\n\t * This API should not be called for RemoteFluidDataStoreContext. But here is one scenario where it's not the case:\n\t * The scenario (hit by stashedOps.spec.ts, \"resends attach op\" UT is the following (as far as I understand):\n\t *\n\t * 1. data store is being attached in attached container\n\t *\n\t * 2. container state is serialized (stashed ops feature)\n\t *\n\t * 3. new container instance is rehydrated (from stashed ops) -\n\t * As result, we create RemoteFluidDataStoreContext for this data store that is actually in \"attaching\" state * (as of # 2).\n\t * But its state is set to attached when loading container from stashed ops.\n\t *\n\t * 4. attach op for this data store is processed - setAttachState() is called.\n\t */\n\tpublic setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {}\n\n\tprivate readonly initialSnapshotDetailsP = new LazyPromise<ISnapshotDetails>(async () => {\n\t\t// Sequence number of the snapshot.\n\t\tlet sequenceNumber: number | undefined;\n\t\t// Check whether we need to fetch the snapshot first to load. The snapshot should be in new format to see\n\t\t// whether we want to evaluate to fetch snapshot or not for loadingGroupId. Otherwise, the snapshot\n\t\t// will contain all the blobs.\n\t\tif (\n\t\t\tthis.snapshotFetchRequired === undefined &&\n\t\t\tthis._baseSnapshot?.groupId !== undefined &&\n\t\t\tthis.isSnapshotInISnapshotFormat\n\t\t) {\n\t\t\tassert(\n\t\t\t\tthis.blobContents !== undefined,\n\t\t\t\t0x97a /* Blob contents should be present to evaluate */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tthis._baseSnapshot !== undefined,\n\t\t\t\t0x97b /* snapshotTree should be present to evaluate */,\n\t\t\t);\n\t\t\tthis.snapshotFetchRequired = isSnapshotFetchRequiredForLoadingGroupId(\n\t\t\t\tthis._baseSnapshot,\n\t\t\t\tthis.blobContents,\n\t\t\t);\n\t\t}\n\t\tif (this.snapshotFetchRequired) {\n\t\t\tassert(\n\t\t\t\tthis.loadingGroupId !== undefined,\n\t\t\t\t0x8f5 /* groupId should be present to fetch snapshot */,\n\t\t\t);\n\t\t\tconst snapshot = await this.runtime.getSnapshotForLoadingGroupId(\n\t\t\t\t[this.loadingGroupId],\n\t\t\t\t[this.id],\n\t\t\t);\n\t\t\tthis._baseSnapshot = snapshot.snapshotTree;\n\t\t\tsequenceNumber = snapshot.sequenceNumber;\n\t\t\tthis.snapshotFetchRequired = false;\n\t\t}\n\t\tlet tree = this.baseSnapshot;\n\t\tlet isRootDataStore = true;\n\n\t\tif (!!tree && tree.blobs[dataStoreAttributesBlobName] !== undefined) {\n\t\t\t// Need to get through snapshot and use that to populate extraBlobs\n\t\t\t// eslint-disable-next-line import/no-deprecated\n\t\t\tconst attributes = await readAndParse<ReadFluidDataStoreAttributes>(\n\t\t\t\tthis.storage,\n\t\t\t\ttree.blobs[dataStoreAttributesBlobName],\n\t\t\t);\n\n\t\t\tlet pkgFromSnapshot: string[];\n\t\t\t// Use the snapshotFormatVersion to determine how the pkg is encoded in the snapshot.\n\t\t\t// For snapshotFormatVersion = \"0.1\" (1) or above, pkg is jsonified, otherwise it is just a string.\n\t\t\tconst formatVersion = getAttributesFormatVersion(attributes);\n\t\t\tif (formatVersion < 1) {\n\t\t\t\tpkgFromSnapshot =\n\t\t\t\t\tattributes.pkg.startsWith('[\"') && attributes.pkg.endsWith('\"]')\n\t\t\t\t\t\t? (JSON.parse(attributes.pkg) as string[])\n\t\t\t\t\t\t: [attributes.pkg];\n\t\t\t} else {\n\t\t\t\tpkgFromSnapshot = JSON.parse(attributes.pkg) as string[];\n\t\t\t}\n\t\t\tthis.pkg = pkgFromSnapshot;\n\n\t\t\t/**\n\t\t\t * If there is no isRootDataStore in the attributes blob, set it to true. This will ensure that\n\t\t\t * data stores in older documents are not garbage collected incorrectly. This may lead to additional\n\t\t\t * roots in the document but they won't break.\n\t\t\t */\n\t\t\tisRootDataStore = attributes.isRootDataStore ?? true;\n\n\t\t\tif (hasIsolatedChannels(attributes)) {\n\t\t\t\ttree = tree.trees[channelsTreeName];\n\t\t\t\tassert(\n\t\t\t\t\ttree !== undefined,\n\t\t\t\t\t0x1fe /* \"isolated channels subtree should exist in remote datastore snapshot\" */,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tassert(\n\t\t\tthis.pkg !== undefined,\n\t\t\t0x8f6 /* The datastore context package should be defined */,\n\t\t);\n\t\treturn {\n\t\t\tpkg: this.pkg,\n\t\t\tisRootDataStore,\n\t\t\tsnapshot: tree,\n\t\t\tsequenceNumber,\n\t\t};\n\t});\n\n\tpublic async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {\n\t\treturn this.initialSnapshotDetailsP;\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachSummary}\n\t */\n\tpublic getAttachSummary(): ISummaryTreeWithStats {\n\t\tthrow new Error(\"Cannot attach remote store\");\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachGCData}\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tthrow new Error(\"Cannot attach remote store\");\n\t}\n}\n\n/**\n * Base class for detached & attached context classes\n * @internal\n */\nexport class LocalFluidDataStoreContextBase extends FluidDataStoreContext {\n\tprivate readonly snapshotTree: ISnapshotTree | undefined;\n\n\tconstructor(props: ILocalFluidDataStoreContextProps) {\n\t\tsuper(\n\t\t\tprops,\n\t\t\tprops.snapshotTree !== undefined /* existing */,\n\t\t\ttrue /* isLocalDataStore */,\n\t\t\tprops.makeLocallyVisibleFn,\n\t\t);\n\n\t\t// Summarizer client should not create local data stores.\n\t\tthis.identifyLocalChangeInSummarizer(\"DataStoreCreatedInSummarizer\");\n\n\t\tthis.snapshotTree = props.snapshotTree;\n\t}\n\n\tpublic setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {\n\t\tswitch (attachState) {\n\t\t\tcase AttachState.Attaching:\n\t\t\t\tassert(\n\t\t\t\t\tthis.attachState === AttachState.Detached,\n\t\t\t\t\t0x14d /* \"Should move from detached to attaching\" */,\n\t\t\t\t);\n\t\t\t\tthis._attachState = AttachState.Attaching;\n\t\t\t\tif (this.channel?.setAttachState) {\n\t\t\t\t\tthis.channel.setAttachState(attachState);\n\t\t\t\t} else if (this.channel) {\n\t\t\t\t\t// back-compat! To be removed in the future\n\t\t\t\t\t// Added in \"2.0.0-rc.2.0.0\" timeframe.\n\t\t\t\t\tthis.emit(\"attaching\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase AttachState.Attached:\n\t\t\t\t// We can get called into here twice, as result of both container and data store being attached, if\n\t\t\t\t// those processes overlapped, for example, in a flow like that one:\n\t\t\t\t// 1. Container attach started\n\t\t\t\t// 2. data store attachment started\n\t\t\t\t// 3. container attached\n\t\t\t\t// 4. data store attached.\n\t\t\t\tif (this.attachState !== AttachState.Attached) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tthis.attachState === AttachState.Attaching,\n\t\t\t\t\t\t0x14e /* \"Should move from attaching to attached\" */,\n\t\t\t\t\t);\n\t\t\t\t\tthis._attachState = AttachState.Attached;\n\t\t\t\t\tthis.channel?.setAttachState?.(attachState);\n\t\t\t\t\tif (this.channel?.setAttachState) {\n\t\t\t\t\t\tthis.channel.setAttachState(attachState);\n\t\t\t\t\t} else if (this.channel) {\n\t\t\t\t\t\t// back-compat! To be removed in the future\n\t\t\t\t\t\t// Added in \"2.0.0-rc.2.0.0\" timeframe.\n\t\t\t\t\t\tthis.emit(\"attached\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tunreachableCase(attachState, \"unreached\");\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachSummary}\n\t */\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {\n\t\tassert(\n\t\t\tthis.channel !== undefined,\n\t\t\t0x14f /* \"There should be a channel when generating attach message\" */,\n\t\t);\n\t\tassert(\n\t\t\tthis.pkg !== undefined,\n\t\t\t0x150 /* \"pkg should be available in local data store context\" */,\n\t\t);\n\n\t\tconst attachSummary = this.channel.getAttachSummary(telemetryContext);\n\n\t\t// Wrap dds summaries in .channels subtree.\n\t\twrapSummaryInChannelsTree(attachSummary);\n\n\t\t// Add data store's attributes to the summary.\n\t\tconst attributes = createAttributes(this.pkg, this.isInMemoryRoot());\n\t\taddBlobToSummary(attachSummary, dataStoreAttributesBlobName, JSON.stringify(attributes));\n\n\t\t// Add loadingGroupId to the summary\n\t\tif (this.loadingGroupId !== undefined) {\n\t\t\tattachSummary.summary.groupId = this.loadingGroupId;\n\t\t}\n\n\t\treturn attachSummary;\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachGCData}\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tassert(\n\t\t\tthis.channel !== undefined,\n\t\t\t0x9a6 /* There should be a channel when generating attach GC data */,\n\t\t);\n\t\treturn this.channel.getAttachGCData(telemetryContext);\n\t}\n\n\tprivate readonly initialSnapshotDetailsP = new LazyPromise<ISnapshotDetails>(async () => {\n\t\tlet snapshot = this.snapshotTree;\n\t\t// eslint-disable-next-line import/no-deprecated\n\t\tlet attributes: ReadFluidDataStoreAttributes;\n\t\tlet isRootDataStore = false;\n\t\tif (snapshot !== undefined) {\n\t\t\t// Get the dataStore attributes.\n\t\t\t// Note: storage can be undefined in special case while detached.\n\t\t\tattributes = await getFluidDataStoreAttributes(this.storage, snapshot);\n\t\t\tif (hasIsolatedChannels(attributes)) {\n\t\t\t\tsnapshot = snapshot.trees[channelsTreeName];\n\t\t\t\tassert(\n\t\t\t\t\tsnapshot !== undefined,\n\t\t\t\t\t0x1ff /* \"isolated channels subtree should exist in local datastore snapshot\" */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.pkg === undefined) {\n\t\t\t\tthis.pkg = JSON.parse(attributes.pkg) as string[];\n\t\t\t\t// If there is no isRootDataStore in the attributes blob, set it to true. This ensures that data\n\t\t\t\t// stores in older documents are not garbage collected incorrectly. This may lead to additional\n\t\t\t\t// roots in the document but they won't break.\n\t\t\t\tif (attributes.isRootDataStore ?? true) {\n\t\t\t\t\tisRootDataStore = true;\n\t\t\t\t\tthis.setInMemoryRoot();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tassert(this.pkg !== undefined, 0x152 /* \"pkg should be available in local data store\" */);\n\n\t\treturn {\n\t\t\tpkg: this.pkg,\n\t\t\tisRootDataStore,\n\t\t\tsnapshot,\n\t\t};\n\t});\n\n\tpublic async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {\n\t\treturn this.initialSnapshotDetailsP;\n\t}\n\n\t/**\n\t * A context should only be marked as deleted when its a remote context.\n\t * Session Expiry at the runtime level should have closed the container creating the local data store context\n\t * before delete is even possible. Session Expiry is at 30 days, and sweep is done 36+ days later from the time\n\t * it was unreferenced. Thus the sweeping container should have loaded from a snapshot and thus creating a remote\n\t * context.\n\t */\n\tpublic delete(): void {\n\t\t// TODO: GC:Validation - potentially prevent this from happening or asserting. Maybe throw here.\n\t\tthis.mc.logger.sendErrorEvent({\n\t\t\teventName: \"GC_Deleted_DataStore_Unexpected_Delete\",\n\t\t\tmessage: \"Unexpected deletion of a local data store context\",\n\t\t});\n\t\tsuper.delete();\n\t}\n}\n\n/**\n * context implementation for \"attached\" data store runtime.\n * Various workflows (snapshot creation, requests) result in .realize() being called\n * on context, resulting in instantiation and attachment of runtime.\n * Runtime is created using data store factory that is associated with this context.\n * @internal\n */\nexport class LocalFluidDataStoreContext extends LocalFluidDataStoreContextBase {\n\tconstructor(props: ILocalFluidDataStoreContextProps) {\n\t\tsuper(props);\n\t}\n}\n\n/**\n * Detached context. Data Store runtime will be attached to it by attachRuntime() call\n * Before attachment happens, this context is not associated with particular type of runtime\n * or factory, i.e. it's package path is undefined.\n * Attachment process provides all missing parts - package path, data store runtime, and data store factory\n */\nexport class LocalDetachedFluidDataStoreContext\n\textends LocalFluidDataStoreContextBase\n\timplements IFluidDataStoreContextDetached\n{\n\tconstructor(props: ILocalDetachedFluidDataStoreContextProps) {\n\t\tsuper(props);\n\t\tthis.detachedRuntimeCreation = true;\n\t\tthis.channelToDataStoreFn = props.channelToDataStoreFn;\n\t}\n\tprivate readonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;\n\n\tpublic async attachRuntime(\n\t\tregistry: IProvideFluidDataStoreFactory,\n\t\tdataStoreChannel: IFluidDataStoreChannel,\n\t): Promise<IDataStore> {\n\t\tassert(this.detachedRuntimeCreation, 0x154 /* \"runtime creation is already attached\" */);\n\t\tthis.detachedRuntimeCreation = false;\n\n\t\tassert(this.channelP === undefined, 0x155 /* \"channel deferral is already set\" */);\n\n\t\tthis.channelP = Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tconst factory = registry.IFluidDataStoreFactory;\n\n\t\t\t\tconst factory2 = await this.factoryFromPackagePath();\n\t\t\t\tassert(factory2 === factory, 0x156 /* \"Unexpected factory for package path\" */);\n\n\t\t\t\tawait super.bindRuntime(dataStoreChannel, false /* existing */);\n\n\t\t\t\tassert(\n\t\t\t\t\t!(await this.isRoot()),\n\t\t\t\t\t0x8f7 /* there are no more createRootDataStore() kind of APIs! */,\n\t\t\t\t);\n\n\t\t\t\treturn dataStoreChannel;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"AttachRuntimeError\" }, error);\n\t\t\t\t// The following two lines result in same exception thrown.\n\t\t\t\t// But we need to ensure that this.channelDeferred.promise is \"observed\", as otherwise\n\t\t\t\t// out UT reports unhandled exception\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\treturn this.channelToDataStoreFn(await this.channelP);\n\t}\n\n\t/**\n\t * This method provides a synchronous path for binding a runtime to the context.\n\t *\n\t * Due to its synchronous nature, it is unable to validate that the runtime\n\t * represents a datastore which is instantiable by remote clients. This could\n\t * happen if the runtime's package path does not return a factory when looked up\n\t * in the container runtime's registry, or if the runtime's entrypoint is not\n\t * properly initialized. As both of these validation's are asynchronous to preform.\n\t *\n\t * If used incorrectly, this function can result in permanent data corruption.\n\t */\n\tpublic unsafe_AttachRuntimeSync(channel: IFluidDataStoreChannel): IDataStore {\n\t\tthis.channelP = Promise.resolve(channel);\n\t\tthis.processPendingOps(channel);\n\t\tthis.completeBindingRuntime(channel);\n\t\treturn this.channelToDataStoreFn(channel);\n\t}\n\n\tpublic async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {\n\t\tif (this.detachedRuntimeCreation) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Detached Fluid Data Store context can't be realized! Please attach runtime first!\",\n\t\t\t);\n\t\t}\n\t\treturn super.getInitialSnapshotDetails();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dataStoreContext.js","sourceRoot":"","sources":["../src/dataStoreContext.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { AttachState, IAudience } from \"@fluidframework/container-definitions\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions/internal\";\nimport {\n\tFluidObject,\n\tIDisposable,\n\tIRequest,\n\tIResponse,\n\tITelemetryBaseProperties,\n\ttype IEvent,\n} from \"@fluidframework/core-interfaces\";\nimport {\n\ttype IFluidHandleContext,\n\ttype IFluidHandleInternal,\n\ttype ITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { assert, LazyPromise, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport { IClientDetails, IQuorumClients } from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentStorageService,\n\ttype ISnapshot,\n\tIDocumentMessage,\n\tISnapshotTree,\n\tITreeEntry,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tBlobTreeEntry,\n\tisInstanceOfISnapshot,\n\treadAndParse,\n} from \"@fluidframework/driver-utils/internal\";\nimport type { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport {\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n\tIGarbageCollectionData,\n\tCreateChildSummarizerNodeFn,\n\tCreateChildSummarizerNodeParam,\n\tFluidDataStoreRegistryEntry,\n\tIContainerRuntimeBase,\n\tIDataStore,\n\tIFluidDataStoreChannel,\n\tIFluidDataStoreContext,\n\tIFluidDataStoreContextDetached,\n\tIFluidDataStoreRegistry,\n\tIFluidParentContext,\n\tIGarbageCollectionDetailsBase,\n\tIProvideFluidDataStoreFactory,\n\tISummarizeInternalResult,\n\tISummarizeResult,\n\tISummarizerNodeWithGC,\n\tSummarizeInternalFn,\n\tchannelsTreeName,\n\tIInboundSignalMessage,\n\ttype IPendingMessagesState,\n\ttype IRuntimeMessageCollection,\n\ttype IFluidDataStoreFactory,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\taddBlobToSummary,\n\tisSnapshotFetchRequiredForLoadingGroupId,\n} from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tDataProcessingError,\n\tLoggingError,\n\tMonitoringContext,\n\tThresholdCounter,\n\tUsageError,\n\tcreateChildMonitoringContext,\n\textractSafePropertiesFromMessage,\n\tgenerateStack,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\t// eslint-disable-next-line import/no-deprecated\n\tReadFluidDataStoreAttributes,\n\tWriteFluidDataStoreAttributes,\n\tdataStoreAttributesBlobName,\n\tgetAttributesFormatVersion,\n\tgetFluidDataStoreAttributes,\n\thasIsolatedChannels,\n\tsummarizerClientType,\n\twrapSummaryInChannelsTree,\n} from \"./summary/index.js\";\n\nfunction createAttributes(\n\tpkg: readonly string[],\n\tisRootDataStore: boolean,\n): WriteFluidDataStoreAttributes {\n\tconst stringifiedPkg = JSON.stringify(pkg);\n\treturn {\n\t\tpkg: stringifiedPkg,\n\t\tsummaryFormatVersion: 2,\n\t\tisRootDataStore,\n\t};\n}\nexport function createAttributesBlob(\n\tpkg: readonly string[],\n\tisRootDataStore: boolean,\n): ITreeEntry {\n\tconst attributes = createAttributes(pkg, isRootDataStore);\n\treturn new BlobTreeEntry(dataStoreAttributesBlobName, JSON.stringify(attributes));\n}\n\n/**\n * @internal\n */\nexport interface ISnapshotDetails {\n\tpkg: readonly string[];\n\tisRootDataStore: boolean;\n\tsnapshot?: ISnapshotTree;\n\tsequenceNumber?: number;\n}\n\n/**\n * This is interface that every context should implement.\n * This interface is used for context's parent - ChannelCollection.\n * It should not be exposed to any other users of context.\n * @internal\n */\nexport interface IFluidDataStoreContextInternal extends IFluidDataStoreContext {\n\tgetAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;\n\n\tgetAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;\n\n\tgetInitialSnapshotDetails(): Promise<ISnapshotDetails>;\n\n\trealize(): Promise<IFluidDataStoreChannel>;\n\n\tisRoot(): Promise<boolean>;\n}\n\n/**\n * Properties necessary for creating a FluidDataStoreContext\n * @internal\n */\nexport interface IFluidDataStoreContextProps {\n\treadonly id: string;\n\treadonly parentContext: IFluidParentContext;\n\treadonly storage: IDocumentStorageService;\n\treadonly scope: FluidObject;\n\treadonly createSummarizerNodeFn: CreateChildSummarizerNodeFn;\n\treadonly pkg?: Readonly<string[]>;\n\treadonly loadingGroupId?: string;\n}\n\n/**\n * Properties necessary for creating a local FluidDataStoreContext\n * @internal\n */\nexport interface ILocalFluidDataStoreContextProps extends IFluidDataStoreContextProps {\n\treadonly pkg: Readonly<string[]> | undefined;\n\treadonly snapshotTree: ISnapshotTree | undefined;\n\treadonly makeLocallyVisibleFn: () => void;\n}\n\n/**\n * Properties necessary for creating a local FluidDataStoreContext\n * @internal\n */\nexport interface ILocalDetachedFluidDataStoreContextProps\n\textends ILocalFluidDataStoreContextProps {\n\treadonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;\n}\n\n/**\n * Properties necessary for creating a remote FluidDataStoreContext\n * @internal\n */\nexport interface IRemoteFluidDataStoreContextProps extends IFluidDataStoreContextProps {\n\treadonly snapshot: ISnapshotTree | ISnapshot | undefined;\n}\n\n// back-compat: To be removed in the future.\n// Added in \"2.0.0-rc.2.0.0\" timeframe (to support older builds).\n/**\n * @internal\n */\nexport interface IFluidDataStoreContextEvents extends IEvent {\n\t(event: \"attaching\" | \"attached\", listener: () => void);\n}\n\n/**\n * Represents the context for the store. This context is passed to the store runtime.\n * @internal\n */\nexport abstract class FluidDataStoreContext\n\textends TypedEventEmitter<IFluidDataStoreContextEvents>\n\timplements IFluidDataStoreContextInternal, IFluidParentContext, IDisposable\n{\n\tpublic get packagePath(): readonly string[] {\n\t\tassert(this.pkg !== undefined, 0x139 /* \"Undefined package path\" */);\n\t\treturn this.pkg;\n\t}\n\n\tpublic get options(): Record<string | number, unknown> {\n\t\treturn this.parentContext.options;\n\t}\n\n\tpublic get clientId(): string | undefined {\n\t\treturn this.parentContext.clientId;\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.parentContext.clientDetails;\n\t}\n\n\tpublic get baseLogger(): ITelemetryBaseLogger {\n\t\treturn this.parentContext.baseLogger;\n\t}\n\n\tpublic get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {\n\t\treturn this.parentContext.deltaManager;\n\t}\n\n\tpublic get connected(): boolean {\n\t\treturn this.parentContext.connected;\n\t}\n\n\tpublic get IFluidHandleContext(): IFluidHandleContext {\n\t\treturn this.parentContext.IFluidHandleContext;\n\t}\n\n\tpublic get containerRuntime(): IContainerRuntimeBase {\n\t\treturn this._containerRuntime;\n\t}\n\tpublic get isLoaded(): boolean {\n\t\treturn this.loaded;\n\t}\n\n\tpublic get baseSnapshot(): ISnapshotTree | undefined {\n\t\treturn this._baseSnapshot;\n\t}\n\n\tpublic get idCompressor(): IIdCompressor | undefined {\n\t\treturn this.parentContext.idCompressor;\n\t}\n\n\tprivate _disposed = false;\n\tpublic get disposed(): boolean {\n\t\treturn this._disposed;\n\t}\n\n\t/**\n\t * A Tombstoned object has been unreferenced long enough that GC knows it won't be referenced again.\n\t * Tombstoned objects are eventually deleted by GC.\n\t */\n\tprivate _tombstoned = false;\n\tpublic get tombstoned(): boolean {\n\t\treturn this._tombstoned;\n\t}\n\t/**\n\t * If true, throw an error when a tombstone data store is used.\n\t * @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.\n\t */\n\tpublic readonly gcThrowOnTombstoneUsage: boolean = false;\n\t/**\n\t * @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.\n\t */\n\tpublic readonly gcTombstoneEnforcementAllowed: boolean = false;\n\n\t/**\n\t * If true, this means that this data store context and its children have been removed from the runtime\n\t */\n\tprotected deleted: boolean = false;\n\n\tpublic get attachState(): AttachState {\n\t\treturn this._attachState;\n\t}\n\n\tpublic get IFluidDataStoreRegistry(): IFluidDataStoreRegistry | undefined {\n\t\treturn this.registry;\n\t}\n\n\tprivate baseSnapshotSequenceNumber: number | undefined;\n\n\t/**\n\t * A datastore is considered as root if it\n\t * 1. is root in memory - see isInMemoryRoot\n\t * 2. is root as part of the base snapshot that the datastore loaded from\n\t * @returns whether a datastore is root\n\t */\n\tpublic async isRoot(aliasedDataStores?: Set<string>): Promise<boolean> {\n\t\tif (this.isInMemoryRoot()) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// This if is a performance optimization.\n\t\t// We know that if the base snapshot is omitted, then the isRootDataStore flag is not set.\n\t\t// That means we can skip the expensive call to getInitialSnapshotDetails for virtualized datastores,\n\t\t// and get the information from the alias map directly.\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n\t\tif (aliasedDataStores !== undefined && (this.baseSnapshot as any)?.omitted === true) {\n\t\t\treturn aliasedDataStores.has(this.id);\n\t\t}\n\n\t\tconst snapshotDetails = await this.getInitialSnapshotDetails();\n\t\treturn snapshotDetails.isRootDataStore;\n\t}\n\n\t/**\n\t * There are 3 states where isInMemoryRoot needs to be true\n\t * 1. when a datastore becomes aliased. This can happen for both remote and local datastores\n\t * 2. when a datastore is created locally as root\n\t * 3. when a datastore is created locally as root and is rehydrated\n\t * @returns whether a datastore is root in memory\n\t */\n\tprotected isInMemoryRoot(): boolean {\n\t\treturn this._isInMemoryRoot;\n\t}\n\n\t/**\n\t * Returns the count of pending messages that are stored until the data store is realized.\n\t */\n\tpublic get pendingCount(): number {\n\t\treturn this.pendingMessagesState?.pendingCount ?? 0;\n\t}\n\n\tprotected registry: IFluidDataStoreRegistry | undefined;\n\n\tprotected detachedRuntimeCreation = false;\n\tprotected channel: IFluidDataStoreChannel | undefined;\n\tprivate loaded = false;\n\t/**\n\t * Tracks the messages for this data store that are sent while it's not loaded\n\t */\n\tprivate pendingMessagesState: IPendingMessagesState | undefined = {\n\t\tmessageCollections: [],\n\t\tpendingCount: 0,\n\t};\n\tprotected channelP: Promise<IFluidDataStoreChannel> | undefined;\n\tprotected _baseSnapshot: ISnapshotTree | undefined;\n\tprotected _attachState: AttachState;\n\tprivate _isInMemoryRoot: boolean = false;\n\tprotected readonly summarizerNode: ISummarizerNodeWithGC;\n\tprotected readonly mc: MonitoringContext;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\t/**\n\t * If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.\n\t * So, adding a count of how many telemetry events are logged per data store context. This can be\n\t * controlled via feature flags.\n\t */\n\tprivate localChangesTelemetryCount: number;\n\n\tpublic readonly id: string;\n\tprivate readonly _containerRuntime: IContainerRuntimeBase;\n\tprivate readonly parentContext: IFluidParentContext;\n\tpublic readonly storage: IDocumentStorageService;\n\tpublic readonly scope: FluidObject;\n\t// Represents the group to which the data store belongs too.\n\tpublic readonly loadingGroupId: string | undefined;\n\tprotected pkg?: readonly string[];\n\n\tconstructor(\n\t\tprops: IFluidDataStoreContextProps,\n\t\tprivate readonly existing: boolean,\n\t\tpublic readonly isLocalDataStore: boolean,\n\t\tprivate readonly makeLocallyVisibleFn: () => void,\n\t) {\n\t\tsuper();\n\n\t\tthis._containerRuntime = props.parentContext.containerRuntime;\n\t\tthis.parentContext = props.parentContext;\n\t\tthis.id = props.id;\n\t\tthis.storage = props.storage;\n\t\tthis.scope = props.scope;\n\t\tthis.pkg = props.pkg;\n\t\tthis.loadingGroupId = props.loadingGroupId;\n\n\t\t// URIs use slashes as delimiters. Handles use URIs.\n\t\t// Thus having slashes in types almost guarantees trouble down the road!\n\t\tassert(!this.id.includes(\"/\"), 0x13a /* Data store ID contains slash */);\n\n\t\tthis._attachState =\n\t\t\tthis.parentContext.attachState !== AttachState.Detached && this.existing\n\t\t\t\t? this.parentContext.attachState\n\t\t\t\t: AttachState.Detached;\n\n\t\tthis.summarizerNode = props.createSummarizerNodeFn(\n\t\t\tasync (fullTree, trackState, telemetryContext) =>\n\t\t\t\tthis.summarizeInternal(fullTree, trackState, telemetryContext),\n\t\t\tasync (fullGC?: boolean) => this.getGCDataInternal(fullGC),\n\t\t);\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: this.baseLogger,\n\t\t\tnamespace: \"FluidDataStoreContext\",\n\t\t\tproperties: {\n\t\t\t\tall: tagCodeArtifacts({\n\t\t\t\t\tfluidDataStoreId: this.id,\n\t\t\t\t\t// The package name is a getter because `this.pkg` may not be initialized during construction.\n\t\t\t\t\t// For data stores loaded from summary, it is initialized during data store realization.\n\t\t\t\t\tfullPackageName: () => this.pkg?.join(\"/\"),\n\t\t\t\t}),\n\t\t\t},\n\t\t});\n\t\tthis.thresholdOpsCounter = new ThresholdCounter(\n\t\t\tFluidDataStoreContext.pendingOpsCountThreshold,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// By default, a data store can log maximum 10 local changes telemetry in summarizer.\n\t\tthis.localChangesTelemetryCount =\n\t\t\tthis.mc.config.getNumber(\"Fluid.Telemetry.LocalChangesTelemetryCount\") ?? 10;\n\t}\n\n\tpublic dispose(): void {\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis._disposed = true;\n\n\t\t// Dispose any pending runtime after it gets fulfilled\n\t\t// Errors are logged where this.channelP is consumed/generated (realizeCore(), bindRuntime())\n\t\tif (this.channelP) {\n\t\t\tthis.channelP\n\t\t\t\t.then((runtime) => {\n\t\t\t\t\truntime.dispose();\n\t\t\t\t})\n\t\t\t\t.catch((error) => {});\n\t\t}\n\t}\n\n\t/**\n\t * When delete is called, that means that the data store is permanently removed from the runtime, and will not show up in future summaries\n\t * This function is called to prevent ops from being generated from this data store once it has been deleted. Furthermore, this data store\n\t * should not receive any ops/signals.\n\t */\n\tpublic delete(): void {\n\t\tthis.deleted = true;\n\t}\n\n\tpublic setTombstone(tombstone: boolean): void {\n\t\tif (this.tombstoned === tombstone) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._tombstoned = tombstone;\n\t}\n\n\tpublic abstract setAttachState(\n\t\tattachState: AttachState.Attaching | AttachState.Attached,\n\t): void;\n\n\tprivate rejectDeferredRealize(\n\t\treason: string,\n\t\tfailedPkgPath?: string,\n\t\tfullPackageName?: readonly string[],\n\t): never {\n\t\tthrow new LoggingError(\n\t\t\treason,\n\t\t\ttagCodeArtifacts({\n\t\t\t\tfailedPkgPath,\n\t\t\t\tpackagePath: fullPackageName?.join(\"/\"),\n\t\t\t}),\n\t\t);\n\t}\n\n\tpublic async realize(): Promise<IFluidDataStoreChannel> {\n\t\tassert(\n\t\t\t!this.detachedRuntimeCreation,\n\t\t\t0x13d /* \"Detached runtime creation on realize()\" */,\n\t\t);\n\t\tif (!this.channelP) {\n\t\t\tthis.channelP = this.realizeCore(this.existing).catch((error) => {\n\t\t\t\tconst errorWrapped = DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\terror,\n\t\t\t\t\t\"realizeFluidDataStoreContext\",\n\t\t\t\t);\n\t\t\t\terrorWrapped.addTelemetryProperties(\n\t\t\t\t\ttagCodeArtifacts({\n\t\t\t\t\t\tfullPackageName: this.pkg?.join(\"/\"),\n\t\t\t\t\t\tfluidDataStoreId: this.id,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"RealizeError\" }, errorWrapped);\n\t\t\t\tthrow errorWrapped;\n\t\t\t});\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tprotected async factoryFromPackagePath(): Promise<IFluidDataStoreFactory> {\n\t\tconst packages = this.pkg;\n\t\tif (packages === undefined) {\n\t\t\tthis.rejectDeferredRealize(\"packages is undefined\");\n\t\t}\n\n\t\tlet entry: FluidDataStoreRegistryEntry | undefined;\n\t\tlet registry: IFluidDataStoreRegistry | undefined =\n\t\t\tthis.parentContext.IFluidDataStoreRegistry;\n\t\tlet lastPkg: string | undefined;\n\t\tfor (const pkg of packages) {\n\t\t\tif (!registry) {\n\t\t\t\tthis.rejectDeferredRealize(\"No registry for package\", lastPkg, packages);\n\t\t\t}\n\t\t\tlastPkg = pkg;\n\t\t\tentry = registry.getSync?.(pkg) ?? (await registry.get(pkg));\n\t\t\tif (!entry) {\n\t\t\t\tthis.rejectDeferredRealize(\n\t\t\t\t\t\"Registry does not contain entry for the package\",\n\t\t\t\t\tpkg,\n\t\t\t\t\tpackages,\n\t\t\t\t);\n\t\t\t}\n\t\t\tregistry = entry.IFluidDataStoreRegistry;\n\t\t}\n\t\tconst factory = entry?.IFluidDataStoreFactory;\n\t\tif (factory === undefined) {\n\t\t\tthis.rejectDeferredRealize(\"Can't find factory for package\", lastPkg, packages);\n\t\t}\n\n\t\tassert(this.registry === undefined, 0x157 /* \"datastore registry already attached\" */);\n\t\tthis.registry = registry;\n\n\t\treturn factory;\n\t}\n\n\tcreateChildDataStore<T extends IFluidDataStoreFactory>(\n\t\tchildFactory: T,\n\t): ReturnType<Exclude<T[\"createDataStore\"], undefined>> {\n\t\tconst maybe = this.registry?.getSync?.(childFactory.type);\n\n\t\tconst isUndefined = maybe === undefined;\n\t\tconst diffInstance = maybe?.IFluidDataStoreFactory !== childFactory;\n\n\t\tif (isUndefined || diffInstance) {\n\t\t\tthrow new UsageError(\n\t\t\t\t\"The provided factory instance must be synchronously available as a child of this datastore\",\n\t\t\t\t{ isUndefined, diffInstance },\n\t\t\t);\n\t\t}\n\t\tif (childFactory?.createDataStore === undefined) {\n\t\t\tthrow new UsageError(\"createDataStore must exist on the provided factory\", {\n\t\t\t\tnoCreateDataStore: true,\n\t\t\t});\n\t\t}\n\n\t\tconst context = this._containerRuntime.createDetachedDataStore([\n\t\t\t...this.packagePath,\n\t\t\tchildFactory.type,\n\t\t]);\n\t\tassert(\n\t\t\tcontext instanceof LocalDetachedFluidDataStoreContext,\n\t\t\t0xa89 /* must be a LocalDetachedFluidDataStoreContext */,\n\t\t);\n\n\t\tconst created = childFactory.createDataStore(context) as ReturnType<\n\t\t\tExclude<T[\"createDataStore\"], undefined>\n\t\t>;\n\t\tcontext.unsafe_AttachRuntimeSync(created.runtime);\n\t\treturn created;\n\t}\n\n\tprivate async realizeCore(existing: boolean): Promise<IFluidDataStoreChannel> {\n\t\tconst details = await this.getInitialSnapshotDetails();\n\t\t// Base snapshot is the baseline where pending ops are applied to.\n\t\t// It is important that this be in sync with the pending ops, and also\n\t\t// that it is set here, before bindRuntime is called.\n\t\tthis._baseSnapshot = details.snapshot;\n\t\tthis.baseSnapshotSequenceNumber = details.sequenceNumber;\n\t\tassert(this.pkg === details.pkg, 0x13e /* \"Unexpected package path\" */);\n\n\t\tconst factory = await this.factoryFromPackagePath();\n\n\t\tconst channel = await factory.instantiateDataStore(this, existing);\n\t\tassert(channel !== undefined, 0x140 /* \"undefined channel on datastore context\" */);\n\t\tawait this.bindRuntime(channel, existing);\n\t\t// This data store may have been disposed before the channel is created during realization. If so,\n\t\t// dispose the channel now.\n\t\tif (this.disposed) {\n\t\t\tchannel.dispose();\n\t\t}\n\n\t\treturn channel;\n\t}\n\n\t/**\n\t * Notifies this object about changes in the connection state.\n\t * @param value - New connection state.\n\t * @param clientId - ID of the client. Its old ID when in disconnected state and\n\t * its new client ID when we are connecting or connected.\n\t */\n\tpublic setConnectionState(connected: boolean, clientId?: string): void {\n\t\t// ConnectionState should not fail in tombstone mode as this is internally run\n\t\tthis.verifyNotClosed(\"setConnectionState\", false /* checkTombstone */);\n\n\t\t// Connection events are ignored if the store is not yet loaded\n\t\tif (!this.loaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tassert(this.connected === connected, 0x141 /* \"Unexpected connected state\" */);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tthis.channel!.setConnectionState(connected, clientId);\n\t}\n\n\t/**\n\t * back-compat ADO 21575: This is temporary and will be removed once the compat requirement across Runtime and\n\t * Datastore boundary is satisfied.\n\t * Process the messages to maintain backwards compatibility. The `processMessages` function is added to\n\t * IFluidDataStoreChannel in 2.5.0. For channels before that, call `process` for each message.\n\t */\n\tprivate processMessagesCompat(\n\t\tchannel: IFluidDataStoreChannel,\n\t\tmessageCollection: IRuntimeMessageCollection,\n\t): void {\n\t\tif (channel.processMessages === undefined) {\n\t\t\tconst { envelope, messagesContent, local } = messageCollection;\n\t\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\t\tchannel.process(\n\t\t\t\t\t{ ...envelope, contents, clientSequenceNumber },\n\t\t\t\t\tlocal,\n\t\t\t\t\tlocalOpMetadata,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tchannel.processMessages(messageCollection);\n\t\t}\n\t}\n\n\t/**\n\t * Process messages for this data store. The messages here are contiguous messages for this data store in a batch.\n\t * @param messageCollection - The collection of messages to process.\n\t */\n\tpublic processMessages(messageCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messageCollection;\n\t\tconst safeTelemetryProps = extractSafePropertiesFromMessage(envelope);\n\t\t// Tombstone error is logged in garbage collector. So, set \"checkTombstone\" to false when calling\n\t\t// \"verifyNotClosed\" which logs tombstone errors.\n\t\tthis.verifyNotClosed(\"process\", false /* checkTombstone */, safeTelemetryProps);\n\n\t\tthis.summarizerNode.recordChange(envelope as ISequencedDocumentMessage);\n\n\t\tif (this.loaded) {\n\t\t\tassert(this.channel !== undefined, 0xa68 /* Channel is not loaded */);\n\t\t\tthis.processMessagesCompat(this.channel, messageCollection);\n\t\t} else {\n\t\t\tassert(!local, 0x142 /* \"local store channel is not loaded\" */);\n\t\t\tassert(\n\t\t\t\tthis.pendingMessagesState !== undefined,\n\t\t\t\t0xa69 /* pending messages queue is undefined */,\n\t\t\t);\n\t\t\tthis.pendingMessagesState.messageCollections.push({\n\t\t\t\t...messageCollection,\n\t\t\t\tmessagesContent: [...messagesContent],\n\t\t\t});\n\t\t\tthis.pendingMessagesState.pendingCount += messagesContent.length;\n\t\t\tthis.thresholdOpsCounter.sendIfMultiple(\n\t\t\t\t\"StorePendingOps\",\n\t\t\t\tthis.pendingMessagesState.pendingCount,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic processSignal(message: IInboundSignalMessage, local: boolean): void {\n\t\tthis.verifyNotClosed(\"processSignal\");\n\n\t\t// Signals are ignored if the store is not yet loaded\n\t\tif (!this.loaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.channel?.processSignal(message, local);\n\t}\n\n\tpublic getQuorum(): IQuorumClients {\n\t\treturn this.parentContext.getQuorum();\n\t}\n\n\tpublic getAudience(): IAudience {\n\t\treturn this.parentContext.getAudience();\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\tawait this.realize();\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst summarizeResult = await this.channel!.summarize(\n\t\t\tfullTree,\n\t\t\ttrackState,\n\t\t\ttelemetryContext,\n\t\t);\n\n\t\t// Wrap dds summaries in .channels subtree.\n\t\twrapSummaryInChannelsTree(summarizeResult);\n\t\tconst pathPartsForChildren = [channelsTreeName];\n\n\t\t// Add data store's attributes to the summary.\n\t\tconst { pkg } = await this.getInitialSnapshotDetails();\n\t\tconst isRoot = await this.isRoot();\n\t\tconst attributes = createAttributes(pkg, isRoot);\n\t\taddBlobToSummary(summarizeResult, dataStoreAttributesBlobName, JSON.stringify(attributes));\n\n\t\t// If we are not referenced, mark the summary tree as unreferenced. Also, update unreferenced blob\n\t\t// size in the summary stats with the blobs size of this data store.\n\t\tif (!this.summarizerNode.isReferenced()) {\n\t\t\tsummarizeResult.summary.unreferenced = true;\n\t\t\tsummarizeResult.stats.unreferencedBlobSize = summarizeResult.stats.totalBlobSize;\n\t\t}\n\n\t\t// Add loadingGroupId to the summary\n\t\tif (this.loadingGroupId !== undefined) {\n\t\t\tsummarizeResult.summary.groupId = this.loadingGroupId;\n\t\t}\n\n\t\treturn {\n\t\t\t...summarizeResult,\n\t\t\tid: this.id,\n\t\t\tpathPartsForChildren,\n\t\t};\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this data store\n\t * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the\n\t * document.\n\t * If there is no new data in this data store 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 data used for garbage collection. This is called when there is new data since last summary. It\n\t * realizes the data store and calls into each channel context 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\tawait this.realize();\n\t\tassert(\n\t\t\tthis.channel !== undefined,\n\t\t\t0x143 /* \"Channel should not be undefined when running GC\" */,\n\t\t);\n\n\t\treturn this.channel.getGCData(fullGC);\n\t}\n\n\t/**\n\t * After GC has run, called to notify the data store of routes used in it. These are used for the following:\n\t * 1. To identify if this data store is being referenced in the document or not.\n\t * 2. To determine if it needs to re-summarize in case used routes changed since last summary.\n\t * 3. To notify child contexts of their used routes. This is done immediately if the data store is loaded.\n\t * Else, it is done by the data stores's summarizer node when child summarizer nodes are created.\n\t *\n\t * @param usedRoutes - The routes that are used in this data store.\n\t */\n\tpublic updateUsedRoutes(usedRoutes: string[]): void {\n\t\t// Update the used routes in this data store's summarizer node.\n\t\tthis.summarizerNode.updateUsedRoutes(usedRoutes);\n\n\t\t// If the channel doesn't exist yet (data store is not realized), the summarizer node will update it\n\t\t// when it creates child nodes.\n\t\tif (!this.channel) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove the route to this data store, if it exists.\n\t\tconst usedChannelRoutes = usedRoutes.filter((id: string) => {\n\t\t\treturn id !== \"/\" && id !== \"\";\n\t\t});\n\t\tthis.channel.updateUsedRoutes(usedChannelRoutes);\n\t}\n\n\t/**\n\t * Called when a new outbound reference is added to another node. This is used by garbage collection to identify\n\t * all references added in the system.\n\t *\n\t * @param fromPath - The absolute path of the node that added the reference.\n\t * @param toPath - The absolute path of the outbound node that is referenced.\n\t * @param messageTimestampMs - The timestamp of the message that added the reference.\n\t */\n\tpublic addedGCOutboundRoute(\n\t\tfromPath: string,\n\t\ttoPath: string,\n\t\tmessageTimestampMs?: number,\n\t): void {\n\t\tthis.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);\n\t}\n\n\t// eslint-disable-next-line jsdoc/require-description\n\t/**\n\t * @deprecated 0.18.Should call request on the runtime directly\n\t */\n\tpublic async request(request: IRequest): Promise<IResponse> {\n\t\tconst runtime = await this.realize();\n\t\treturn runtime.request(request);\n\t}\n\n\tpublic submitMessage(type: string, content: unknown, localOpMetadata: unknown): void {\n\t\tthis.verifyNotClosed(\"submitMessage\");\n\t\tassert(!!this.channel, 0x146 /* \"Channel must exist when submitting message\" */);\n\t\t// Summarizer clients should not submit messages.\n\t\tthis.identifyLocalChangeInSummarizer(\"DataStoreMessageSubmittedInSummarizer\", type);\n\n\t\tthis.parentContext.submitMessage(type, content, localOpMetadata);\n\t}\n\n\t/**\n\t * This is called from a SharedSummaryBlock that does not generate ops but only wants to be part of the summary.\n\t * It indicates that there is data in the object that needs to be summarized.\n\t * We will update the latestSequenceNumber of the summary tracker of this\n\t * store and of the object's channel.\n\t *\n\t * @param address - The address of the channel that is dirty.\n\t *\n\t */\n\tpublic setChannelDirty(address: string): void {\n\t\tthis.verifyNotClosed(\"setChannelDirty\");\n\n\t\t// Get the latest sequence number.\n\t\tconst latestSequenceNumber = this.deltaManager.lastSequenceNumber;\n\n\t\tthis.summarizerNode.invalidate(latestSequenceNumber);\n\n\t\tconst channelSummarizerNode = this.summarizerNode.getChild(address);\n\n\t\tif (channelSummarizerNode) {\n\t\t\tchannelSummarizerNode.invalidate(latestSequenceNumber); // TODO: lazy load problem?\n\t\t}\n\t}\n\n\t/**\n\t * Submits the signal to be sent to other clients.\n\t * @param type - Type of the signal.\n\t * @param content - Content of the signal. Should be a JSON serializable object or primitive.\n\t * @param targetClientId - When specified, the signal is only sent to the provided client id.\n\t */\n\tpublic submitSignal(type: string, content: unknown, targetClientId?: string): void {\n\t\tthis.verifyNotClosed(\"submitSignal\");\n\n\t\tassert(!!this.channel, 0x147 /* \"Channel must exist on submitting signal\" */);\n\t\treturn this.parentContext.submitSignal(type, content, targetClientId);\n\t}\n\n\t/**\n\t * This is called by the data store channel when it becomes locally visible indicating that it is ready to become\n\t * globally visible now.\n\t */\n\tpublic makeLocallyVisible(): void {\n\t\tassert(this.channel !== undefined, 0x2cf /* \"undefined channel on datastore context\" */);\n\t\tthis.makeLocallyVisibleFn();\n\t}\n\n\tprotected processPendingOps(channel: IFluidDataStoreChannel): void {\n\t\tconst baseSequenceNumber = this.baseSnapshotSequenceNumber ?? -1;\n\n\t\tassert(\n\t\t\tthis.pendingMessagesState !== undefined,\n\t\t\t0xa6a /* pending messages queue is undefined */,\n\t\t);\n\t\tfor (const messageCollection of this.pendingMessagesState.messageCollections) {\n\t\t\t// Only process ops whose seq number is greater than snapshot sequence number from which it loaded.\n\t\t\tif (messageCollection.envelope.sequenceNumber > baseSequenceNumber) {\n\t\t\t\tthis.processMessagesCompat(channel, messageCollection);\n\t\t\t}\n\t\t}\n\n\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pendingMessagesState.pendingCount);\n\t\tthis.pendingMessagesState = undefined;\n\t}\n\n\tprotected completeBindingRuntime(channel: IFluidDataStoreChannel): void {\n\t\t// And now mark the runtime active\n\t\tthis.loaded = true;\n\t\tthis.channel = channel;\n\n\t\t// Channel does not know when it's \"live\" (as in - starts to receive events in the system)\n\t\t// It may read current state of the system when channel was created, but it was not getting any updates\n\t\t// through creation process and could have missed events. So update it on current state.\n\t\t// Once this.loaded is set (above), it will stat receiving events.\n\t\tchannel.setConnectionState(this.connected, this.clientId);\n\n\t\t// Freeze the package path to ensure that someone doesn't modify it when it is\n\t\t// returned in packagePath().\n\t\tObject.freeze(this.pkg);\n\t}\n\n\tprotected async bindRuntime(\n\t\tchannel: IFluidDataStoreChannel,\n\t\texisting: boolean,\n\t): Promise<void> {\n\t\tif (this.channel) {\n\t\t\tthrow new Error(\"Runtime already bound\");\n\t\t}\n\n\t\tassert(\n\t\t\t!this.detachedRuntimeCreation,\n\t\t\t0x148 /* \"Detached runtime creation on runtime bind\" */,\n\t\t);\n\t\tassert(this.pkg !== undefined, 0x14a /* \"Undefined package path\" */);\n\n\t\tif (!existing) {\n\t\t\t// Execute data store's entry point to make sure that for a local (aka detached from container) data store, the\n\t\t\t// entryPoint initialization function is called before the data store gets attached and potentially connected to\n\t\t\t// the delta stream, so it gets a chance to do things while the data store is still \"purely local\".\n\t\t\t// This preserves the behavior from before we introduced entryPoints, where the instantiateDataStore method\n\t\t\t// of data store factories tends to construct the data object (at least kick off an async method that returns\n\t\t\t// it); that code moved to the entryPoint initialization function, so we want to ensure it still executes\n\t\t\t// before the data store is attached.\n\t\t\tawait channel.entryPoint.get();\n\t\t}\n\n\t\tthis.processPendingOps(channel);\n\t\tthis.completeBindingRuntime(channel);\n\t}\n\n\tpublic async getAbsoluteUrl(relativeUrl: string): Promise<string | undefined> {\n\t\tif (this.attachState !== AttachState.Attached) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.parentContext.getAbsoluteUrl(relativeUrl);\n\t}\n\n\t/**\n\t * Get the summary required when attaching this context's DataStore.\n\t * Used for both Container Attach and DataStore Attach.\n\t */\n\tpublic abstract getAttachSummary(\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * Get the GC Data for the initial state being attached so remote clients can learn of this DataStore's\n\t * outbound routes.\n\t */\n\tpublic abstract getAttachGCData(\n\t\ttelemetryContext?: ITelemetryContext,\n\t): IGarbageCollectionData;\n\n\tpublic abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;\n\n\t// eslint-disable-next-line jsdoc/require-description\n\t/**\n\t * @deprecated Sets the datastore as root, for aliasing purposes: #7948\n\t * This method should not be used outside of the aliasing context.\n\t * It will be removed, as the source of truth for this flag will be the aliasing blob.\n\t */\n\tpublic setInMemoryRoot(): void {\n\t\tthis._isInMemoryRoot = true;\n\t}\n\n\t// eslint-disable-next-line jsdoc/require-description\n\t/**\n\t * @deprecated The functionality to get base GC details has been moved to summarizer node.\n\t */\n\tpublic async getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase> {\n\t\treturn {};\n\t}\n\n\tpublic reSubmit(type: string, contents: unknown, localOpMetadata: unknown): void {\n\t\tassert(!!this.channel, 0x14b /* \"Channel must exist when resubmitting ops\" */);\n\t\tthis.channel.reSubmit(type, contents, localOpMetadata);\n\t}\n\n\tpublic rollback(type: string, contents: unknown, localOpMetadata: unknown): void {\n\t\tif (!this.channel) {\n\t\t\tthrow new Error(\"Channel must exist when rolling back ops\");\n\t\t}\n\t\tif (!this.channel.rollback) {\n\t\t\tthrow new Error(\"Channel doesn't support rollback\");\n\t\t}\n\t\tthis.channel.rollback(type, contents, localOpMetadata);\n\t}\n\n\tpublic async applyStashedOp(contents: unknown): Promise<unknown> {\n\t\tif (!this.channel) {\n\t\t\tawait this.realize();\n\t\t}\n\t\tassert(!!this.channel, 0x14c /* \"Channel must exist when rebasing ops\" */);\n\t\treturn this.channel.applyStashedOp(contents);\n\t}\n\n\tprivate verifyNotClosed(\n\t\tcallSite: string,\n\t\tcheckTombstone = true,\n\t\tsafeTelemetryProps: ITelemetryBaseProperties = {},\n\t): void {\n\t\tif (this.deleted) {\n\t\t\tconst messageString = `Context is deleted! Call site [${callSite}]`;\n\t\t\tconst error = DataProcessingError.create(\n\t\t\t\tmessageString,\n\t\t\t\tcallSite,\n\t\t\t\tundefined /* sequencedMessage */,\n\t\t\t\tsafeTelemetryProps,\n\t\t\t);\n\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"GC_Deleted_DataStore_Changed\",\n\t\t\t\t\tcallSite,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (this._disposed) {\n\t\t\tthrow new Error(`Context is closed! Call site [${callSite}]`);\n\t\t}\n\n\t\tif (checkTombstone && this.tombstoned) {\n\t\t\tconst messageString = `Context is tombstoned! Call site [${callSite}]`;\n\t\t\tconst error = DataProcessingError.create(\n\t\t\t\tmessageString,\n\t\t\t\tcallSite,\n\t\t\t\tundefined /* sequencedMessage */,\n\t\t\t\tsafeTelemetryProps,\n\t\t\t);\n\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"GC_Tombstone_DataStore_Changed\",\n\t\t\t\t\tcategory: \"generic\",\n\t\t\t\t\tcallSite,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Summarizer client should not have local changes. These changes can become part of the summary and can break\n\t * eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas\n\t * other clients that are up-to-date till seq# 100 may not have them yet.\n\t */\n\tprotected identifyLocalChangeInSummarizer(eventName: string, type?: string): void {\n\t\tif (\n\t\t\tthis.clientDetails.type !== summarizerClientType ||\n\t\t\tthis.localChangesTelemetryCount <= 0\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Log a telemetry if there are local changes in the summarizer. This will give us data on how often\n\t\t// this is happening and which data stores do this. The eventual goal is to disallow local changes\n\t\t// in the summarizer and the data will help us plan this.\n\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\teventName,\n\t\t\ttype,\n\t\t\tisSummaryInProgress: this.summarizerNode.isSummaryInProgress?.(),\n\t\t\tstack: generateStack(30),\n\t\t});\n\t\tthis.localChangesTelemetryCount--;\n\t}\n\n\tpublic getCreateChildSummarizerNodeFn(\n\t\tid: string,\n\t\tcreateParam: CreateChildSummarizerNodeParam,\n\t) {\n\t\treturn (\n\t\t\tsummarizeInternal: SummarizeInternalFn,\n\t\t\tgetGCDataFn: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\t\t): ISummarizerNodeWithGC =>\n\t\t\tthis.summarizerNode.createChild(\n\t\t\t\tsummarizeInternal,\n\t\t\t\tid,\n\t\t\t\tcreateParam,\n\t\t\t\tundefined /* config */,\n\t\t\t\tgetGCDataFn,\n\t\t\t);\n\t}\n\n\tpublic deleteChildSummarizerNode(id: string): void {\n\t\tthis.summarizerNode.deleteChild(id);\n\t}\n\n\tpublic async uploadBlob(\n\t\tblob: ArrayBufferLike,\n\t\tsignal?: AbortSignal,\n\t): Promise<IFluidHandleInternal<ArrayBufferLike>> {\n\t\treturn this.parentContext.uploadBlob(blob, signal);\n\t}\n}\n\n/**\n * @internal\n */\nexport class RemoteFluidDataStoreContext extends FluidDataStoreContext {\n\t// Tells whether we need to fetch the snapshot before use. This is to support Data Virtualization.\n\tprivate snapshotFetchRequired: boolean | undefined;\n\tprivate readonly runtime: IContainerRuntimeBase;\n\tprivate readonly blobContents: Map<string, ArrayBuffer> | undefined;\n\tprivate readonly isSnapshotInISnapshotFormat: boolean | undefined;\n\n\tconstructor(props: IRemoteFluidDataStoreContextProps) {\n\t\tsuper(props, true /* existing */, false /* isLocalDataStore */, () => {\n\t\t\tthrow new Error(\"Already attached\");\n\t\t});\n\n\t\tthis.runtime = props.parentContext.containerRuntime;\n\t\tif (isInstanceOfISnapshot(props.snapshot)) {\n\t\t\tthis.blobContents = props.snapshot.blobContents;\n\t\t\tthis._baseSnapshot = props.snapshot.snapshotTree;\n\t\t\tthis.isSnapshotInISnapshotFormat = true;\n\t\t} else {\n\t\t\tthis._baseSnapshot = props.snapshot;\n\t\t\tthis.isSnapshotInISnapshotFormat = false;\n\t\t}\n\t}\n\n\t/**\n\t * This API should not be called for RemoteFluidDataStoreContext. But here is one scenario where it's not the case:\n\t * The scenario (hit by stashedOps.spec.ts, \"resends attach op\" UT is the following (as far as I understand):\n\t *\n\t * 1. data store is being attached in attached container\n\t *\n\t * 2. container state is serialized (stashed ops feature)\n\t *\n\t * 3. new container instance is rehydrated (from stashed ops) -\n\t * As result, we create RemoteFluidDataStoreContext for this data store that is actually in \"attaching\" state * (as of # 2).\n\t * But its state is set to attached when loading container from stashed ops.\n\t *\n\t * 4. attach op for this data store is processed - setAttachState() is called.\n\t */\n\tpublic setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {}\n\n\t// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda\n\tprivate readonly initialSnapshotDetailsP = new LazyPromise<ISnapshotDetails>(async () => {\n\t\t// Sequence number of the snapshot.\n\t\tlet sequenceNumber: number | undefined;\n\t\t// Check whether we need to fetch the snapshot first to load. The snapshot should be in new format to see\n\t\t// whether we want to evaluate to fetch snapshot or not for loadingGroupId. Otherwise, the snapshot\n\t\t// will contain all the blobs.\n\t\tif (\n\t\t\tthis.snapshotFetchRequired === undefined &&\n\t\t\tthis._baseSnapshot?.groupId !== undefined &&\n\t\t\tthis.isSnapshotInISnapshotFormat\n\t\t) {\n\t\t\tassert(\n\t\t\t\tthis.blobContents !== undefined,\n\t\t\t\t0x97a /* Blob contents should be present to evaluate */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tthis._baseSnapshot !== undefined,\n\t\t\t\t0x97b /* snapshotTree should be present to evaluate */,\n\t\t\t);\n\t\t\tthis.snapshotFetchRequired = isSnapshotFetchRequiredForLoadingGroupId(\n\t\t\t\tthis._baseSnapshot,\n\t\t\t\tthis.blobContents,\n\t\t\t);\n\t\t}\n\t\tif (this.snapshotFetchRequired) {\n\t\t\tassert(\n\t\t\t\tthis.loadingGroupId !== undefined,\n\t\t\t\t0x8f5 /* groupId should be present to fetch snapshot */,\n\t\t\t);\n\t\t\tconst snapshot = await this.runtime.getSnapshotForLoadingGroupId(\n\t\t\t\t[this.loadingGroupId],\n\t\t\t\t[this.id],\n\t\t\t);\n\t\t\tthis._baseSnapshot = snapshot.snapshotTree;\n\t\t\tsequenceNumber = snapshot.sequenceNumber;\n\t\t\tthis.snapshotFetchRequired = false;\n\t\t}\n\t\tlet tree = this.baseSnapshot;\n\t\tlet isRootDataStore = true;\n\n\t\tif (!!tree && tree.blobs[dataStoreAttributesBlobName] !== undefined) {\n\t\t\t// Need to get through snapshot and use that to populate extraBlobs\n\t\t\t// eslint-disable-next-line import/no-deprecated\n\t\t\tconst attributes = await readAndParse<ReadFluidDataStoreAttributes>(\n\t\t\t\tthis.storage,\n\t\t\t\ttree.blobs[dataStoreAttributesBlobName],\n\t\t\t);\n\n\t\t\tlet pkgFromSnapshot: string[];\n\t\t\t// Use the snapshotFormatVersion to determine how the pkg is encoded in the snapshot.\n\t\t\t// For snapshotFormatVersion = \"0.1\" (1) or above, pkg is jsonified, otherwise it is just a string.\n\t\t\tconst formatVersion = getAttributesFormatVersion(attributes);\n\t\t\tif (formatVersion < 1) {\n\t\t\t\tpkgFromSnapshot =\n\t\t\t\t\tattributes.pkg.startsWith('[\"') && attributes.pkg.endsWith('\"]')\n\t\t\t\t\t\t? (JSON.parse(attributes.pkg) as string[])\n\t\t\t\t\t\t: [attributes.pkg];\n\t\t\t} else {\n\t\t\t\tpkgFromSnapshot = JSON.parse(attributes.pkg) as string[];\n\t\t\t}\n\t\t\tthis.pkg = pkgFromSnapshot;\n\n\t\t\t/**\n\t\t\t * If there is no isRootDataStore in the attributes blob, set it to true. This will ensure that\n\t\t\t * data stores in older documents are not garbage collected incorrectly. This may lead to additional\n\t\t\t * roots in the document but they won't break.\n\t\t\t */\n\t\t\tisRootDataStore = attributes.isRootDataStore ?? true;\n\n\t\t\tif (hasIsolatedChannels(attributes)) {\n\t\t\t\ttree = tree.trees[channelsTreeName];\n\t\t\t\tassert(\n\t\t\t\t\ttree !== undefined,\n\t\t\t\t\t0x1fe /* \"isolated channels subtree should exist in remote datastore snapshot\" */,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tassert(\n\t\t\tthis.pkg !== undefined,\n\t\t\t0x8f6 /* The datastore context package should be defined */,\n\t\t);\n\t\treturn {\n\t\t\tpkg: this.pkg,\n\t\t\tisRootDataStore,\n\t\t\tsnapshot: tree,\n\t\t\tsequenceNumber,\n\t\t};\n\t});\n\n\tpublic async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {\n\t\treturn this.initialSnapshotDetailsP;\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachSummary}\n\t */\n\tpublic getAttachSummary(): ISummaryTreeWithStats {\n\t\tthrow new Error(\"Cannot attach remote store\");\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachGCData}\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tthrow new Error(\"Cannot attach remote store\");\n\t}\n}\n\n/**\n * Base class for detached & attached context classes\n * @internal\n */\nexport class LocalFluidDataStoreContextBase extends FluidDataStoreContext {\n\tprivate readonly snapshotTree: ISnapshotTree | undefined;\n\n\tconstructor(props: ILocalFluidDataStoreContextProps) {\n\t\tsuper(\n\t\t\tprops,\n\t\t\tprops.snapshotTree !== undefined /* existing */,\n\t\t\ttrue /* isLocalDataStore */,\n\t\t\tprops.makeLocallyVisibleFn,\n\t\t);\n\n\t\t// Summarizer client should not create local data stores.\n\t\tthis.identifyLocalChangeInSummarizer(\"DataStoreCreatedInSummarizer\");\n\n\t\tthis.snapshotTree = props.snapshotTree;\n\t}\n\n\tpublic setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {\n\t\tswitch (attachState) {\n\t\t\tcase AttachState.Attaching: {\n\t\t\t\tassert(\n\t\t\t\t\tthis.attachState === AttachState.Detached,\n\t\t\t\t\t0x14d /* \"Should move from detached to attaching\" */,\n\t\t\t\t);\n\t\t\t\tthis._attachState = AttachState.Attaching;\n\t\t\t\tif (this.channel?.setAttachState) {\n\t\t\t\t\tthis.channel.setAttachState(attachState);\n\t\t\t\t} else if (this.channel) {\n\t\t\t\t\t// back-compat! To be removed in the future\n\t\t\t\t\t// Added in \"2.0.0-rc.2.0.0\" timeframe.\n\t\t\t\t\tthis.emit(\"attaching\");\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase AttachState.Attached: {\n\t\t\t\t// We can get called into here twice, as result of both container and data store being attached, if\n\t\t\t\t// those processes overlapped, for example, in a flow like that one:\n\t\t\t\t// 1. Container attach started\n\t\t\t\t// 2. data store attachment started\n\t\t\t\t// 3. container attached\n\t\t\t\t// 4. data store attached.\n\t\t\t\tif (this.attachState !== AttachState.Attached) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tthis.attachState === AttachState.Attaching,\n\t\t\t\t\t\t0x14e /* \"Should move from attaching to attached\" */,\n\t\t\t\t\t);\n\t\t\t\t\tthis._attachState = AttachState.Attached;\n\t\t\t\t\tthis.channel?.setAttachState?.(attachState);\n\t\t\t\t\tif (this.channel?.setAttachState) {\n\t\t\t\t\t\tthis.channel.setAttachState(attachState);\n\t\t\t\t\t} else if (this.channel) {\n\t\t\t\t\t\t// back-compat! To be removed in the future\n\t\t\t\t\t\t// Added in \"2.0.0-rc.2.0.0\" timeframe.\n\t\t\t\t\t\tthis.emit(\"attached\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(attachState, \"unreached\");\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachSummary}\n\t */\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {\n\t\tassert(\n\t\t\tthis.channel !== undefined,\n\t\t\t0x14f /* \"There should be a channel when generating attach message\" */,\n\t\t);\n\t\tassert(\n\t\t\tthis.pkg !== undefined,\n\t\t\t0x150 /* \"pkg should be available in local data store context\" */,\n\t\t);\n\n\t\tconst attachSummary = this.channel.getAttachSummary(telemetryContext);\n\n\t\t// Wrap dds summaries in .channels subtree.\n\t\twrapSummaryInChannelsTree(attachSummary);\n\n\t\t// Add data store's attributes to the summary.\n\t\tconst attributes = createAttributes(this.pkg, this.isInMemoryRoot());\n\t\taddBlobToSummary(attachSummary, dataStoreAttributesBlobName, JSON.stringify(attributes));\n\n\t\t// Add loadingGroupId to the summary\n\t\tif (this.loadingGroupId !== undefined) {\n\t\t\tattachSummary.summary.groupId = this.loadingGroupId;\n\t\t}\n\n\t\treturn attachSummary;\n\t}\n\n\t/**\n\t * {@inheritDoc FluidDataStoreContext.getAttachGCData}\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tassert(\n\t\t\tthis.channel !== undefined,\n\t\t\t0x9a6 /* There should be a channel when generating attach GC data */,\n\t\t);\n\t\treturn this.channel.getAttachGCData(telemetryContext);\n\t}\n\n\t// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda\n\tprivate readonly initialSnapshotDetailsP = new LazyPromise<ISnapshotDetails>(async () => {\n\t\tlet snapshot = this.snapshotTree;\n\t\t// eslint-disable-next-line import/no-deprecated\n\t\tlet attributes: ReadFluidDataStoreAttributes;\n\t\tlet isRootDataStore = false;\n\t\tif (snapshot !== undefined) {\n\t\t\t// Get the dataStore attributes.\n\t\t\t// Note: storage can be undefined in special case while detached.\n\t\t\tattributes = await getFluidDataStoreAttributes(this.storage, snapshot);\n\t\t\tif (hasIsolatedChannels(attributes)) {\n\t\t\t\tsnapshot = snapshot.trees[channelsTreeName];\n\t\t\t\tassert(\n\t\t\t\t\tsnapshot !== undefined,\n\t\t\t\t\t0x1ff /* \"isolated channels subtree should exist in local datastore snapshot\" */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.pkg === undefined) {\n\t\t\t\tthis.pkg = JSON.parse(attributes.pkg) as string[];\n\t\t\t\t// If there is no isRootDataStore in the attributes blob, set it to true. This ensures that data\n\t\t\t\t// stores in older documents are not garbage collected incorrectly. This may lead to additional\n\t\t\t\t// roots in the document but they won't break.\n\t\t\t\tif (attributes.isRootDataStore ?? true) {\n\t\t\t\t\tisRootDataStore = true;\n\t\t\t\t\tthis.setInMemoryRoot();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tassert(this.pkg !== undefined, 0x152 /* \"pkg should be available in local data store\" */);\n\n\t\treturn {\n\t\t\tpkg: this.pkg,\n\t\t\tisRootDataStore,\n\t\t\tsnapshot,\n\t\t};\n\t});\n\n\tpublic async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {\n\t\treturn this.initialSnapshotDetailsP;\n\t}\n\n\t/**\n\t * A context should only be marked as deleted when its a remote context.\n\t * Session Expiry at the runtime level should have closed the container creating the local data store context\n\t * before delete is even possible. Session Expiry is at 30 days, and sweep is done 36+ days later from the time\n\t * it was unreferenced. Thus the sweeping container should have loaded from a snapshot and thus creating a remote\n\t * context.\n\t */\n\tpublic delete(): void {\n\t\t// TODO: GC:Validation - potentially prevent this from happening or asserting. Maybe throw here.\n\t\tthis.mc.logger.sendErrorEvent({\n\t\t\teventName: \"GC_Deleted_DataStore_Unexpected_Delete\",\n\t\t\tmessage: \"Unexpected deletion of a local data store context\",\n\t\t});\n\t\tsuper.delete();\n\t}\n}\n\n/**\n * context implementation for \"attached\" data store runtime.\n * Various workflows (snapshot creation, requests) result in .realize() being called\n * on context, resulting in instantiation and attachment of runtime.\n * Runtime is created using data store factory that is associated with this context.\n * @internal\n */\nexport class LocalFluidDataStoreContext extends LocalFluidDataStoreContextBase {\n\tconstructor(props: ILocalFluidDataStoreContextProps) {\n\t\tsuper(props);\n\t}\n}\n\n/**\n * Detached context. Data Store runtime will be attached to it by attachRuntime() call\n * Before attachment happens, this context is not associated with particular type of runtime\n * or factory, i.e. it's package path is undefined.\n * Attachment process provides all missing parts - package path, data store runtime, and data store factory\n */\nexport class LocalDetachedFluidDataStoreContext\n\textends LocalFluidDataStoreContextBase\n\timplements IFluidDataStoreContextDetached\n{\n\tconstructor(props: ILocalDetachedFluidDataStoreContextProps) {\n\t\tsuper(props);\n\t\tthis.detachedRuntimeCreation = true;\n\t\tthis.channelToDataStoreFn = props.channelToDataStoreFn;\n\t}\n\tprivate readonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;\n\n\tpublic async attachRuntime(\n\t\tregistry: IProvideFluidDataStoreFactory,\n\t\tdataStoreChannel: IFluidDataStoreChannel,\n\t): Promise<IDataStore> {\n\t\tassert(this.detachedRuntimeCreation, 0x154 /* \"runtime creation is already attached\" */);\n\t\tthis.detachedRuntimeCreation = false;\n\n\t\tassert(this.channelP === undefined, 0x155 /* \"channel deferral is already set\" */);\n\n\t\tthis.channelP = Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tconst factory = registry.IFluidDataStoreFactory;\n\n\t\t\t\tconst factory2 = await this.factoryFromPackagePath();\n\t\t\t\tassert(factory2 === factory, 0x156 /* \"Unexpected factory for package path\" */);\n\n\t\t\t\tawait super.bindRuntime(dataStoreChannel, false /* existing */);\n\n\t\t\t\tassert(\n\t\t\t\t\t!(await this.isRoot()),\n\t\t\t\t\t0x8f7 /* there are no more createRootDataStore() kind of APIs! */,\n\t\t\t\t);\n\n\t\t\t\treturn dataStoreChannel;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"AttachRuntimeError\" }, error);\n\t\t\t\t// The following two lines result in same exception thrown.\n\t\t\t\t// But we need to ensure that this.channelDeferred.promise is \"observed\", as otherwise\n\t\t\t\t// out UT reports unhandled exception\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\treturn this.channelToDataStoreFn(await this.channelP);\n\t}\n\n\t/**\n\t * This method provides a synchronous path for binding a runtime to the context.\n\t *\n\t * Due to its synchronous nature, it is unable to validate that the runtime\n\t * represents a datastore which is instantiable by remote clients. This could\n\t * happen if the runtime's package path does not return a factory when looked up\n\t * in the container runtime's registry, or if the runtime's entrypoint is not\n\t * properly initialized. As both of these validation's are asynchronous to preform.\n\t *\n\t * If used incorrectly, this function can result in permanent data corruption.\n\t */\n\tpublic unsafe_AttachRuntimeSync(channel: IFluidDataStoreChannel): IDataStore {\n\t\tthis.channelP = Promise.resolve(channel);\n\t\tthis.processPendingOps(channel);\n\t\tthis.completeBindingRuntime(channel);\n\t\treturn this.channelToDataStoreFn(channel);\n\t}\n\n\tpublic async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {\n\t\tif (this.detachedRuntimeCreation) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Detached Fluid Data Store context can't be realized! Please attach runtime first!\",\n\t\t\t);\n\t\t}\n\t\treturn super.getInitialSnapshotDetails();\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreContexts.d.ts","sourceRoot":"","sources":["../src/dataStoreContexts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAOpF,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAE1F;;GAEG;AACH,qBAAa,iBACZ,YAAW,QAAQ,CAAC,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,EAAE,WAAW;IAEjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IAEtD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IAEtE;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsD;
|
|
1
|
+
{"version":3,"file":"dataStoreContexts.d.ts","sourceRoot":"","sources":["../src/dataStoreContexts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAOpF,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAE1F;;GAEG;AACH,qBAAa,iBACZ,YAAW,QAAQ,CAAC,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,EAAE,WAAW;IAEjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IAEtD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IAEtE;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsD;IAGvF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAiBzB;IAEH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;gBAElC,UAAU,EAAE,oBAAoB;IAI5C,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAI9D,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,QAAQ,IAAI,OAAO,CAE7B;IACD,SAAgB,OAAO,QAAO,IAAI,CAA2B;IAEtD,cAAc,IAAI,MAAM;IAIxB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAIlD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAWlC,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAC9B;IAEJ,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAI/E;;;OAGG;IACI,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IASrE;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAU5D;;;;;OAKG;IACU,iBAAiB,CAC7B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,GACX,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAU7C,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACI,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAO7B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAavB;;;;OAIG;IACI,iBAAiB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI;CAU9D"}
|
package/lib/dataStoreContexts.js
CHANGED
|
@@ -22,6 +22,7 @@ export class DataStoreContexts {
|
|
|
22
22
|
* This is a superset of _contexts, since contexts remain here once the Deferred resolves.
|
|
23
23
|
*/
|
|
24
24
|
this.deferredContexts = new Map();
|
|
25
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda
|
|
25
26
|
this.disposeOnce = new Lazy(() => {
|
|
26
27
|
// close/stop all store contexts
|
|
27
28
|
for (const [fluidDataStoreId, contextD] of this.deferredContexts) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreContexts.js","sourceRoot":"","sources":["../src/dataStoreContexts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAEN,iBAAiB,GACjB,MAAM,0CAA0C,CAAC;AAIlD;;GAEG;AACH,MAAM,OAAO,iBAAiB;IAwC7B,YAAY,UAAgC;QArC3B,qBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QAEtD;;WAEG;QACc,cAAS,GAAG,IAAI,GAAG,EAAiC,CAAC;QAEtE;;;;;;WAMG;QACc,qBAAgB,GAAG,IAAI,GAAG,EAA2C,CAAC;QAEtE,gBAAW,GAAG,IAAI,IAAI,CAAO,GAAG,EAAE;YAClD,gCAAgC;YAChC,KAAK,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAClE,QAAQ,CAAC,OAAO;qBACd,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;oBACjB,OAAO,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,YAAY,EAAE,EAAE;oBACvB,IAAI,CAAC,OAAO,CAAC,cAAc,CAC1B;wBACC,SAAS,EAAE,mCAAmC;wBAC9C,gBAAgB;qBAChB,EACD,YAAY,CACZ,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACF,CAAC,CAAC,CAAC;QAmBa,YAAO,GAAG,GAAS,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;QA6B5C,6BAAwB,GACxC,IAAI,GAAG,EAAE,CAAC;QA5CV,IAAI,CAAC,OAAO,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED,IAAW,IAAI;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;IACnC,CAAC;IAGM,cAAc;QACpB,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;IACnC,CAAC;IAEM,UAAU,CAAC,EAAU;QAC3B,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAEM,GAAG,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAEM,GAAG,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAEM,MAAM,CAAC,EAAU;QACvB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAEjC,kGAAkG;QAClG,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAE/C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAKM,yBAAyB,CAAC,EAAU;QAC1C,OAAO,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,EAAU;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7D,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,OAAO,OAAqC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACI,UAAU,CAAC,OAAmC;QACpD,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAE/E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,iBAAiB,CAC7B,EAAU,EACV,IAAa;QAEb,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAEhD,IAAI,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC;YAC3C,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,OAAO,eAAe,CAAC,OAAO,CAAC;IAChC,CAAC;IAEO,cAAc,CAAC,EAAU;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,QAAQ,EAAE,CAAC;YACd,OAAO,QAAQ,CAAC;QACjB,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,QAAQ,EAAyB,CAAC;QAC1D,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC3C,OAAO,WAAW,CAAC;IACpB,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,EAAU;QACrB,MAAM,OAAO,GAAY,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAExF,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,EAAU;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACnE,MAAM,CACL,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,EAC9B,KAAK,CAAC,oEAAoE,CAC1E,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/C,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAClE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,OAA8B;QACtD,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAE/E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhC,qEAAqE;QACrE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred, Lazy } from \"@fluidframework/core-utils/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { FluidDataStoreContext, LocalFluidDataStoreContext } from \"./dataStoreContext.js\";\n\n/**\n * @internal\n */\nexport class DataStoreContexts\n\timplements Iterable<[string, FluidDataStoreContext]>, IDisposable\n{\n\tprivate readonly notBoundContexts = new Set<string>();\n\n\t/**\n\t * Attached and loaded context proxies\n\t */\n\tprivate readonly _contexts = new Map<string, FluidDataStoreContext>();\n\n\t/**\n\t * List of pending context waiting either to be bound or to arrive from another client.\n\t * This covers the case where a local context has been created but not yet bound,\n\t * or the case where a client knows a store will exist and is waiting on its creation,\n\t * so that a caller may await the deferred's promise until such a time as the context is fully ready.\n\t * This is a superset of _contexts, since contexts remain here once the Deferred resolves.\n\t */\n\tprivate readonly deferredContexts = new Map<string, Deferred<FluidDataStoreContext>>();\n\n\tprivate readonly disposeOnce = new Lazy<void>(() => {\n\t\t// close/stop all store contexts\n\t\tfor (const [fluidDataStoreId, contextD] of this.deferredContexts) {\n\t\t\tcontextD.promise\n\t\t\t\t.then((context) => {\n\t\t\t\t\tcontext.dispose();\n\t\t\t\t})\n\t\t\t\t.catch((contextError) => {\n\t\t\t\t\tthis._logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"FluidDataStoreContextDisposeError\",\n\t\t\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontextError,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t}\n\t});\n\n\tprivate readonly _logger: ITelemetryLoggerExt;\n\n\tconstructor(baseLogger: ITelemetryBaseLogger) {\n\t\tthis._logger = createChildLogger({ logger: baseLogger });\n\t}\n\n\t[Symbol.iterator](): Iterator<[string, FluidDataStoreContext]> {\n\t\treturn this._contexts.entries();\n\t}\n\n\tpublic get size(): number {\n\t\treturn this._contexts.size;\n\t}\n\n\tpublic get disposed(): boolean {\n\t\treturn this.disposeOnce.evaluated;\n\t}\n\tpublic readonly dispose = (): void => this.disposeOnce.value;\n\n\tpublic notBoundLength(): number {\n\t\treturn this.notBoundContexts.size;\n\t}\n\n\tpublic isNotBound(id: string): boolean {\n\t\treturn this.notBoundContexts.has(id);\n\t}\n\n\tpublic has(id: string): boolean {\n\t\treturn this._contexts.has(id);\n\t}\n\n\tpublic get(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._contexts.get(id);\n\t}\n\n\tpublic delete(id: string): boolean {\n\t\tthis.deferredContexts.delete(id);\n\t\tthis.notBoundContexts.delete(id);\n\n\t\t// Stash the context here in case it's requested in this session, we can log some details about it\n\t\tconst context = this._contexts.get(id);\n\t\tthis._recentlyDeletedContexts.set(id, context);\n\n\t\treturn this._contexts.delete(id);\n\t}\n\n\tprivate readonly _recentlyDeletedContexts: Map<string, FluidDataStoreContext | undefined> =\n\t\tnew Map();\n\n\tpublic getRecentlyDeletedContext(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._recentlyDeletedContexts.get(id);\n\t}\n\n\t/**\n\t * Return the unbound local context with the given id,\n\t * or undefined if it's not found or not unbound.\n\t */\n\tpublic getUnbound(id: string): LocalFluidDataStoreContext | undefined {\n\t\tconst context = this._contexts.get(id);\n\t\tif (context === undefined || !this.notBoundContexts.has(id)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn context as LocalFluidDataStoreContext;\n\t}\n\n\t/**\n\t * Add the given context, marking it as to-be-bound\n\t */\n\tpublic addUnbound(context: LocalFluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x158 /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\tthis.notBoundContexts.add(id);\n\t\tthis.ensureDeferred(id);\n\t}\n\n\t/**\n\t * Get the context with the given id, once it exists locally and is attached.\n\t * e.g. If created locally, it must be bound, or if created remotely then it's fine as soon as it's sync'd in.\n\t * @param id - The id of the context to get\n\t * @param wait - If false, return undefined if the context isn't present and ready now. Otherwise, wait for it.\n\t */\n\tpublic async getBoundOrRemoted(\n\t\tid: string,\n\t\twait: boolean,\n\t): Promise<FluidDataStoreContext | undefined> {\n\t\tconst deferredContext = this.ensureDeferred(id);\n\n\t\tif (!wait && !deferredContext.isCompleted) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn deferredContext.promise;\n\t}\n\n\tprivate ensureDeferred(id: string): Deferred<FluidDataStoreContext> {\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tif (deferred) {\n\t\t\treturn deferred;\n\t\t}\n\n\t\tconst newDeferred = new Deferred<FluidDataStoreContext>();\n\t\tthis.deferredContexts.set(id, newDeferred);\n\t\treturn newDeferred;\n\t}\n\n\t/**\n\t * Update this context as bound\n\t */\n\tpublic bind(id: string): void {\n\t\tconst removed: boolean = this.notBoundContexts.delete(id);\n\t\tassert(removed, 0x159 /* \"The given id was not found in notBoundContexts to delete\" */);\n\n\t\tthis.resolveDeferred(id);\n\t}\n\n\t/**\n\t * Triggers the deferred to resolve, indicating the context is not local-only\n\t * @param id - The id of the context to resolve to\n\t */\n\tprivate resolveDeferred(id: string): void {\n\t\tconst context = this._contexts.get(id);\n\t\tassert(!!context, 0x15a /* \"Cannot find context to resolve to\" */);\n\t\tassert(\n\t\t\t!this.notBoundContexts.has(id),\n\t\t\t0x15b /* \"Expected this id to already be removed from notBoundContexts\" */,\n\t\t);\n\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tassert(!!deferred, 0x15c /* \"Cannot find deferred to resolve\" */);\n\t\tdeferred.resolve(context);\n\t}\n\n\t/**\n\t * Add the given context, marking it as not local-only.\n\t * This could be because it's a local context that's been bound, or because it's a remote context.\n\t * @param context - The context to add\n\t */\n\tpublic addBoundOrRemoted(context: FluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x15d /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\t// Resolve the deferred immediately since this context is not unbound\n\t\tthis.ensureDeferred(id);\n\t\tthis.resolveDeferred(id);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dataStoreContexts.js","sourceRoot":"","sources":["../src/dataStoreContexts.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 { IDisposable, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred, Lazy } from \"@fluidframework/core-utils/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { FluidDataStoreContext, LocalFluidDataStoreContext } from \"./dataStoreContext.js\";\n\n/**\n * @internal\n */\nexport class DataStoreContexts\n\timplements Iterable<[string, FluidDataStoreContext]>, IDisposable\n{\n\tprivate readonly notBoundContexts = new Set<string>();\n\n\t/**\n\t * Attached and loaded context proxies\n\t */\n\tprivate readonly _contexts = new Map<string, FluidDataStoreContext>();\n\n\t/**\n\t * List of pending context waiting either to be bound or to arrive from another client.\n\t * This covers the case where a local context has been created but not yet bound,\n\t * or the case where a client knows a store will exist and is waiting on its creation,\n\t * so that a caller may await the deferred's promise until such a time as the context is fully ready.\n\t * This is a superset of _contexts, since contexts remain here once the Deferred resolves.\n\t */\n\tprivate readonly deferredContexts = new Map<string, Deferred<FluidDataStoreContext>>();\n\n\t// eslint-disable-next-line unicorn/consistent-function-scoping -- Property is defined once; no need to extract inner lambda\n\tprivate readonly disposeOnce = new Lazy<void>(() => {\n\t\t// close/stop all store contexts\n\t\tfor (const [fluidDataStoreId, contextD] of this.deferredContexts) {\n\t\t\tcontextD.promise\n\t\t\t\t.then((context) => {\n\t\t\t\t\tcontext.dispose();\n\t\t\t\t})\n\t\t\t\t.catch((contextError) => {\n\t\t\t\t\tthis._logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"FluidDataStoreContextDisposeError\",\n\t\t\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontextError,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t}\n\t});\n\n\tprivate readonly _logger: ITelemetryLoggerExt;\n\n\tconstructor(baseLogger: ITelemetryBaseLogger) {\n\t\tthis._logger = createChildLogger({ logger: baseLogger });\n\t}\n\n\t[Symbol.iterator](): Iterator<[string, FluidDataStoreContext]> {\n\t\treturn this._contexts.entries();\n\t}\n\n\tpublic get size(): number {\n\t\treturn this._contexts.size;\n\t}\n\n\tpublic get disposed(): boolean {\n\t\treturn this.disposeOnce.evaluated;\n\t}\n\tpublic readonly dispose = (): void => this.disposeOnce.value;\n\n\tpublic notBoundLength(): number {\n\t\treturn this.notBoundContexts.size;\n\t}\n\n\tpublic isNotBound(id: string): boolean {\n\t\treturn this.notBoundContexts.has(id);\n\t}\n\n\tpublic has(id: string): boolean {\n\t\treturn this._contexts.has(id);\n\t}\n\n\tpublic get(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._contexts.get(id);\n\t}\n\n\tpublic delete(id: string): boolean {\n\t\tthis.deferredContexts.delete(id);\n\t\tthis.notBoundContexts.delete(id);\n\n\t\t// Stash the context here in case it's requested in this session, we can log some details about it\n\t\tconst context = this._contexts.get(id);\n\t\tthis._recentlyDeletedContexts.set(id, context);\n\n\t\treturn this._contexts.delete(id);\n\t}\n\n\tprivate readonly _recentlyDeletedContexts: Map<string, FluidDataStoreContext | undefined> =\n\t\tnew Map();\n\n\tpublic getRecentlyDeletedContext(id: string): FluidDataStoreContext | undefined {\n\t\treturn this._recentlyDeletedContexts.get(id);\n\t}\n\n\t/**\n\t * Return the unbound local context with the given id,\n\t * or undefined if it's not found or not unbound.\n\t */\n\tpublic getUnbound(id: string): LocalFluidDataStoreContext | undefined {\n\t\tconst context = this._contexts.get(id);\n\t\tif (context === undefined || !this.notBoundContexts.has(id)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn context as LocalFluidDataStoreContext;\n\t}\n\n\t/**\n\t * Add the given context, marking it as to-be-bound\n\t */\n\tpublic addUnbound(context: LocalFluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x158 /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\tthis.notBoundContexts.add(id);\n\t\tthis.ensureDeferred(id);\n\t}\n\n\t/**\n\t * Get the context with the given id, once it exists locally and is attached.\n\t * e.g. If created locally, it must be bound, or if created remotely then it's fine as soon as it's sync'd in.\n\t * @param id - The id of the context to get\n\t * @param wait - If false, return undefined if the context isn't present and ready now. Otherwise, wait for it.\n\t */\n\tpublic async getBoundOrRemoted(\n\t\tid: string,\n\t\twait: boolean,\n\t): Promise<FluidDataStoreContext | undefined> {\n\t\tconst deferredContext = this.ensureDeferred(id);\n\n\t\tif (!wait && !deferredContext.isCompleted) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn deferredContext.promise;\n\t}\n\n\tprivate ensureDeferred(id: string): Deferred<FluidDataStoreContext> {\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tif (deferred) {\n\t\t\treturn deferred;\n\t\t}\n\n\t\tconst newDeferred = new Deferred<FluidDataStoreContext>();\n\t\tthis.deferredContexts.set(id, newDeferred);\n\t\treturn newDeferred;\n\t}\n\n\t/**\n\t * Update this context as bound\n\t */\n\tpublic bind(id: string): void {\n\t\tconst removed: boolean = this.notBoundContexts.delete(id);\n\t\tassert(removed, 0x159 /* \"The given id was not found in notBoundContexts to delete\" */);\n\n\t\tthis.resolveDeferred(id);\n\t}\n\n\t/**\n\t * Triggers the deferred to resolve, indicating the context is not local-only\n\t * @param id - The id of the context to resolve to\n\t */\n\tprivate resolveDeferred(id: string): void {\n\t\tconst context = this._contexts.get(id);\n\t\tassert(!!context, 0x15a /* \"Cannot find context to resolve to\" */);\n\t\tassert(\n\t\t\t!this.notBoundContexts.has(id),\n\t\t\t0x15b /* \"Expected this id to already be removed from notBoundContexts\" */,\n\t\t);\n\n\t\tconst deferred = this.deferredContexts.get(id);\n\t\tassert(!!deferred, 0x15c /* \"Cannot find deferred to resolve\" */);\n\t\tdeferred.resolve(context);\n\t}\n\n\t/**\n\t * Add the given context, marking it as not local-only.\n\t * This could be because it's a local context that's been bound, or because it's a remote context.\n\t * @param context - The context to add\n\t */\n\tpublic addBoundOrRemoted(context: FluidDataStoreContext): void {\n\t\tconst id = context.id;\n\t\tassert(!this._contexts.has(id), 0x15d /* \"Creating store with existing ID\" */);\n\n\t\tthis._contexts.set(id, context);\n\n\t\t// Resolve the deferred immediately since this context is not unbound\n\t\tthis.ensureDeferred(id);\n\t\tthis.resolveDeferred(id);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deltaScheduler.d.ts","sourceRoot":"","sources":["../src/deltaScheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"deltaScheduler.d.ts","sourceRoot":"","sources":["../src/deltaScheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAEnF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAc,MAAM,0CAA0C,CAAC;AAE3F;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;IA4BzB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM;IA5BxB,gBAAuB,cAAc,MAAM;IAG3C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAM;IAE9C,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,mCAAmC,CAAyC;IAKpF,OAAO,CAAC,eAAe,CAAa;IAEpC,OAAO,CAAC,aAAa,CAUR;gBAGK,YAAY,EAAE,iBAAiB,EAC/B,oBAAoB,EAAE,iBAAiB,CAAC,2BAA2B,CAAC,EACpE,MAAM,EAAE,mBAAmB;IAOtC,OAAO,IAAI,IAAI;IAMtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAiBzB;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAmDvB;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CA8B/B;IAEF;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAK1B"}
|
package/lib/deltaScheduler.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { performanceNow } from "@fluid-internal/client-utils";
|
|
6
6
|
import { formatTick } from "@fluidframework/telemetry-utils/internal";
|
|
7
7
|
/**
|
|
8
8
|
* DeltaScheduler is responsible for the scheduling of inbound delta queue in cases where there
|
|
@@ -31,7 +31,7 @@ export class DeltaScheduler {
|
|
|
31
31
|
this.schedulingCount = 0;
|
|
32
32
|
this.batchBegin = (message) => {
|
|
33
33
|
if (!this.processingStartTime) {
|
|
34
|
-
this.processingStartTime =
|
|
34
|
+
this.processingStartTime = performanceNow();
|
|
35
35
|
}
|
|
36
36
|
if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
|
|
37
37
|
// Every 500th time we are scheduling the inbound queue, we log telemetry for the
|
|
@@ -43,7 +43,7 @@ export class DeltaScheduler {
|
|
|
43
43
|
numberOfBatchesProcessed: 0,
|
|
44
44
|
firstSequenceNumber: message.sequenceNumber,
|
|
45
45
|
lastSequenceNumber: message.sequenceNumber,
|
|
46
|
-
startTime:
|
|
46
|
+
startTime: performanceNow(),
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
};
|
|
@@ -54,7 +54,7 @@ export class DeltaScheduler {
|
|
|
54
54
|
this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
|
|
55
55
|
}
|
|
56
56
|
if (this.shouldRunScheduler()) {
|
|
57
|
-
const currentTime =
|
|
57
|
+
const currentTime = performanceNow();
|
|
58
58
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
59
59
|
const elapsedTime = currentTime - this.processingStartTime;
|
|
60
60
|
if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
|
|
@@ -83,7 +83,7 @@ export class DeltaScheduler {
|
|
|
83
83
|
processingTime: formatTick(this.schedulingLog.totalProcessingTime),
|
|
84
84
|
numberOfTurns: this.schedulingLog.numberOfTurns,
|
|
85
85
|
batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
|
|
86
|
-
timeToResume: formatTick(
|
|
86
|
+
timeToResume: formatTick(performanceNow() - currentTime),
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
this.deltaManager.inbound.resume();
|
|
@@ -96,7 +96,7 @@ export class DeltaScheduler {
|
|
|
96
96
|
if (this.schedulingLog) {
|
|
97
97
|
// Add the time taken for processing the final ops to the total processing time in the
|
|
98
98
|
// telemetry log object.
|
|
99
|
-
const currentTime =
|
|
99
|
+
const currentTime = performanceNow();
|
|
100
100
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
101
101
|
this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
|
|
102
102
|
this.logger.sendTelemetryEvent({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deltaScheduler.js","sourceRoot":"","sources":["../src/deltaScheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAA0B,MAAM,8BAA8B,CAAC;AAInF,OAAO,EAAuB,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3F;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAc;IA2B1B,YACkB,YAA+B,EAC/B,oBAAoE,EACpE,MAA2B;QAF3B,iBAAY,GAAZ,YAAY,CAAmB;QAC/B,yBAAoB,GAApB,oBAAoB,CAAgD;QACpE,WAAM,GAAN,MAAM,CAAqB;QA1B7C,2DAA2D;QAC1C,4BAAuB,GAAG,EAAE,CAAC;QAGtC,wCAAmC,GAAW,cAAc,CAAC,cAAc,CAAC;QAEpF,+FAA+F;QAC/F,gGAAgG;QAChG,sBAAsB;QACd,oBAAe,GAAW,CAAC,CAAC;QA8BnB,eAAU,GAAG,CAAC,OAAkC,EAAQ,EAAE;YAC1E,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC/B,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAC9C,CAAC;YACD,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC;gBAC1E,iFAAiF;gBACjF,oFAAoF;gBACpF,IAAI,CAAC,aAAa,GAAG;oBACpB,qBAAqB,EAAE,CAAC;oBACxB,aAAa,EAAE,CAAC;oBAChB,mBAAmB,EAAE,CAAC;oBACtB,wBAAwB,EAAE,CAAC;oBAC3B,mBAAmB,EAAE,OAAO,CAAC,cAAc;oBAC3C,kBAAkB,EAAE,OAAO,CAAC,cAAc;oBAC1C,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE;iBAC5B,CAAC;YACH,CAAC;QACF,CAAC,CAAC;QAEe,aAAQ,GAAG,CAAC,KAAc,EAAE,OAAkC,EAAQ,EAAE;YACxF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,IAAI,CAAC,aAAa,CAAC,wBAAwB,EAAE,CAAC;gBAC9C,IAAI,CAAC,aAAa,CAAC,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;gBAC/D,IAAI,CAAC,aAAa,CAAC,qBAAqB,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC;YAC7E,CAAC;YAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBAC/B,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBACtC,oEAAoE;gBACpE,MAAM,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC,mBAAoB,CAAC;gBAC5D,IAAI,WAAW,GAAG,IAAI,CAAC,mCAAmC,EAAE,CAAC;oBAC5D,+EAA+E;oBAC/E,iDAAiD;oBAEjD,mEAAmE;oBACnE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBAElC,6FAA6F;oBAC7F,8FAA8F;oBAC9F,2CAA2C;oBAC3C,IAAI,CAAC,mCAAmC,IAAI,IAAI,CAAC,uBAAuB,CAAC;oBAEzE,8EAA8E;oBAC9E,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;wBACxB,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;wBACnC,IAAI,CAAC,aAAa,CAAC,mBAAmB,IAAI,WAAW,CAAC;oBACvD,CAAC;oBAED,UAAU,CAAC,GAAG,EAAE;wBACf,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;4BACxB,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;gCAC9B,SAAS,EAAE,iCAAiC;gCAC5C,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC;gCACjC,YAAY,EACX,IAAI,CAAC,aAAa,CAAC,kBAAkB;oCACrC,IAAI,CAAC,aAAa,CAAC,mBAAmB;oCACtC,CAAC;gCACF,qBAAqB,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM;gCACvD,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC;gCAClE,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa;gCAC/C,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,wBAAwB;gCAC7D,YAAY,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;6BACzD,CAAC,CAAC;wBACJ,CAAC;wBACD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpC,CAAC,CAAC,CAAC;oBAEH,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;gBACtC,CAAC;YACF,CAAC;QACF,CAAC,CAAC;QAEe,qBAAgB,GAAG,GAAS,EAAE;YAC9C,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACxB,sFAAsF;gBACtF,wBAAwB;gBACxB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBACtC,oEAAoE;gBACpE,IAAI,CAAC,aAAa,CAAC,mBAAmB,IAAI,WAAW,GAAG,IAAI,CAAC,mBAAoB,CAAC;gBAElF,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;oBAC9B,SAAS,EAAE,0BAA0B;oBACrC,qBAAqB,EAAE,IAAI,CAAC,aAAa,CAAC,qBAAqB;oBAC/D,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa;oBAC/C,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC;oBAClE,YAAY,EACX,IAAI,CAAC,aAAa,CAAC,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,mBAAmB,GAAG,CAAC;oBACnF,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,wBAAwB;oBAC7D,QAAQ,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;oBAChE,eAAe,EAAE,IAAI,CAAC,eAAe;iBACrC,CAAC,CAAC;gBAEH,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAChC,CAAC;YAED,yFAAyF;YACzF,qCAAqC;YACrC,IAAI,CAAC,eAAe,EAAE,CAAC;YAEvB,8BAA8B;YAC9B,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;YACrC,IAAI,CAAC,mCAAmC,GAAG,cAAc,CAAC,cAAc,CAAC;QAC1E,CAAC,CAAC;QAjHD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC5D,oBAAoB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACvD,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IAEM,OAAO;QACb,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7D,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7D,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC;IA0GD;;OAEG;IACK,kBAAkB;QACzB,qFAAqF;QACrF,qBAAqB;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7C,CAAC;;AAzJD,gDAAgD;AACzB,6BAAc,GAAG,EAAE,AAAL,CAAM","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { performance, type TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IContainerRuntimeBaseEvents } from \"@fluidframework/runtime-definitions/internal\";\nimport { ITelemetryLoggerExt, formatTick } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * DeltaScheduler is responsible for the scheduling of inbound delta queue in cases where there\n * is more than one op a particular run of the queue. It does not schedule if there is just one\n * op or just one batch in the run. It does the following two things:\n *\n * 1. If the ops have been processed for more than a specific amount of time, it pauses the queue\n * and calls setTimeout to schedule a resume of the queue. This ensures that we don't block\n * the JS thread for a long time processing ops synchronously (for example, when catching up\n * ops right after boot or catching up ops / delayed realizing data stores by summarizer).\n *\n * 2. If we scheduled a particular run of the queue, it logs telemetry for the number of ops\n * processed, the time and number of turns it took to process the ops.\n */\nexport class DeltaScheduler {\n\t// The time for processing ops in a single turn.\n\tpublic static readonly processingTime = 50;\n\n\t// The increase in time for processing ops after each turn.\n\tprivate readonly processingTimeIncrement = 10;\n\n\tprivate processingStartTime: number | undefined;\n\tprivate currentAllowedProcessingTimeForTurn: number = DeltaScheduler.processingTime;\n\n\t// This keeps track of the number of times inbound queue has been scheduled. After a particular\n\t// count, we log telemetry for the number of ops processed, the time and number of turns it took\n\t// to process the ops.\n\tprivate schedulingCount: number = 0;\n\n\tprivate schedulingLog:\n\t\t| {\n\t\t\t\topsRemainingToProcess: number;\n\t\t\t\ttotalProcessingTime: number;\n\t\t\t\tnumberOfTurns: number;\n\t\t\t\tnumberOfBatchesProcessed: number;\n\t\t\t\tlastSequenceNumber: number;\n\t\t\t\tfirstSequenceNumber: number;\n\t\t\t\tstartTime: number;\n\t\t }\n\t\t| undefined;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly runtimeEventsEmitter: TypedEventEmitter<IContainerRuntimeBaseEvents>,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\tthis.deltaManager.inbound.on(\"idle\", this.inboundQueueIdle);\n\t\truntimeEventsEmitter.on(\"batchBegin\", this.batchBegin);\n\t\truntimeEventsEmitter.on(\"batchEnd\", this.batchEnd);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.inbound.off(\"idle\", this.inboundQueueIdle);\n\t\tthis.runtimeEventsEmitter.off(\"batchBegin\", this.batchBegin);\n\t\tthis.runtimeEventsEmitter.off(\"batchEnd\", this.batchEnd);\n\t}\n\n\tprivate readonly batchBegin = (message: ISequencedDocumentMessage): void => {\n\t\tif (!this.processingStartTime) {\n\t\t\tthis.processingStartTime = performance.now();\n\t\t}\n\t\tif (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {\n\t\t\t// Every 500th time we are scheduling the inbound queue, we log telemetry for the\n\t\t\t// number of ops processed, the time and number of turns it took to process the ops.\n\t\t\tthis.schedulingLog = {\n\t\t\t\topsRemainingToProcess: 0,\n\t\t\t\tnumberOfTurns: 1,\n\t\t\t\ttotalProcessingTime: 0,\n\t\t\t\tnumberOfBatchesProcessed: 0,\n\t\t\t\tfirstSequenceNumber: message.sequenceNumber,\n\t\t\t\tlastSequenceNumber: message.sequenceNumber,\n\t\t\t\tstartTime: performance.now(),\n\t\t\t};\n\t\t}\n\t};\n\n\tprivate readonly batchEnd = (error: unknown, message: ISequencedDocumentMessage): void => {\n\t\tif (this.schedulingLog) {\n\t\t\tthis.schedulingLog.numberOfBatchesProcessed++;\n\t\t\tthis.schedulingLog.lastSequenceNumber = message.sequenceNumber;\n\t\t\tthis.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;\n\t\t}\n\n\t\tif (this.shouldRunScheduler()) {\n\t\t\tconst currentTime = performance.now();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst elapsedTime = currentTime - this.processingStartTime!;\n\t\t\tif (elapsedTime > this.currentAllowedProcessingTimeForTurn) {\n\t\t\t\t// We have processed ops for more than the total processing time. So, pause the\n\t\t\t\t// queue, yield the thread and schedule a resume.\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\tthis.deltaManager.inbound.pause();\n\n\t\t\t\t// Increase the total processing time. Keep doing this after each turn until all the ops have\n\t\t\t\t// been processed. This way we keep the responsiveness at the beginning while also making sure\n\t\t\t\t// that all the ops process fairly quickly.\n\t\t\t\tthis.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;\n\n\t\t\t\t// If we are logging the telemetry this time, update the telemetry log object.\n\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\tthis.schedulingLog.numberOfTurns++;\n\t\t\t\t\tthis.schedulingLog.totalProcessingTime += elapsedTime;\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\t\teventName: \"InboundOpsPartialProcessingTime\",\n\t\t\t\t\t\t\tduration: formatTick(elapsedTime),\n\t\t\t\t\t\t\topsProcessed:\n\t\t\t\t\t\t\t\tthis.schedulingLog.lastSequenceNumber -\n\t\t\t\t\t\t\t\tthis.schedulingLog.firstSequenceNumber +\n\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\topsRemainingToProcess: this.deltaManager.inbound.length,\n\t\t\t\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\t\t\t\ttimeToResume: formatTick(performance.now() - currentTime),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.deltaManager.inbound.resume();\n\t\t\t\t});\n\n\t\t\t\tthis.processingStartTime = undefined;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate readonly inboundQueueIdle = (): void => {\n\t\tif (this.schedulingLog) {\n\t\t\t// Add the time taken for processing the final ops to the total processing time in the\n\t\t\t// telemetry log object.\n\t\t\tconst currentTime = performance.now();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime!;\n\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"InboundOpsProcessingTime\",\n\t\t\t\topsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,\n\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\topsProcessed:\n\t\t\t\t\tthis.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,\n\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\tduration: formatTick(currentTime - this.schedulingLog.startTime),\n\t\t\t\tschedulingCount: this.schedulingCount,\n\t\t\t});\n\n\t\t\tthis.schedulingLog = undefined;\n\t\t}\n\n\t\t// If we scheduled this batch of the inbound queue, increment the counter that tracks the\n\t\t// number of times we have done this.\n\t\tthis.schedulingCount++;\n\n\t\t// Reset the processing times.\n\t\tthis.processingStartTime = undefined;\n\t\tthis.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;\n\t};\n\n\t/**\n\t * This function tells whether we should run the scheduler.\n\t */\n\tprivate shouldRunScheduler(): boolean {\n\t\t// If there are still ops in the queue after the one we are processing now, we should\n\t\t// run the scheduler.\n\t\treturn this.deltaManager.inbound.length > 0;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"deltaScheduler.js","sourceRoot":"","sources":["../src/deltaScheduler.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 { performanceNow, type TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IContainerRuntimeBaseEvents } from \"@fluidframework/runtime-definitions/internal\";\nimport { ITelemetryLoggerExt, formatTick } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * DeltaScheduler is responsible for the scheduling of inbound delta queue in cases where there\n * is more than one op a particular run of the queue. It does not schedule if there is just one\n * op or just one batch in the run. It does the following two things:\n *\n * 1. If the ops have been processed for more than a specific amount of time, it pauses the queue\n * and calls setTimeout to schedule a resume of the queue. This ensures that we don't block\n * the JS thread for a long time processing ops synchronously (for example, when catching up\n * ops right after boot or catching up ops / delayed realizing data stores by summarizer).\n *\n * 2. If we scheduled a particular run of the queue, it logs telemetry for the number of ops\n * processed, the time and number of turns it took to process the ops.\n */\nexport class DeltaScheduler {\n\t// The time for processing ops in a single turn.\n\tpublic static readonly processingTime = 50;\n\n\t// The increase in time for processing ops after each turn.\n\tprivate readonly processingTimeIncrement = 10;\n\n\tprivate processingStartTime: number | undefined;\n\tprivate currentAllowedProcessingTimeForTurn: number = DeltaScheduler.processingTime;\n\n\t// This keeps track of the number of times inbound queue has been scheduled. After a particular\n\t// count, we log telemetry for the number of ops processed, the time and number of turns it took\n\t// to process the ops.\n\tprivate schedulingCount: number = 0;\n\n\tprivate schedulingLog:\n\t\t| {\n\t\t\t\topsRemainingToProcess: number;\n\t\t\t\ttotalProcessingTime: number;\n\t\t\t\tnumberOfTurns: number;\n\t\t\t\tnumberOfBatchesProcessed: number;\n\t\t\t\tlastSequenceNumber: number;\n\t\t\t\tfirstSequenceNumber: number;\n\t\t\t\tstartTime: number;\n\t\t }\n\t\t| undefined;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly runtimeEventsEmitter: TypedEventEmitter<IContainerRuntimeBaseEvents>,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\tthis.deltaManager.inbound.on(\"idle\", this.inboundQueueIdle);\n\t\truntimeEventsEmitter.on(\"batchBegin\", this.batchBegin);\n\t\truntimeEventsEmitter.on(\"batchEnd\", this.batchEnd);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.inbound.off(\"idle\", this.inboundQueueIdle);\n\t\tthis.runtimeEventsEmitter.off(\"batchBegin\", this.batchBegin);\n\t\tthis.runtimeEventsEmitter.off(\"batchEnd\", this.batchEnd);\n\t}\n\n\tprivate readonly batchBegin = (message: ISequencedDocumentMessage): void => {\n\t\tif (!this.processingStartTime) {\n\t\t\tthis.processingStartTime = performanceNow();\n\t\t}\n\t\tif (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {\n\t\t\t// Every 500th time we are scheduling the inbound queue, we log telemetry for the\n\t\t\t// number of ops processed, the time and number of turns it took to process the ops.\n\t\t\tthis.schedulingLog = {\n\t\t\t\topsRemainingToProcess: 0,\n\t\t\t\tnumberOfTurns: 1,\n\t\t\t\ttotalProcessingTime: 0,\n\t\t\t\tnumberOfBatchesProcessed: 0,\n\t\t\t\tfirstSequenceNumber: message.sequenceNumber,\n\t\t\t\tlastSequenceNumber: message.sequenceNumber,\n\t\t\t\tstartTime: performanceNow(),\n\t\t\t};\n\t\t}\n\t};\n\n\tprivate readonly batchEnd = (error: unknown, message: ISequencedDocumentMessage): void => {\n\t\tif (this.schedulingLog) {\n\t\t\tthis.schedulingLog.numberOfBatchesProcessed++;\n\t\t\tthis.schedulingLog.lastSequenceNumber = message.sequenceNumber;\n\t\t\tthis.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;\n\t\t}\n\n\t\tif (this.shouldRunScheduler()) {\n\t\t\tconst currentTime = performanceNow();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst elapsedTime = currentTime - this.processingStartTime!;\n\t\t\tif (elapsedTime > this.currentAllowedProcessingTimeForTurn) {\n\t\t\t\t// We have processed ops for more than the total processing time. So, pause the\n\t\t\t\t// queue, yield the thread and schedule a resume.\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\tthis.deltaManager.inbound.pause();\n\n\t\t\t\t// Increase the total processing time. Keep doing this after each turn until all the ops have\n\t\t\t\t// been processed. This way we keep the responsiveness at the beginning while also making sure\n\t\t\t\t// that all the ops process fairly quickly.\n\t\t\t\tthis.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;\n\n\t\t\t\t// If we are logging the telemetry this time, update the telemetry log object.\n\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\tthis.schedulingLog.numberOfTurns++;\n\t\t\t\t\tthis.schedulingLog.totalProcessingTime += elapsedTime;\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\t\teventName: \"InboundOpsPartialProcessingTime\",\n\t\t\t\t\t\t\tduration: formatTick(elapsedTime),\n\t\t\t\t\t\t\topsProcessed:\n\t\t\t\t\t\t\t\tthis.schedulingLog.lastSequenceNumber -\n\t\t\t\t\t\t\t\tthis.schedulingLog.firstSequenceNumber +\n\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\topsRemainingToProcess: this.deltaManager.inbound.length,\n\t\t\t\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\t\t\t\ttimeToResume: formatTick(performanceNow() - currentTime),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.deltaManager.inbound.resume();\n\t\t\t\t});\n\n\t\t\t\tthis.processingStartTime = undefined;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate readonly inboundQueueIdle = (): void => {\n\t\tif (this.schedulingLog) {\n\t\t\t// Add the time taken for processing the final ops to the total processing time in the\n\t\t\t// telemetry log object.\n\t\t\tconst currentTime = performanceNow();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime!;\n\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"InboundOpsProcessingTime\",\n\t\t\t\topsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,\n\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\topsProcessed:\n\t\t\t\t\tthis.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,\n\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\tduration: formatTick(currentTime - this.schedulingLog.startTime),\n\t\t\t\tschedulingCount: this.schedulingCount,\n\t\t\t});\n\n\t\t\tthis.schedulingLog = undefined;\n\t\t}\n\n\t\t// If we scheduled this batch of the inbound queue, increment the counter that tracks the\n\t\t// number of times we have done this.\n\t\tthis.schedulingCount++;\n\n\t\t// Reset the processing times.\n\t\tthis.processingStartTime = undefined;\n\t\tthis.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;\n\t};\n\n\t/**\n\t * This function tells whether we should run the scheduler.\n\t */\n\tprivate shouldRunScheduler(): boolean {\n\t\t// If there are still ops in the queue after the one we are processing now, we should\n\t\t// run the scheduler.\n\t\treturn this.deltaManager.inbound.length > 0;\n\t}\n}\n"]}
|