@fluidframework/container-runtime 2.118.1 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -4
- package/README.md +53 -50
- package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
- package/api-report/container-runtime.legacy.alpha.api.md +3 -1
- package/api-report/container-runtime.legacy.beta.api.md +3 -1
- package/container-runtime.test-files.tar +0 -0
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +5 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager/blobManager.d.ts +1 -1
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +264 -231
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +70 -58
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.js +38 -20
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerCompatibility.d.ts +3 -3
- package/dist/containerCompatibility.d.ts.map +1 -1
- package/dist/containerCompatibility.js +36 -45
- package/dist/containerCompatibility.js.map +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +4 -0
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +4 -4
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +346 -223
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +9 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +184 -127
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.js +43 -42
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js +1 -0
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaManagerProxies.js +5 -0
- package/dist/deltaManagerProxies.js.map +1 -1
- package/dist/deltaScheduler.js +104 -99
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.js +2 -1
- package/dist/error.js.map +1 -1
- package/dist/gc/garbageCollection.js +85 -55
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.js +2 -3
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcHelpers.js +12 -13
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js +1 -2
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +8 -3
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.js +12 -5
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +18 -1
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/inboundBatchAggregator.js +122 -117
- package/dist/inboundBatchAggregator.js.map +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +3 -3
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +11 -5
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.js +18 -18
- package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +2 -2
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.js +2 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +10 -6
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +5 -3
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSerialization.d.ts +11 -1
- package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
- package/dist/opLifecycle/opSerialization.js +22 -6
- package/dist/opLifecycle/opSerialization.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +17 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +46 -9
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +17 -13
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +6 -3
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.d.ts.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.js +54 -47
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runCounter.js +10 -30
- package/dist/runCounter.js.map +1 -1
- package/dist/runtimeLayerCompatState.d.ts +1 -1
- package/dist/runtimeLayerCompatState.d.ts.map +1 -1
- package/dist/runtimeLayerCompatState.js +31 -11
- package/dist/runtimeLayerCompatState.js.map +1 -1
- package/dist/signalTelemetryProcessing.js +15 -17
- package/dist/signalTelemetryProcessing.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js +2 -0
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +51 -13
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/orderedClientElection.js +25 -17
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +18 -7
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +22 -13
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerUtils.d.ts.map +1 -1
- package/dist/summary/summarizerUtils.js +4 -3
- package/dist/summary/summarizerUtils.js.map +1 -1
- package/dist/summary/summaryCollection.js +23 -11
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.js +15 -6
- package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +7 -7
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryHelpers.js +5 -5
- package/dist/summary/summaryHelpers.js.map +1 -1
- package/dist/summary/summaryManager.js +66 -54
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/throttler.d.ts.map +1 -1
- package/dist/throttler.js +4 -1
- package/dist/throttler.js.map +1 -1
- package/dist/versionMarks/inboundBatch.d.ts +8 -6
- package/dist/versionMarks/inboundBatch.d.ts.map +1 -1
- package/dist/versionMarks/inboundBatch.js +11 -7
- package/dist/versionMarks/inboundBatch.js.map +1 -1
- package/dist/versionMarks/versionMarkResolver.d.ts +30 -23
- package/dist/versionMarks/versionMarkResolver.d.ts.map +1 -1
- package/dist/versionMarks/versionMarkResolver.js +112 -63
- package/dist/versionMarks/versionMarkResolver.js.map +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +5 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +1 -1
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +264 -231
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +65 -53
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.js +36 -18
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerCompatibility.d.ts +3 -3
- package/lib/containerCompatibility.d.ts.map +1 -1
- package/lib/containerCompatibility.js +33 -42
- package/lib/containerCompatibility.js.map +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +4 -0
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +4 -4
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +341 -218
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +9 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +182 -125
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.js +43 -42
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js +1 -0
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaManagerProxies.js +5 -0
- package/lib/deltaManagerProxies.js.map +1 -1
- package/lib/deltaScheduler.js +104 -99
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/error.js +2 -1
- package/lib/error.js.map +1 -1
- package/lib/gc/garbageCollection.js +85 -55
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +8 -3
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.js +12 -5
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +18 -1
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/inboundBatchAggregator.js +122 -117
- package/lib/inboundBatchAggregator.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/legacyAlpha.d.ts +1 -1
- package/lib/metadata.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +8 -2
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.js +18 -18
- package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +2 -2
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +2 -2
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.js +3 -2
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +10 -6
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +3 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSerialization.d.ts +11 -1
- package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
- package/lib/opLifecycle/opSerialization.js +16 -0
- package/lib/opLifecycle/opSerialization.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +17 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +44 -7
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +14 -10
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +4 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.d.ts.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.js +52 -45
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/runCounter.js +10 -30
- package/lib/runCounter.js.map +1 -1
- package/lib/runtimeLayerCompatState.d.ts +1 -1
- package/lib/runtimeLayerCompatState.d.ts.map +1 -1
- package/lib/runtimeLayerCompatState.js +28 -8
- package/lib/runtimeLayerCompatState.js.map +1 -1
- package/lib/signalTelemetryProcessing.js +15 -17
- package/lib/signalTelemetryProcessing.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js +2 -0
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +51 -13
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/orderedClientElection.js +25 -17
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +18 -7
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +22 -13
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerUtils.d.ts.map +1 -1
- package/lib/summary/summarizerUtils.js +1 -0
- package/lib/summary/summarizerUtils.js.map +1 -1
- package/lib/summary/summaryCollection.js +23 -11
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js +15 -6
- package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +66 -54
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/throttler.d.ts.map +1 -1
- package/lib/throttler.js +4 -1
- package/lib/throttler.js.map +1 -1
- package/lib/versionMarks/inboundBatch.d.ts +8 -6
- package/lib/versionMarks/inboundBatch.d.ts.map +1 -1
- package/lib/versionMarks/inboundBatch.js +10 -5
- package/lib/versionMarks/inboundBatch.js.map +1 -1
- package/lib/versionMarks/versionMarkResolver.d.ts +30 -23
- package/lib/versionMarks/versionMarkResolver.d.ts.map +1 -1
- package/lib/versionMarks/versionMarkResolver.js +112 -63
- package/lib/versionMarks/versionMarkResolver.js.map +1 -1
- package/package.json +60 -102
- package/src/containerCompatibility.ts +33 -42
- package/src/containerRuntime.ts +15 -12
- package/src/opLifecycle/index.ts +7 -1
- package/src/opLifecycle/opCompressor.ts +2 -2
- package/src/opLifecycle/opSerialization.ts +22 -1
- package/src/opLifecycle/opSplitter.ts +63 -6
- package/src/packageVersion.ts +1 -1
- package/src/runtimeLayerCompatState.ts +28 -21
- package/src/summary/documentSchema.ts +31 -6
- package/src/versionMarks/DEV.md +595 -157
- package/src/versionMarks/inboundBatch.ts +18 -8
- package/src/versionMarks/versionMarkResolver.ts +144 -75
- package/tsconfig.json +1 -1
- package/internal.d.ts +0 -11
- package/legacy/alpha.d.ts +0 -11
- package/legacy.d.ts +0 -11
- /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
- /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStoreRegistry.js","sourceRoot":"","sources":["../src/dataStoreRegistry.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAoE;AAMpE,uEAAsE;AAEtE;;GAEG;AACH,MAAa,sBAAsB;
|
|
1
|
+
{"version":3,"file":"dataStoreRegistry.js","sourceRoot":"","sources":["../src/dataStoreRegistry.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAoE;AAMpE,uEAAsE;AAEtE;;GAEG;AACH,MAAa,sBAAsB;IACjB,GAAG,CAGlB;IAEF,IAAW,uBAAuB;QACjC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,YAAY,YAAgD;QAC3D,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,qBAAU,CAAC,6BAA6B,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,IAAY;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAEM,OAAO,CAAC,IAAY;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AApCD,wDAoCC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { isPromiseLike } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tFluidDataStoreRegistryEntry,\n\tIFluidDataStoreRegistry,\n\tNamedFluidDataStoreRegistryEntries,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * @internal\n */\nexport class FluidDataStoreRegistry implements IFluidDataStoreRegistry {\n\tprivate readonly map: Map<\n\t\tstring,\n\t\tFluidDataStoreRegistryEntry | Promise<FluidDataStoreRegistryEntry>\n\t>;\n\n\tpublic get IFluidDataStoreRegistry(): IFluidDataStoreRegistry {\n\t\treturn this;\n\t}\n\n\tconstructor(namedEntries: NamedFluidDataStoreRegistryEntries) {\n\t\tthis.map = new Map();\n\t\tfor (const entry of namedEntries) {\n\t\t\tif (this.map.has(entry[0])) {\n\t\t\t\tthrow new UsageError(\"Duplicate entry names exist\");\n\t\t\t}\n\t\t\tthis.map.set(entry[0], entry[1]);\n\t\t}\n\t}\n\n\tpublic async get(name: string): Promise<FluidDataStoreRegistryEntry | undefined> {\n\t\tif (this.map.has(name)) {\n\t\t\treturn this.map.get(name);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic getSync(name: string): FluidDataStoreRegistryEntry | undefined {\n\t\tconst entry = this.map.get(name);\n\t\tif (!isPromiseLike(entry)) {\n\t\t\treturn entry;\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
@@ -14,6 +14,7 @@ const index_js_1 = require("./summary/index.js");
|
|
|
14
14
|
* of the DeltaManager.
|
|
15
15
|
*/
|
|
16
16
|
class BaseDeltaManagerProxy extends client_utils_1.TypedEventEmitter {
|
|
17
|
+
deltaManager;
|
|
17
18
|
get IDeltaSender() {
|
|
18
19
|
return this;
|
|
19
20
|
}
|
|
@@ -62,6 +63,7 @@ class BaseDeltaManagerProxy extends client_utils_1.TypedEventEmitter {
|
|
|
62
63
|
get readOnlyInfo() {
|
|
63
64
|
return this.deltaManager.readOnlyInfo;
|
|
64
65
|
}
|
|
66
|
+
eventHandlers;
|
|
65
67
|
constructor(deltaManager, overrides) {
|
|
66
68
|
super();
|
|
67
69
|
this.deltaManager = deltaManager;
|
|
@@ -123,6 +125,7 @@ exports.BaseDeltaManagerProxy = BaseDeltaManagerProxy;
|
|
|
123
125
|
* - Summarizer client should not be active to layers below the container runtime to restrict local changes.
|
|
124
126
|
*/
|
|
125
127
|
class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
|
|
128
|
+
deltaManager;
|
|
126
129
|
static wrapIfSummarizer(deltaManager) {
|
|
127
130
|
if (deltaManager.clientDetails.type === index_js_1.summarizerClientType) {
|
|
128
131
|
return new DeltaManagerSummarizerProxy(deltaManager);
|
|
@@ -152,6 +155,8 @@ class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
|
|
|
152
155
|
}
|
|
153
156
|
exports.DeltaManagerSummarizerProxy = DeltaManagerSummarizerProxy;
|
|
154
157
|
class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
|
|
158
|
+
deltaManager;
|
|
159
|
+
pendingStateManager;
|
|
155
160
|
get minimumSequenceNumber() {
|
|
156
161
|
const minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;
|
|
157
162
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deltaManagerProxies.js","sourceRoot":"","sources":["../src/deltaManagerProxies.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 type {\n\tIConnectionDetails,\n\tIDeltaManagerEvents,\n\tIDeltaManagerFull,\n\tIDeltaQueue,\n\tIDeltaSender,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { IErrorBase } from \"@fluidframework/core-interfaces\";\nimport type { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIAnyDriverError,\n\tIClientConfiguration,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport type { PendingStateManager } from \"./pendingStateManager.js\";\nimport { summarizerClientType } from \"./summary/index.js\";\n\n/**\n * Interface defining event handlers for the BaseDeltaManagerProxy.\n * These handlers allow customization of behavior for various DeltaManager events.\n */\nexport interface BaseDeltaManagerProxyEventHandlers {\n\t/**\n\t * Event handler triggered when the readonly state changes.\n\t * @param readonly - Indicates if the connection is readonly.\n\t * @param readonlyConnectionReason - Optional reason and error details for the readonly state.\n\t */\n\tonReadonly: (\n\t\treadonly: boolean,\n\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t) => void;\n\n\t/**\n\t * Event handler triggered before sending a message.\n\t * @param messageBuffer - The buffer of messages to be sent.\n\t */\n\tonPrepareSend: (messageBuffer: unknown[]) => void;\n\n\t/**\n\t * Event handler triggered when an operation is submitted.\n\t * @param message - The document message being submitted.\n\t */\n\tonSubmitOp: (message: IDocumentMessage) => void;\n\n\t/**\n\t * Event handler triggered when an operation is received.\n\t * @param message - The sequenced document message received.\n\t * @param processingTime - The time taken to process the message.\n\t */\n\tonOp: (message: ISequencedDocumentMessage, processingTime: number) => void;\n\n\t/**\n\t * Event handler triggered when a pong response is received.\n\t * @param latency - The latency of the pong response.\n\t */\n\tonPong: (latency: number) => void;\n\n\t/**\n\t * Event handler triggered when a connection is established.\n\t * @param details - The connection details.\n\t * @param opsBehind - Optional number of operations behind the latest state.\n\t */\n\tonConnect: (details: IConnectionDetails, opsBehind?: number) => void;\n\n\t/**\n\t * Event handler triggered when a disconnection occurs.\n\t * @param reason - The reason for the disconnection.\n\t * @param error - Optional error details for the disconnection.\n\t */\n\tonDisconnect: (reason: string, error?: IAnyDriverError) => void;\n}\n\n/**\n * Base class for DeltaManager proxy that proxy's access to the real DeltaManager.\n *\n * This class allows us to build proxy functionality without actually having to implement all the methods\n * of the DeltaManager.\n */\nexport class BaseDeltaManagerProxy\n\textends TypedEventEmitter<IDeltaManagerEvents>\n\timplements IDeltaManagerFull\n{\n\tpublic get IDeltaSender(): IDeltaSender {\n\t\treturn this;\n\t}\n\n\tpublic get inbound(): IDeltaQueue<ISequencedDocumentMessage> {\n\t\treturn this.deltaManager.inbound;\n\t}\n\n\tpublic get outbound(): IDeltaQueue<IDocumentMessage[]> {\n\t\treturn this.deltaManager.outbound;\n\t}\n\n\tpublic get inboundSignal(): IDeltaQueue<ISignalMessage> {\n\t\treturn this.deltaManager.inboundSignal;\n\t}\n\n\tpublic get minimumSequenceNumber(): number {\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastSequenceNumber(): number {\n\t\treturn this.deltaManager.lastSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\treturn this.deltaManager.lastMessage;\n\t}\n\n\tpublic get lastKnownSeqNumber(): number {\n\t\treturn this.deltaManager.lastKnownSeqNumber;\n\t}\n\n\tpublic get initialSequenceNumber(): number {\n\t\treturn this.deltaManager.initialSequenceNumber;\n\t}\n\n\tpublic get hasCheckpointSequenceNumber(): boolean {\n\t\treturn this.deltaManager.hasCheckpointSequenceNumber;\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.deltaManager.clientDetails;\n\t}\n\n\tpublic get version(): string {\n\t\treturn this.deltaManager.version;\n\t}\n\n\tpublic get maxMessageSize(): number {\n\t\treturn this.deltaManager.maxMessageSize;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.deltaManager.serviceConfiguration;\n\t}\n\n\tpublic get active(): boolean {\n\t\treturn this.deltaManager.active;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\treturn this.deltaManager.readOnlyInfo;\n\t}\n\n\tprivate readonly eventHandlers: BaseDeltaManagerProxyEventHandlers;\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\toverrides?: Partial<BaseDeltaManagerProxyEventHandlers>,\n\t) {\n\t\tsuper();\n\n\t\tthis.eventHandlers = {\n\t\t\tonPrepareSend: (messageBuffer: unknown[]): void => {\n\t\t\t\tthis.emit(\"prepareSend\", messageBuffer);\n\t\t\t},\n\t\t\tonSubmitOp: (message: IDocumentMessage): void => {\n\t\t\t\tthis.emit(\"submitOp\", message);\n\t\t\t},\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tthis.emit(\"op\", message, processingTime);\n\t\t\t},\n\t\t\tonPong: (latency: number): void => {\n\t\t\t\tthis.emit(\"pong\", latency);\n\t\t\t},\n\t\t\tonConnect: (details: IConnectionDetails, opsBehind?: number): void => {\n\t\t\t\tthis.emit(\"connect\", details, opsBehind);\n\t\t\t},\n\t\t\tonDisconnect: (reason: string, error?: IAnyDriverError): void => {\n\t\t\t\tthis.emit(\"disconnect\", reason, error);\n\t\t\t},\n\t\t\tonReadonly: (\n\t\t\t\treadonly: boolean,\n\t\t\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t\t\t): void => {\n\t\t\t\tthis.emit(\"readonly\", readonly, readonlyConnectionReason);\n\t\t\t},\n\n\t\t\t...overrides,\n\t\t};\n\n\t\t// We are expecting this class to have many listeners, so we suppress noisy \"MaxListenersExceededWarning\" logging.\n\t\tsuper.setMaxListeners(0);\n\n\t\tthis.deltaManager.on(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.on(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.on(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.on(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.on(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.on(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.on(\"readonly\", this.eventHandlers.onReadonly);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.off(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.off(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.off(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.off(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.off(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.off(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.off(\"readonly\", this.eventHandlers.onReadonly);\n\t\tthis.removeAllListeners();\n\t}\n\n\tpublic submitSignal(content: string, targetClientId?: string): void {\n\t\treturn this.deltaManager.submitSignal(content, targetClientId);\n\t}\n\n\tpublic flush(): void {\n\t\treturn this.deltaManager.flush();\n\t}\n}\n\n/**\n * Proxy to the real IDeltaManager for restricting certain access to layers below container runtime in summarizer clients:\n * - Summarizer client should be read-only to layers below the container runtime to restrict local changes.\n * - Summarizer client should not be active to layers below the container runtime to restrict local changes.\n */\nexport class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {\n\tpublic static wrapIfSummarizer(deltaManager: IDeltaManagerFull): IDeltaManagerFull {\n\t\tif (deltaManager.clientDetails.type === summarizerClientType) {\n\t\t\treturn new DeltaManagerSummarizerProxy(deltaManager);\n\t\t}\n\t\treturn deltaManager;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/class-literal-property-style\n\tpublic get active(): boolean {\n\t\t// Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer\n\t\t// except for the SummarizeOp which is generated by the runtime.\n\t\treturn false;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\t// Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't\n\t\t// be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.\n\n\t\treturn {\n\t\t\treadonly: true,\n\t\t\tforced: false,\n\t\t\tpermissions: undefined,\n\t\t\tstorageOnly: false,\n\t\t};\n\t}\n\n\tconstructor(protected readonly deltaManager: IDeltaManagerFull) {\n\t\tsuper(deltaManager, { onReadonly: () => {} });\n\t}\n}\n\nexport class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {\n\tpublic get minimumSequenceNumber(): number {\n\t\tconst minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;\n\t\t/**\n\t\t * The reason why the minimum pending sequence number can be less than the delta manager's minimum sequence\n\t\t * number (DM's msn) is that when we are processing messages in the container runtime/delta manager, the delta\n\t\t * manager's msn can be updated to continually increase. In the meantime, the pending state manager's op which\n\t\t * hasn't been sent can still have a lower sequence number than the DM's msn (think about a disconnected\n\t\t * scenario). To successfully resubmit that pending op it has to be rebased first by the DDS. The DDS still\n\t\t * needs to keep the local data for that op that has a reference sequence number lower than the DM's msn. To\n\t\t * achieve this, the msn passed to the DDS needs to be the minimum of the DM's msn and the minimum pending\n\t\t * sequence number, so that it can keep the relevant local data to generate the right data for the new op\n\t\t * during resubmission.\n\t\t */\n\t\tif (\n\t\t\tminPendingSeqNum !== undefined &&\n\t\t\tminPendingSeqNum < this.deltaManager.minimumSequenceNumber\n\t\t) {\n\t\t\treturn minPendingSeqNum;\n\t\t}\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\tif (this.deltaManager.lastMessage === undefined) {\n\t\t\treturn this.deltaManager.lastMessage;\n\t\t}\n\t\treturn {\n\t\t\t...this.deltaManager.lastMessage,\n\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t};\n\t}\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly pendingStateManager: Pick<\n\t\t\tPendingStateManager,\n\t\t\t\"minimumPendingMessageSequenceNumber\"\n\t\t>,\n\t) {\n\t\tsuper(deltaManager, {\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tconst messageIntercept = {\n\t\t\t\t\t...message,\n\t\t\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t\t\t};\n\t\t\t\tthis.emit(\"op\", messageIntercept, processingTime);\n\t\t\t},\n\t\t});\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"deltaManagerProxies.js","sourceRoot":"","sources":["../src/deltaManagerProxies.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 type {\n\tIConnectionDetails,\n\tIDeltaManagerEvents,\n\tIDeltaManagerFull,\n\tIDeltaQueue,\n\tIDeltaSender,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { IErrorBase } from \"@fluidframework/core-interfaces\";\nimport type { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIAnyDriverError,\n\tIClientConfiguration,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport type { PendingStateManager } from \"./pendingStateManager.js\";\nimport { summarizerClientType } from \"./summary/index.js\";\n\n/**\n * Interface defining event handlers for the BaseDeltaManagerProxy.\n * These handlers allow customization of behavior for various DeltaManager events.\n */\nexport interface BaseDeltaManagerProxyEventHandlers {\n\t/**\n\t * Event handler triggered when the readonly state changes.\n\t * @param readonly - Indicates if the connection is readonly.\n\t * @param readonlyConnectionReason - Optional reason and error details for the readonly state.\n\t */\n\tonReadonly: (\n\t\treadonly: boolean,\n\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t) => void;\n\n\t/**\n\t * Event handler triggered before sending a message.\n\t * @param messageBuffer - The buffer of messages to be sent.\n\t */\n\tonPrepareSend: (messageBuffer: unknown[]) => void;\n\n\t/**\n\t * Event handler triggered when an operation is submitted.\n\t * @param message - The document message being submitted.\n\t */\n\tonSubmitOp: (message: IDocumentMessage) => void;\n\n\t/**\n\t * Event handler triggered when an operation is received.\n\t * @param message - The sequenced document message received.\n\t * @param processingTime - The time taken to process the message.\n\t */\n\tonOp: (message: ISequencedDocumentMessage, processingTime: number) => void;\n\n\t/**\n\t * Event handler triggered when a pong response is received.\n\t * @param latency - The latency of the pong response.\n\t */\n\tonPong: (latency: number) => void;\n\n\t/**\n\t * Event handler triggered when a connection is established.\n\t * @param details - The connection details.\n\t * @param opsBehind - Optional number of operations behind the latest state.\n\t */\n\tonConnect: (details: IConnectionDetails, opsBehind?: number) => void;\n\n\t/**\n\t * Event handler triggered when a disconnection occurs.\n\t * @param reason - The reason for the disconnection.\n\t * @param error - Optional error details for the disconnection.\n\t */\n\tonDisconnect: (reason: string, error?: IAnyDriverError) => void;\n}\n\n/**\n * Base class for DeltaManager proxy that proxy's access to the real DeltaManager.\n *\n * This class allows us to build proxy functionality without actually having to implement all the methods\n * of the DeltaManager.\n */\nexport class BaseDeltaManagerProxy\n\textends TypedEventEmitter<IDeltaManagerEvents>\n\timplements IDeltaManagerFull\n{\n\tpublic get IDeltaSender(): IDeltaSender {\n\t\treturn this;\n\t}\n\n\tpublic get inbound(): IDeltaQueue<ISequencedDocumentMessage> {\n\t\treturn this.deltaManager.inbound;\n\t}\n\n\tpublic get outbound(): IDeltaQueue<IDocumentMessage[]> {\n\t\treturn this.deltaManager.outbound;\n\t}\n\n\tpublic get inboundSignal(): IDeltaQueue<ISignalMessage> {\n\t\treturn this.deltaManager.inboundSignal;\n\t}\n\n\tpublic get minimumSequenceNumber(): number {\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastSequenceNumber(): number {\n\t\treturn this.deltaManager.lastSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\treturn this.deltaManager.lastMessage;\n\t}\n\n\tpublic get lastKnownSeqNumber(): number {\n\t\treturn this.deltaManager.lastKnownSeqNumber;\n\t}\n\n\tpublic get initialSequenceNumber(): number {\n\t\treturn this.deltaManager.initialSequenceNumber;\n\t}\n\n\tpublic get hasCheckpointSequenceNumber(): boolean {\n\t\treturn this.deltaManager.hasCheckpointSequenceNumber;\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.deltaManager.clientDetails;\n\t}\n\n\tpublic get version(): string {\n\t\treturn this.deltaManager.version;\n\t}\n\n\tpublic get maxMessageSize(): number {\n\t\treturn this.deltaManager.maxMessageSize;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.deltaManager.serviceConfiguration;\n\t}\n\n\tpublic get active(): boolean {\n\t\treturn this.deltaManager.active;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\treturn this.deltaManager.readOnlyInfo;\n\t}\n\n\tprivate readonly eventHandlers: BaseDeltaManagerProxyEventHandlers;\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\toverrides?: Partial<BaseDeltaManagerProxyEventHandlers>,\n\t) {\n\t\tsuper();\n\n\t\tthis.eventHandlers = {\n\t\t\tonPrepareSend: (messageBuffer: unknown[]): void => {\n\t\t\t\tthis.emit(\"prepareSend\", messageBuffer);\n\t\t\t},\n\t\t\tonSubmitOp: (message: IDocumentMessage): void => {\n\t\t\t\tthis.emit(\"submitOp\", message);\n\t\t\t},\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tthis.emit(\"op\", message, processingTime);\n\t\t\t},\n\t\t\tonPong: (latency: number): void => {\n\t\t\t\tthis.emit(\"pong\", latency);\n\t\t\t},\n\t\t\tonConnect: (details: IConnectionDetails, opsBehind?: number): void => {\n\t\t\t\tthis.emit(\"connect\", details, opsBehind);\n\t\t\t},\n\t\t\tonDisconnect: (reason: string, error?: IAnyDriverError): void => {\n\t\t\t\tthis.emit(\"disconnect\", reason, error);\n\t\t\t},\n\t\t\tonReadonly: (\n\t\t\t\treadonly: boolean,\n\t\t\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t\t\t): void => {\n\t\t\t\tthis.emit(\"readonly\", readonly, readonlyConnectionReason);\n\t\t\t},\n\n\t\t\t...overrides,\n\t\t};\n\n\t\t// We are expecting this class to have many listeners, so we suppress noisy \"MaxListenersExceededWarning\" logging.\n\t\tsuper.setMaxListeners(0);\n\n\t\tthis.deltaManager.on(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.on(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.on(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.on(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.on(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.on(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.on(\"readonly\", this.eventHandlers.onReadonly);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.off(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.off(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.off(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.off(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.off(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.off(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.off(\"readonly\", this.eventHandlers.onReadonly);\n\t\tthis.removeAllListeners();\n\t}\n\n\tpublic submitSignal(content: string, targetClientId?: string): void {\n\t\treturn this.deltaManager.submitSignal(content, targetClientId);\n\t}\n\n\tpublic flush(): void {\n\t\treturn this.deltaManager.flush();\n\t}\n}\n\n/**\n * Proxy to the real IDeltaManager for restricting certain access to layers below container runtime in summarizer clients:\n * - Summarizer client should be read-only to layers below the container runtime to restrict local changes.\n * - Summarizer client should not be active to layers below the container runtime to restrict local changes.\n */\nexport class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {\n\tpublic static wrapIfSummarizer(deltaManager: IDeltaManagerFull): IDeltaManagerFull {\n\t\tif (deltaManager.clientDetails.type === summarizerClientType) {\n\t\t\treturn new DeltaManagerSummarizerProxy(deltaManager);\n\t\t}\n\t\treturn deltaManager;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/class-literal-property-style\n\tpublic get active(): boolean {\n\t\t// Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer\n\t\t// except for the SummarizeOp which is generated by the runtime.\n\t\treturn false;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\t// Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't\n\t\t// be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.\n\n\t\treturn {\n\t\t\treadonly: true,\n\t\t\tforced: false,\n\t\t\tpermissions: undefined,\n\t\t\tstorageOnly: false,\n\t\t};\n\t}\n\n\tconstructor(protected readonly deltaManager: IDeltaManagerFull) {\n\t\tsuper(deltaManager, { onReadonly: () => {} });\n\t}\n}\n\nexport class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {\n\tpublic get minimumSequenceNumber(): number {\n\t\tconst minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;\n\t\t/**\n\t\t * The reason why the minimum pending sequence number can be less than the delta manager's minimum sequence\n\t\t * number (DM's msn) is that when we are processing messages in the container runtime/delta manager, the delta\n\t\t * manager's msn can be updated to continually increase. In the meantime, the pending state manager's op which\n\t\t * hasn't been sent can still have a lower sequence number than the DM's msn (think about a disconnected\n\t\t * scenario). To successfully resubmit that pending op it has to be rebased first by the DDS. The DDS still\n\t\t * needs to keep the local data for that op that has a reference sequence number lower than the DM's msn. To\n\t\t * achieve this, the msn passed to the DDS needs to be the minimum of the DM's msn and the minimum pending\n\t\t * sequence number, so that it can keep the relevant local data to generate the right data for the new op\n\t\t * during resubmission.\n\t\t */\n\t\tif (\n\t\t\tminPendingSeqNum !== undefined &&\n\t\t\tminPendingSeqNum < this.deltaManager.minimumSequenceNumber\n\t\t) {\n\t\t\treturn minPendingSeqNum;\n\t\t}\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\tif (this.deltaManager.lastMessage === undefined) {\n\t\t\treturn this.deltaManager.lastMessage;\n\t\t}\n\t\treturn {\n\t\t\t...this.deltaManager.lastMessage,\n\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t};\n\t}\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly pendingStateManager: Pick<\n\t\t\tPendingStateManager,\n\t\t\t\"minimumPendingMessageSequenceNumber\"\n\t\t>,\n\t) {\n\t\tsuper(deltaManager, {\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tconst messageIntercept = {\n\t\t\t\t\t...message,\n\t\t\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t\t\t};\n\t\t\t\tthis.emit(\"op\", messageIntercept, processingTime);\n\t\t\t},\n\t\t});\n\t}\n}\n"]}
|
package/dist/deltaScheduler.js
CHANGED
|
@@ -21,107 +21,24 @@ const internal_1 = require("@fluidframework/telemetry-utils/internal");
|
|
|
21
21
|
* processed, the time and number of turns it took to process the ops.
|
|
22
22
|
*/
|
|
23
23
|
class DeltaScheduler {
|
|
24
|
+
deltaManager;
|
|
25
|
+
runtimeEventsEmitter;
|
|
26
|
+
logger;
|
|
27
|
+
// The time for processing ops in a single turn.
|
|
28
|
+
static processingTime = 50;
|
|
29
|
+
// The increase in time for processing ops after each turn.
|
|
30
|
+
processingTimeIncrement = 10;
|
|
31
|
+
processingStartTime;
|
|
32
|
+
currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
|
|
33
|
+
// This keeps track of the number of times inbound queue has been scheduled. After a particular
|
|
34
|
+
// count, we log telemetry for the number of ops processed, the time and number of turns it took
|
|
35
|
+
// to process the ops.
|
|
36
|
+
schedulingCount = 0;
|
|
37
|
+
schedulingLog;
|
|
24
38
|
constructor(deltaManager, runtimeEventsEmitter, logger) {
|
|
25
39
|
this.deltaManager = deltaManager;
|
|
26
40
|
this.runtimeEventsEmitter = runtimeEventsEmitter;
|
|
27
41
|
this.logger = logger;
|
|
28
|
-
// The increase in time for processing ops after each turn.
|
|
29
|
-
this.processingTimeIncrement = 10;
|
|
30
|
-
this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
|
|
31
|
-
// This keeps track of the number of times inbound queue has been scheduled. After a particular
|
|
32
|
-
// count, we log telemetry for the number of ops processed, the time and number of turns it took
|
|
33
|
-
// to process the ops.
|
|
34
|
-
this.schedulingCount = 0;
|
|
35
|
-
this.batchBegin = (message) => {
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
|
|
37
|
-
if (this.processingStartTime === undefined) {
|
|
38
|
-
this.processingStartTime = (0, client_utils_1.performanceNow)();
|
|
39
|
-
}
|
|
40
|
-
if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
|
|
41
|
-
// Every 500th time we are scheduling the inbound queue, we log telemetry for the
|
|
42
|
-
// number of ops processed, the time and number of turns it took to process the ops.
|
|
43
|
-
this.schedulingLog = {
|
|
44
|
-
opsRemainingToProcess: 0,
|
|
45
|
-
numberOfTurns: 1,
|
|
46
|
-
totalProcessingTime: 0,
|
|
47
|
-
numberOfBatchesProcessed: 0,
|
|
48
|
-
firstSequenceNumber: message.sequenceNumber,
|
|
49
|
-
lastSequenceNumber: message.sequenceNumber,
|
|
50
|
-
startTime: (0, client_utils_1.performanceNow)(),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
this.batchEnd = (error, message) => {
|
|
55
|
-
if (this.schedulingLog) {
|
|
56
|
-
this.schedulingLog.numberOfBatchesProcessed++;
|
|
57
|
-
this.schedulingLog.lastSequenceNumber = message.sequenceNumber;
|
|
58
|
-
this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
|
|
59
|
-
}
|
|
60
|
-
if (this.shouldRunScheduler()) {
|
|
61
|
-
const currentTime = (0, client_utils_1.performanceNow)();
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
63
|
-
const elapsedTime = currentTime - this.processingStartTime;
|
|
64
|
-
if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
|
|
65
|
-
// We have processed ops for more than the total processing time. So, pause the
|
|
66
|
-
// queue, yield the thread and schedule a resume.
|
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
68
|
-
this.deltaManager.inbound.pause();
|
|
69
|
-
// Increase the total processing time. Keep doing this after each turn until all the ops have
|
|
70
|
-
// been processed. This way we keep the responsiveness at the beginning while also making sure
|
|
71
|
-
// that all the ops process fairly quickly.
|
|
72
|
-
this.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;
|
|
73
|
-
// If we are logging the telemetry this time, update the telemetry log object.
|
|
74
|
-
if (this.schedulingLog) {
|
|
75
|
-
this.schedulingLog.numberOfTurns++;
|
|
76
|
-
this.schedulingLog.totalProcessingTime += elapsedTime;
|
|
77
|
-
}
|
|
78
|
-
setTimeout(() => {
|
|
79
|
-
if (this.schedulingLog) {
|
|
80
|
-
this.logger.sendTelemetryEvent({
|
|
81
|
-
eventName: "InboundOpsPartialProcessingTime",
|
|
82
|
-
duration: (0, internal_1.formatTick)(elapsedTime),
|
|
83
|
-
opsProcessed: this.schedulingLog.lastSequenceNumber -
|
|
84
|
-
this.schedulingLog.firstSequenceNumber +
|
|
85
|
-
1,
|
|
86
|
-
opsRemainingToProcess: this.deltaManager.inbound.length,
|
|
87
|
-
processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
|
|
88
|
-
numberOfTurns: this.schedulingLog.numberOfTurns,
|
|
89
|
-
batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
|
|
90
|
-
timeToResume: (0, internal_1.formatTick)((0, client_utils_1.performanceNow)() - currentTime),
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
this.deltaManager.inbound.resume();
|
|
94
|
-
});
|
|
95
|
-
this.processingStartTime = undefined;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
this.inboundQueueIdle = () => {
|
|
100
|
-
if (this.schedulingLog) {
|
|
101
|
-
// Add the time taken for processing the final ops to the total processing time in the
|
|
102
|
-
// telemetry log object.
|
|
103
|
-
const currentTime = (0, client_utils_1.performanceNow)();
|
|
104
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
105
|
-
this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
|
|
106
|
-
this.logger.sendTelemetryEvent({
|
|
107
|
-
eventName: "InboundOpsProcessingTime",
|
|
108
|
-
opsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,
|
|
109
|
-
numberOfTurns: this.schedulingLog.numberOfTurns,
|
|
110
|
-
processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
|
|
111
|
-
opsProcessed: this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
|
|
112
|
-
batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
|
|
113
|
-
duration: (0, internal_1.formatTick)(currentTime - this.schedulingLog.startTime),
|
|
114
|
-
schedulingCount: this.schedulingCount,
|
|
115
|
-
});
|
|
116
|
-
this.schedulingLog = undefined;
|
|
117
|
-
}
|
|
118
|
-
// If we scheduled this batch of the inbound queue, increment the counter that tracks the
|
|
119
|
-
// number of times we have done this.
|
|
120
|
-
this.schedulingCount++;
|
|
121
|
-
// Reset the processing times.
|
|
122
|
-
this.processingStartTime = undefined;
|
|
123
|
-
this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
|
|
124
|
-
};
|
|
125
42
|
this.deltaManager.inbound.on("idle", this.inboundQueueIdle);
|
|
126
43
|
runtimeEventsEmitter.on("batchBegin", this.batchBegin);
|
|
127
44
|
runtimeEventsEmitter.on("batchEnd", this.batchEnd);
|
|
@@ -131,6 +48,96 @@ class DeltaScheduler {
|
|
|
131
48
|
this.runtimeEventsEmitter.off("batchBegin", this.batchBegin);
|
|
132
49
|
this.runtimeEventsEmitter.off("batchEnd", this.batchEnd);
|
|
133
50
|
}
|
|
51
|
+
batchBegin = (message) => {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
|
|
53
|
+
if (this.processingStartTime === undefined) {
|
|
54
|
+
this.processingStartTime = (0, client_utils_1.performanceNow)();
|
|
55
|
+
}
|
|
56
|
+
if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
|
|
57
|
+
// Every 500th time we are scheduling the inbound queue, we log telemetry for the
|
|
58
|
+
// number of ops processed, the time and number of turns it took to process the ops.
|
|
59
|
+
this.schedulingLog = {
|
|
60
|
+
opsRemainingToProcess: 0,
|
|
61
|
+
numberOfTurns: 1,
|
|
62
|
+
totalProcessingTime: 0,
|
|
63
|
+
numberOfBatchesProcessed: 0,
|
|
64
|
+
firstSequenceNumber: message.sequenceNumber,
|
|
65
|
+
lastSequenceNumber: message.sequenceNumber,
|
|
66
|
+
startTime: (0, client_utils_1.performanceNow)(),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
batchEnd = (error, message) => {
|
|
71
|
+
if (this.schedulingLog) {
|
|
72
|
+
this.schedulingLog.numberOfBatchesProcessed++;
|
|
73
|
+
this.schedulingLog.lastSequenceNumber = message.sequenceNumber;
|
|
74
|
+
this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
|
|
75
|
+
}
|
|
76
|
+
if (this.shouldRunScheduler()) {
|
|
77
|
+
const currentTime = (0, client_utils_1.performanceNow)();
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
79
|
+
const elapsedTime = currentTime - this.processingStartTime;
|
|
80
|
+
if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
|
|
81
|
+
// We have processed ops for more than the total processing time. So, pause the
|
|
82
|
+
// queue, yield the thread and schedule a resume.
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
84
|
+
this.deltaManager.inbound.pause();
|
|
85
|
+
// Increase the total processing time. Keep doing this after each turn until all the ops have
|
|
86
|
+
// been processed. This way we keep the responsiveness at the beginning while also making sure
|
|
87
|
+
// that all the ops process fairly quickly.
|
|
88
|
+
this.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;
|
|
89
|
+
// If we are logging the telemetry this time, update the telemetry log object.
|
|
90
|
+
if (this.schedulingLog) {
|
|
91
|
+
this.schedulingLog.numberOfTurns++;
|
|
92
|
+
this.schedulingLog.totalProcessingTime += elapsedTime;
|
|
93
|
+
}
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
if (this.schedulingLog) {
|
|
96
|
+
this.logger.sendTelemetryEvent({
|
|
97
|
+
eventName: "InboundOpsPartialProcessingTime",
|
|
98
|
+
duration: (0, internal_1.formatTick)(elapsedTime),
|
|
99
|
+
opsProcessed: this.schedulingLog.lastSequenceNumber -
|
|
100
|
+
this.schedulingLog.firstSequenceNumber +
|
|
101
|
+
1,
|
|
102
|
+
opsRemainingToProcess: this.deltaManager.inbound.length,
|
|
103
|
+
processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
|
|
104
|
+
numberOfTurns: this.schedulingLog.numberOfTurns,
|
|
105
|
+
batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
|
|
106
|
+
timeToResume: (0, internal_1.formatTick)((0, client_utils_1.performanceNow)() - currentTime),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
this.deltaManager.inbound.resume();
|
|
110
|
+
});
|
|
111
|
+
this.processingStartTime = undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
inboundQueueIdle = () => {
|
|
116
|
+
if (this.schedulingLog) {
|
|
117
|
+
// Add the time taken for processing the final ops to the total processing time in the
|
|
118
|
+
// telemetry log object.
|
|
119
|
+
const currentTime = (0, client_utils_1.performanceNow)();
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
121
|
+
this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
|
|
122
|
+
this.logger.sendTelemetryEvent({
|
|
123
|
+
eventName: "InboundOpsProcessingTime",
|
|
124
|
+
opsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,
|
|
125
|
+
numberOfTurns: this.schedulingLog.numberOfTurns,
|
|
126
|
+
processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
|
|
127
|
+
opsProcessed: this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
|
|
128
|
+
batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
|
|
129
|
+
duration: (0, internal_1.formatTick)(currentTime - this.schedulingLog.startTime),
|
|
130
|
+
schedulingCount: this.schedulingCount,
|
|
131
|
+
});
|
|
132
|
+
this.schedulingLog = undefined;
|
|
133
|
+
}
|
|
134
|
+
// If we scheduled this batch of the inbound queue, increment the counter that tracks the
|
|
135
|
+
// number of times we have done this.
|
|
136
|
+
this.schedulingCount++;
|
|
137
|
+
// Reset the processing times.
|
|
138
|
+
this.processingStartTime = undefined;
|
|
139
|
+
this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
|
|
140
|
+
};
|
|
134
141
|
/**
|
|
135
142
|
* This function tells whether we should run the scheduler.
|
|
136
143
|
*/
|
|
@@ -141,6 +148,4 @@ class DeltaScheduler {
|
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
exports.DeltaScheduler = DeltaScheduler;
|
|
144
|
-
// The time for processing ops in a single turn.
|
|
145
|
-
DeltaScheduler.processingTime = 50;
|
|
146
151
|
//# sourceMappingURL=deltaScheduler.js.map
|
|
@@ -1 +1 @@
|
|
|
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 type { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IContainerRuntimeBaseEvents } from \"@fluidframework/runtime-definitions/internal\";\nimport { formatTick, type TelemetryLoggerExt } 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: TelemetryLoggerExt,\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\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\tif (this.processingStartTime === undefined) {\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"]}
|
|
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 type { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IContainerRuntimeBaseEvents } from \"@fluidframework/runtime-definitions/internal\";\nimport { formatTick, type TelemetryLoggerExt } 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: TelemetryLoggerExt,\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\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\tif (this.processingStartTime === undefined) {\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"]}
|
package/dist/error.js
CHANGED
|
@@ -11,10 +11,11 @@ const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
|
11
11
|
* Error indicating that a client's session has reached its time limit and is closed.
|
|
12
12
|
*/
|
|
13
13
|
class ClientSessionExpiredError extends internal_2.LoggingError {
|
|
14
|
+
expiryMs;
|
|
15
|
+
errorType = internal_1.ContainerErrorTypes.clientSessionExpiredError;
|
|
14
16
|
constructor(message, expiryMs) {
|
|
15
17
|
super(message, { timeoutMs: expiryMs });
|
|
16
18
|
this.expiryMs = expiryMs;
|
|
17
|
-
this.errorType = internal_1.ContainerErrorTypes.clientSessionExpiredError;
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
exports.ClientSessionExpiredError = ClientSessionExpiredError;
|
package/dist/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAAqF;AACrF,uEAA8F;AAE9F;;GAEG;AACH,MAAa,yBAA0B,SAAQ,uBAAY;
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAAqF;AACrF,uEAA8F;AAE9F;;GAEG;AACH,MAAa,yBAA0B,SAAQ,uBAAY;IAKhD;IAJD,SAAS,GAAG,8BAAmB,CAAC,yBAAyB,CAAC;IAEnE,YACC,OAAe,EACN,QAAgB;QAEzB,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAF/B,aAAQ,GAAR,QAAQ,CAAQ;IAG1B,CAAC;CACD;AATD,8DASC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ContainerErrorTypes } from \"@fluidframework/container-definitions/internal\";\nimport { type IFluidErrorBase, LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * Error indicating that a client's session has reached its time limit and is closed.\n */\nexport class ClientSessionExpiredError extends LoggingError implements IFluidErrorBase {\n\treadonly errorType = ContainerErrorTypes.clientSessionExpiredError;\n\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly expiryMs: number,\n\t) {\n\t\tsuper(message, { timeoutMs: expiryMs });\n\t}\n}\n"]}
|
|
@@ -46,12 +46,57 @@ class GarbageCollector {
|
|
|
46
46
|
static create(createParams) {
|
|
47
47
|
return new GarbageCollector(createParams);
|
|
48
48
|
}
|
|
49
|
+
mc;
|
|
50
|
+
configs;
|
|
49
51
|
get serializedConfigs() {
|
|
50
52
|
return JSON.stringify(this.configs);
|
|
51
53
|
}
|
|
52
54
|
get shouldRunGC() {
|
|
53
55
|
return this.configs.gcAllowed;
|
|
54
56
|
}
|
|
57
|
+
sessionExpiryTimerStarted;
|
|
58
|
+
// Keeps track of the GC state from the last run.
|
|
59
|
+
gcDataFromLastRun;
|
|
60
|
+
// Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
|
|
61
|
+
// outbound routes from that node.
|
|
62
|
+
newReferencesSinceLastRun = new Map();
|
|
63
|
+
// A list of nodes that have been tombstoned.
|
|
64
|
+
tombstones = [];
|
|
65
|
+
// A list of nodes that have been deleted during sweep phase.
|
|
66
|
+
deletedNodes = new Set();
|
|
67
|
+
// Promise when resolved returns the GC data data in the base snapshot.
|
|
68
|
+
baseSnapshotDataP;
|
|
69
|
+
// Promise when resolved initializes the GC state from the data in the base snapshot.
|
|
70
|
+
initializeGCStateFromBaseSnapshotP;
|
|
71
|
+
// The GC details generated from the base snapshot.
|
|
72
|
+
baseGCDetailsP;
|
|
73
|
+
/**
|
|
74
|
+
* Map of node ids to their unreferenced state tracker
|
|
75
|
+
* NOTE: The set of keys in this map is considered as the set of unreferenced nodes
|
|
76
|
+
* as of the last GC run. So in between runs, nothing should be added or removed.
|
|
77
|
+
*/
|
|
78
|
+
unreferencedNodesState = new gcUnreferencedStateTracker_js_1.UnreferencedStateTrackerMap();
|
|
79
|
+
// The Timer responsible for closing the container when the session has expired
|
|
80
|
+
sessionExpiryTimer;
|
|
81
|
+
// The number of times GC has successfully completed on this instance of GarbageCollector.
|
|
82
|
+
completedRuns = 0;
|
|
83
|
+
runtime;
|
|
84
|
+
/**
|
|
85
|
+
* Called when the runtime should close because of an error.
|
|
86
|
+
*/
|
|
87
|
+
closeFn;
|
|
88
|
+
isSummarizerClient;
|
|
89
|
+
summaryStateTracker;
|
|
90
|
+
telemetryTracker;
|
|
91
|
+
/**
|
|
92
|
+
* For a given node path, returns the node's package path.
|
|
93
|
+
*/
|
|
94
|
+
getNodePackagePath;
|
|
95
|
+
/**
|
|
96
|
+
* Returns the timestamp of the last summary generated for this container.
|
|
97
|
+
*/
|
|
98
|
+
getLastSummaryTimestampMs;
|
|
99
|
+
submitMessage;
|
|
55
100
|
/**
|
|
56
101
|
* Returns the count of data stores whose GC state updated since the last summary.
|
|
57
102
|
*/
|
|
@@ -59,61 +104,6 @@ class GarbageCollector {
|
|
|
59
104
|
return this.summaryStateTracker.updatedDSCountSinceLastSummary;
|
|
60
105
|
}
|
|
61
106
|
constructor(createParams) {
|
|
62
|
-
// Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
|
|
63
|
-
// outbound routes from that node.
|
|
64
|
-
this.newReferencesSinceLastRun = new Map();
|
|
65
|
-
// A list of nodes that have been tombstoned.
|
|
66
|
-
this.tombstones = [];
|
|
67
|
-
// A list of nodes that have been deleted during sweep phase.
|
|
68
|
-
this.deletedNodes = new Set();
|
|
69
|
-
/**
|
|
70
|
-
* Map of node ids to their unreferenced state tracker
|
|
71
|
-
* NOTE: The set of keys in this map is considered as the set of unreferenced nodes
|
|
72
|
-
* as of the last GC run. So in between runs, nothing should be added or removed.
|
|
73
|
-
*/
|
|
74
|
-
this.unreferencedNodesState = new gcUnreferencedStateTracker_js_1.UnreferencedStateTrackerMap();
|
|
75
|
-
// The number of times GC has successfully completed on this instance of GarbageCollector.
|
|
76
|
-
this.completedRuns = 0;
|
|
77
|
-
/**
|
|
78
|
-
* API for ensuring the correct auto-recovery mitigations
|
|
79
|
-
*/
|
|
80
|
-
// TODO: consider hoisting this to an outer scope as an optimization
|
|
81
|
-
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
82
|
-
this.autoRecovery = (() => {
|
|
83
|
-
// This uses a hidden state machine for forcing fullGC as part of auto-recovery,
|
|
84
|
-
// to regenerate the GC data for each node.
|
|
85
|
-
//
|
|
86
|
-
// Once fullGC has been requested, we need to wait until GC has run and the summary has been acked before clearing the state.
|
|
87
|
-
//
|
|
88
|
-
// States:
|
|
89
|
-
// - undefined: No need to run fullGC now.
|
|
90
|
-
// - "requested": FullGC requested, but GC has not yet run. Keep using fullGC until back to undefined.
|
|
91
|
-
// - "ran": FullGC ran, but the following summary has not yet been acked. Keep using fullGC until back to undefined.
|
|
92
|
-
//
|
|
93
|
-
// Transitions:
|
|
94
|
-
// - autoRecovery.requestFullGCOnNextRun :: [anything] --> "requested"
|
|
95
|
-
// - autoRecovery.onCompletedGCRun :: "requested" --> "ran"
|
|
96
|
-
// - autoRecovery.onSummaryAck :: "ran" --> undefined
|
|
97
|
-
let state;
|
|
98
|
-
return {
|
|
99
|
-
requestFullGCOnNextRun: () => {
|
|
100
|
-
state = "requested";
|
|
101
|
-
},
|
|
102
|
-
onCompletedGCRun: () => {
|
|
103
|
-
if (state === "requested") {
|
|
104
|
-
state = "ran";
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
onSummaryAck: () => {
|
|
108
|
-
if (state === "ran") {
|
|
109
|
-
state = undefined;
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
useFullGC: () => {
|
|
113
|
-
return state !== undefined;
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
})();
|
|
117
107
|
this.runtime = createParams.runtime;
|
|
118
108
|
this.closeFn = createParams.closeFn;
|
|
119
109
|
this.isSummarizerClient = createParams.isSummarizerClient;
|
|
@@ -241,6 +231,46 @@ class GarbageCollector {
|
|
|
241
231
|
return { gcData: { gcNodes }, usedRoutes };
|
|
242
232
|
});
|
|
243
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* API for ensuring the correct auto-recovery mitigations
|
|
236
|
+
*/
|
|
237
|
+
// TODO: consider hoisting this to an outer scope as an optimization
|
|
238
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
239
|
+
autoRecovery = (() => {
|
|
240
|
+
// This uses a hidden state machine for forcing fullGC as part of auto-recovery,
|
|
241
|
+
// to regenerate the GC data for each node.
|
|
242
|
+
//
|
|
243
|
+
// Once fullGC has been requested, we need to wait until GC has run and the summary has been acked before clearing the state.
|
|
244
|
+
//
|
|
245
|
+
// States:
|
|
246
|
+
// - undefined: No need to run fullGC now.
|
|
247
|
+
// - "requested": FullGC requested, but GC has not yet run. Keep using fullGC until back to undefined.
|
|
248
|
+
// - "ran": FullGC ran, but the following summary has not yet been acked. Keep using fullGC until back to undefined.
|
|
249
|
+
//
|
|
250
|
+
// Transitions:
|
|
251
|
+
// - autoRecovery.requestFullGCOnNextRun :: [anything] --> "requested"
|
|
252
|
+
// - autoRecovery.onCompletedGCRun :: "requested" --> "ran"
|
|
253
|
+
// - autoRecovery.onSummaryAck :: "ran" --> undefined
|
|
254
|
+
let state;
|
|
255
|
+
return {
|
|
256
|
+
requestFullGCOnNextRun: () => {
|
|
257
|
+
state = "requested";
|
|
258
|
+
},
|
|
259
|
+
onCompletedGCRun: () => {
|
|
260
|
+
if (state === "requested") {
|
|
261
|
+
state = "ran";
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
onSummaryAck: () => {
|
|
265
|
+
if (state === "ran") {
|
|
266
|
+
state = undefined;
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
useFullGC: () => {
|
|
270
|
+
return state !== undefined;
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
})();
|
|
244
274
|
/**
|
|
245
275
|
* Called during container initialization. Initializes the tombstone and deleted nodes state from the base snapshot.
|
|
246
276
|
* Also, initializes the GC state including unreferenced nodes tracking if a current reference timestamp exists.
|