@fluidframework/container-runtime 2.0.0-dev-rc.2.0.0.245554 → 2.0.0-dev-rc.3.0.0.250606
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/api-report/container-runtime.api.md +81 -27
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -2
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +3 -3
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +3 -3
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +6 -5
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +57 -19
- 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 +3 -3
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +205 -12
- package/dist/container-runtime-beta.d.ts +16 -3
- package/dist/container-runtime-public.d.ts +16 -3
- package/dist/container-runtime-untrimmed.d.ts +207 -26
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +32 -26
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +235 -133
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +2 -2
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +4 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +18 -18
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +4 -0
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +1 -1
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +11 -5
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js +4 -0
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +1 -19
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +3 -3
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +3 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +2 -3
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +15 -4
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +60 -61
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +2 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +9 -11
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +11 -3
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +48 -38
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +18 -17
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +8 -0
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +36 -32
- 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 +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +6 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +178 -0
- package/dist/summary/documentSchema.d.ts.map +1 -0
- package/dist/summary/documentSchema.js +345 -0
- package/dist/summary/documentSchema.js.map +1 -0
- package/dist/summary/index.d.ts +2 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +4 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +2 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +7 -2
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- 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 +2 -2
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -2
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +2 -2
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +2 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +3 -3
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +3 -3
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +5 -16
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +2 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +2 -2
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +2 -2
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -2
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +3 -3
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +5 -5
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +6 -5
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +59 -21
- 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 +3 -3
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +205 -12
- package/lib/container-runtime-beta.d.ts +16 -3
- package/lib/container-runtime-public.d.ts +16 -3
- package/lib/container-runtime-untrimmed.d.ts +207 -26
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +32 -26
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +197 -95
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +2 -2
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +4 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +3 -3
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +4 -0
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaScheduler.d.ts +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +3 -3
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +1 -1
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +1 -1
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +1 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +1 -1
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +11 -5
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js +4 -0
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +1 -19
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +3 -3
- 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.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +2 -3
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +15 -4
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +60 -61
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +2 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +7 -10
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +11 -3
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +46 -37
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +18 -17
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +8 -0
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +36 -32
- 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 +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +6 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +178 -0
- package/lib/summary/documentSchema.d.ts.map +1 -0
- package/lib/summary/documentSchema.js +341 -0
- package/lib/summary/documentSchema.js.map +1 -0
- package/lib/summary/index.d.ts +2 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -0
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +2 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +7 -2
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- 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 +3 -3
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -2
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +3 -3
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +2 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +2 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +4 -4
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +3 -3
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +5 -16
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +2 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +3 -3
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +2 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/test/blobManager.spec.js +3 -3
- package/lib/test/blobManager.spec.js.map +1 -1
- package/lib/test/containerRuntime.spec.js +6 -4
- package/lib/test/containerRuntime.spec.js.map +1 -1
- package/lib/test/dataStoreContext.spec.js +4 -4
- package/lib/test/dataStoreContext.spec.js.map +1 -1
- package/lib/test/dataStoreCreation.spec.js +1 -1
- package/lib/test/dataStoreCreation.spec.js.map +1 -1
- package/lib/test/dataStoreRegistry.spec.js.map +1 -1
- package/lib/test/documentSchema.spec.js +282 -0
- package/lib/test/documentSchema.spec.js.map +1 -0
- package/lib/test/fuzz/fuzzUtils.js +11 -7
- package/lib/test/fuzz/fuzzUtils.js.map +1 -1
- package/lib/test/fuzz/summarizer.fuzz.spec.js +9 -7
- package/lib/test/fuzz/summarizer.fuzz.spec.js.map +1 -1
- package/lib/test/fuzz/summarizerFuzzMocks.js +43 -25
- package/lib/test/fuzz/summarizerFuzzMocks.js.map +1 -1
- package/lib/test/fuzz/summarizerFuzzSuite.js +7 -4
- package/lib/test/fuzz/summarizerFuzzSuite.js.map +1 -1
- package/lib/test/gc/garbageCollection.spec.js +5 -5
- package/lib/test/gc/garbageCollection.spec.js.map +1 -1
- package/lib/test/gc/gcConfigs.spec.js +2 -2
- package/lib/test/gc/gcConfigs.spec.js.map +1 -1
- package/lib/test/gc/gcHelpers.spec.js.map +1 -1
- package/lib/test/gc/gcStats.spec.js +2 -2
- package/lib/test/gc/gcStats.spec.js.map +1 -1
- package/lib/test/gc/gcSummaryStateTracker.spec.js +1 -1
- package/lib/test/gc/gcSummaryStateTracker.spec.js.map +1 -1
- package/lib/test/gc/gcTelemetry.spec.js +3 -3
- package/lib/test/gc/gcTelemetry.spec.js.map +1 -1
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js +1 -1
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +1 -1
- package/lib/test/getPendingBlobs.spec.js +1 -1
- package/lib/test/getPendingBlobs.spec.js.map +1 -1
- package/lib/test/hardwareStats.spec.js +1 -1
- package/lib/test/hardwareStats.spec.js.map +1 -1
- package/lib/test/opLifecycle/OpGroupingManager.spec.js +95 -118
- package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +1 -1
- package/lib/test/opLifecycle/batchManager.spec.js +1 -1
- package/lib/test/opLifecycle/batchManager.spec.js.map +1 -1
- package/lib/test/opLifecycle/opCompressor.spec.js +0 -1
- package/lib/test/opLifecycle/opCompressor.spec.js.map +1 -1
- package/lib/test/opLifecycle/opDecompressor.spec.js +60 -55
- package/lib/test/opLifecycle/opDecompressor.spec.js.map +1 -1
- package/lib/test/opLifecycle/opSplitter.spec.js +56 -41
- package/lib/test/opLifecycle/opSplitter.spec.js.map +1 -1
- package/lib/test/opLifecycle/outbox.spec.js +118 -10
- package/lib/test/opLifecycle/outbox.spec.js.map +1 -1
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +115 -91
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +1 -1
- package/lib/test/pendingStateManager.spec.js +1 -1
- package/lib/test/pendingStateManager.spec.js.map +1 -1
- package/lib/test/scheduleManager.spec.js +1 -1
- package/lib/test/scheduleManager.spec.js.map +1 -1
- package/lib/test/summarizerNode.spec.js +1 -1
- package/lib/test/summarizerNode.spec.js.map +1 -1
- package/lib/test/summarizerNodeWithGc.spec.js +1 -1
- package/lib/test/summarizerNodeWithGc.spec.js.map +1 -1
- package/lib/test/summary/runningSummarizer.spec.js +4 -4
- package/lib/test/summary/runningSummarizer.spec.js.map +1 -1
- package/lib/test/summary/summarizer.spec.js.map +1 -1
- package/lib/test/summary/summarizerClientElection.spec.js +2 -2
- package/lib/test/summary/summarizerClientElection.spec.js.map +1 -1
- package/lib/test/summary/summarizerHeuristics.spec.js +1 -1
- package/lib/test/summary/summarizerHeuristics.spec.js.map +1 -1
- package/lib/test/summary/summaryCollection.spec.js +1 -1
- package/lib/test/summary/summaryCollection.spec.js.map +1 -1
- package/lib/test/summary/summaryManager.spec.js +3 -3
- package/lib/test/summary/summaryManager.spec.js.map +1 -1
- package/lib/test/throttler.spec.js +1 -1
- package/lib/test/throttler.spec.js.map +1 -1
- package/lib/test/types/validateContainerRuntimePrevious.generated.js +6 -4
- package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +1 -1
- package/package.json +35 -21
- package/src/batchTracker.ts +3 -3
- package/src/blobManager.ts +15 -15
- package/src/channelCollection.ts +90 -44
- package/src/connectionTelemetry.ts +10 -10
- package/src/containerHandleContext.ts +1 -1
- package/src/containerRuntime.ts +375 -213
- package/src/dataStore.ts +2 -2
- package/src/dataStoreContext.ts +19 -19
- package/src/dataStoreContexts.ts +2 -2
- package/src/dataStoreRegistry.ts +2 -1
- package/src/deltaScheduler.ts +1 -1
- package/src/gc/garbageCollection.ts +12 -12
- package/src/gc/gcConfigs.ts +11 -11
- package/src/gc/gcDefinitions.ts +2 -2
- package/src/gc/gcHelpers.ts +2 -2
- package/src/gc/gcSummaryStateTracker.ts +4 -4
- package/src/gc/gcTelemetry.ts +6 -6
- package/src/index.ts +8 -1
- package/src/messageTypes.ts +18 -5
- package/src/opLifecycle/README.md +89 -0
- package/src/opLifecycle/definitions.ts +1 -20
- package/src/opLifecycle/index.ts +3 -9
- package/src/opLifecycle/opCompressor.ts +4 -5
- package/src/opLifecycle/opDecompressor.ts +83 -100
- package/src/opLifecycle/opGroupingManager.ts +9 -12
- package/src/opLifecycle/opSplitter.ts +73 -47
- package/src/opLifecycle/outbox.ts +26 -37
- package/src/opLifecycle/remoteMessageProcessor.ts +41 -55
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +2 -2
- package/src/scheduleManager.ts +8 -7
- package/src/summary/documentSchema.ts +553 -0
- package/src/summary/index.ts +10 -1
- package/src/summary/orderedClientElection.ts +7 -5
- package/src/summary/runWhileConnectedCoordinator.ts +1 -1
- package/src/summary/runningSummarizer.ts +19 -19
- package/src/summary/summarizer.ts +14 -14
- package/src/summary/summarizerClientElection.ts +2 -2
- package/src/summary/summarizerHeuristics.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +15 -15
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +1 -1
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +4 -4
- package/src/summary/summarizerTypes.ts +3 -3
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +8 -19
- package/src/summary/summaryGenerator.ts +10 -10
- package/src/summary/summaryManager.ts +4 -4
package/dist/containerRuntime.js
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*/
|
|
2
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.
|
|
7
|
+
exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
|
|
8
|
+
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
4
9
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
5
10
|
const core_utils_1 = require("@fluidframework/core-utils");
|
|
6
|
-
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
7
|
-
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
8
11
|
const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
9
12
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
10
13
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
11
14
|
const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
|
|
12
15
|
const runtime_utils_1 = require("@fluidframework/runtime-utils");
|
|
16
|
+
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
13
17
|
const uuid_1 = require("uuid");
|
|
14
|
-
const
|
|
15
|
-
const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
|
|
16
|
-
const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
|
|
17
|
-
const pendingStateManager_js_1 = require("./pendingStateManager.js");
|
|
18
|
-
const packageVersion_js_1 = require("./packageVersion.js");
|
|
18
|
+
const batchTracker_js_1 = require("./batchTracker.js");
|
|
19
19
|
const blobManager_js_1 = require("./blobManager.js");
|
|
20
20
|
const channelCollection_js_1 = require("./channelCollection.js");
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const index_js_2 = require("./gc/index.js");
|
|
21
|
+
const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
|
|
22
|
+
const containerHandleContext_js_1 = require("./containerHandleContext.js");
|
|
24
23
|
const dataStore_js_1 = require("./dataStore.js");
|
|
25
|
-
const
|
|
26
|
-
const scheduleManager_js_1 = require("./scheduleManager.js");
|
|
27
|
-
const index_js_3 = require("./opLifecycle/index.js");
|
|
24
|
+
const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
|
|
28
25
|
const deltaManagerSummarizerProxy_js_1 = require("./deltaManagerSummarizerProxy.js");
|
|
26
|
+
const index_js_1 = require("./gc/index.js");
|
|
29
27
|
const messageTypes_js_1 = require("./messageTypes.js");
|
|
28
|
+
const index_js_2 = require("./opLifecycle/index.js");
|
|
29
|
+
const packageVersion_js_1 = require("./packageVersion.js");
|
|
30
|
+
const pendingStateManager_js_1 = require("./pendingStateManager.js");
|
|
31
|
+
const scheduleManager_js_1 = require("./scheduleManager.js");
|
|
32
|
+
const index_js_3 = require("./summary/index.js");
|
|
33
|
+
const throttler_js_1 = require("./throttler.js");
|
|
30
34
|
/**
|
|
31
35
|
* Utility to implement compat behaviors given an unknown message type
|
|
32
36
|
* The parameters are typed to support compile-time enforcement of handling all known types/behaviors
|
|
@@ -81,6 +85,11 @@ var CompressionAlgorithms;
|
|
|
81
85
|
(function (CompressionAlgorithms) {
|
|
82
86
|
CompressionAlgorithms["lz4"] = "lz4";
|
|
83
87
|
})(CompressionAlgorithms || (exports.CompressionAlgorithms = CompressionAlgorithms = {}));
|
|
88
|
+
/** @alpha */
|
|
89
|
+
exports.disabledCompressionConfig = {
|
|
90
|
+
minimumBatchSizeInBytes: Infinity,
|
|
91
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
92
|
+
};
|
|
84
93
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
85
94
|
const defaultFlushMode = runtime_definitions_1.FlushMode.TurnBased;
|
|
86
95
|
// The actual limit is 1Mb (socket.io and Kafka limits)
|
|
@@ -104,26 +113,12 @@ exports.defaultPendingOpsRetryDelayMs = 1000;
|
|
|
104
113
|
* This delay's goal is to prevent tight restart loops
|
|
105
114
|
*/
|
|
106
115
|
const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
|
|
107
|
-
/**
|
|
108
|
-
* @deprecated use ContainerRuntimeMessageType instead
|
|
109
|
-
* @internal
|
|
110
|
-
*/
|
|
111
|
-
var RuntimeMessage;
|
|
112
|
-
(function (RuntimeMessage) {
|
|
113
|
-
RuntimeMessage["FluidDataStoreOp"] = "component";
|
|
114
|
-
RuntimeMessage["Attach"] = "attach";
|
|
115
|
-
RuntimeMessage["ChunkedOp"] = "chunkedOp";
|
|
116
|
-
RuntimeMessage["BlobAttach"] = "blobAttach";
|
|
117
|
-
RuntimeMessage["Rejoin"] = "rejoin";
|
|
118
|
-
RuntimeMessage["Alias"] = "alias";
|
|
119
|
-
RuntimeMessage["Operation"] = "op";
|
|
120
|
-
})(RuntimeMessage || (exports.RuntimeMessage = RuntimeMessage = {}));
|
|
121
116
|
/**
|
|
122
117
|
* @deprecated please use version in driver-utils
|
|
123
118
|
* @internal
|
|
124
119
|
*/
|
|
125
120
|
function isRuntimeMessage(message) {
|
|
126
|
-
return Object.values(
|
|
121
|
+
return Object.values(messageTypes_js_1.ContainerMessageType).includes(message.type);
|
|
127
122
|
}
|
|
128
123
|
exports.isRuntimeMessage = isRuntimeMessage;
|
|
129
124
|
/**
|
|
@@ -172,7 +167,7 @@ async function createSummarizer(loader, url) {
|
|
|
172
167
|
[container_definitions_1.LoaderHeader.cache]: false,
|
|
173
168
|
[container_definitions_1.LoaderHeader.clientDetails]: {
|
|
174
169
|
capabilities: { interactive: false },
|
|
175
|
-
type:
|
|
170
|
+
type: index_js_3.summarizerClientType,
|
|
176
171
|
},
|
|
177
172
|
[driver_definitions_1.DriverHeader.summarizingClient]: true,
|
|
178
173
|
[container_definitions_1.LoaderHeader.reconnect]: false,
|
|
@@ -200,6 +195,17 @@ async function createSummarizer(loader, url) {
|
|
|
200
195
|
}
|
|
201
196
|
return fluidObject.ISummarizer;
|
|
202
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Extract last message from the snapshot metadata.
|
|
200
|
+
* Uses legacy property if not using explicit schema control, otherwise uses the new property.
|
|
201
|
+
* This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
|
|
202
|
+
* Please see addMetadataToSummary() as well
|
|
203
|
+
*/
|
|
204
|
+
function lastMessageFromMetadata(metadata) {
|
|
205
|
+
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
206
|
+
? metadata?.lastMessage
|
|
207
|
+
: metadata?.message;
|
|
208
|
+
}
|
|
203
209
|
/**
|
|
204
210
|
* Represents the runtime of the container. Contains helper functions/state of the container.
|
|
205
211
|
* It will define the store level mappings.
|
|
@@ -237,7 +243,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
237
243
|
},
|
|
238
244
|
});
|
|
239
245
|
const mc = (0, telemetry_utils_1.loggerToMonitoringContext)(logger);
|
|
240
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor
|
|
246
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, explicitSchemaControl = false, } = runtimeOptions;
|
|
241
247
|
const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
|
|
242
248
|
const tryFetchBlob = async (blobName) => {
|
|
243
249
|
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
@@ -249,27 +255,34 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
249
255
|
}
|
|
250
256
|
};
|
|
251
257
|
const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
|
|
252
|
-
tryFetchBlob(
|
|
253
|
-
tryFetchBlob(
|
|
254
|
-
tryFetchBlob(
|
|
255
|
-
tryFetchBlob(
|
|
256
|
-
tryFetchBlob(
|
|
258
|
+
tryFetchBlob(index_js_3.chunksBlobName),
|
|
259
|
+
tryFetchBlob(index_js_3.metadataBlobName),
|
|
260
|
+
tryFetchBlob(index_js_3.electedSummarizerBlobName),
|
|
261
|
+
tryFetchBlob(index_js_3.aliasBlobName),
|
|
262
|
+
tryFetchBlob(index_js_3.idCompressorBlobName),
|
|
257
263
|
]);
|
|
258
264
|
// read snapshot blobs needed for BlobManager to load
|
|
259
|
-
const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[
|
|
265
|
+
const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_3.blobsTreeName], async (id) => {
|
|
260
266
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
261
267
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
262
268
|
(0, core_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
|
|
263
269
|
return (0, driver_utils_1.readAndParse)(context.storage, id);
|
|
264
270
|
});
|
|
271
|
+
const messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
265
272
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
266
|
-
const runtimeSequenceNumber =
|
|
273
|
+
const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
|
|
267
274
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
268
275
|
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
269
276
|
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
270
277
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
271
278
|
if (loadSequenceNumberVerification !== "bypass" &&
|
|
272
279
|
runtimeSequenceNumber !== protocolSequenceNumber) {
|
|
280
|
+
// Message to OCEs:
|
|
281
|
+
// You can hit this error with runtimeSequenceNumber === -1 in < 2.0 RC3 builds.
|
|
282
|
+
// This would indicate that explicit schema control is enabled in current (2.0 RC3+) builds and it
|
|
283
|
+
// results in addMetadataToSummary() creating a poison pill for older runtimes in the form of a -1 sequence number.
|
|
284
|
+
// Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
|
|
285
|
+
// this poison pill to prevent them from proceeding.
|
|
273
286
|
// "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
|
|
274
287
|
const error = new telemetry_utils_1.DataCorruptionError(
|
|
275
288
|
// pre-0.58 error message: SummaryMetadataMismatch
|
|
@@ -283,7 +296,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
283
296
|
}
|
|
284
297
|
}
|
|
285
298
|
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
286
|
-
// allow new containers to turn it on
|
|
299
|
+
// allow new containers to turn it on.
|
|
287
300
|
let idCompressorMode;
|
|
288
301
|
if (existing) {
|
|
289
302
|
// This setting has to be sticky for correctness:
|
|
@@ -292,20 +305,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
292
305
|
// 2) if it's ON, then all sessions should load compressor right away
|
|
293
306
|
// 3) Same logic applies for "delayed" mode
|
|
294
307
|
// Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
|
|
295
|
-
// We could do "off" -> "on"
|
|
296
|
-
// this will allow clients to eventually to disregard "off" setting (when it's safe so) and start
|
|
308
|
+
// We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
|
|
309
|
+
// do so for a while - this will allow clients to eventually to disregard "off" setting (when it's safe so) and start
|
|
310
|
+
// using compressor in future sessions.
|
|
297
311
|
// Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
|
|
298
|
-
idCompressorMode = metadata?.
|
|
312
|
+
idCompressorMode = metadata?.documentSchema?.runtime
|
|
313
|
+
?.idCompressorMode;
|
|
299
314
|
}
|
|
300
315
|
else {
|
|
301
|
-
|
|
302
|
-
const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
|
|
303
|
-
switch (enabled) {
|
|
316
|
+
switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
|
|
304
317
|
case true:
|
|
305
318
|
idCompressorMode = "on";
|
|
306
319
|
break;
|
|
307
320
|
case false:
|
|
308
|
-
idCompressorMode =
|
|
321
|
+
idCompressorMode = undefined;
|
|
309
322
|
break;
|
|
310
323
|
default:
|
|
311
324
|
idCompressorMode = enableRuntimeIdCompressor;
|
|
@@ -338,6 +351,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
338
351
|
return createIdCompressor(compressorLogger);
|
|
339
352
|
}
|
|
340
353
|
};
|
|
354
|
+
const disableGroupedBatching = mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
|
|
355
|
+
const disableCompression = mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
356
|
+
const compressionLz4 = disableCompression !== true &&
|
|
357
|
+
compressionOptions.minimumBatchSizeInBytes !== Infinity &&
|
|
358
|
+
compressionOptions.compressionAlgorithm === "lz4";
|
|
359
|
+
const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
|
|
360
|
+
const documentSchemaController = new index_js_3.DocumentsSchemaController(existing, metadata?.documentSchema, {
|
|
361
|
+
explicitSchemaControl,
|
|
362
|
+
compressionLz4,
|
|
363
|
+
idCompressorMode,
|
|
364
|
+
opGroupingEnabled,
|
|
365
|
+
}, (schema) => {
|
|
366
|
+
runtime.onSchemaChange(schema);
|
|
367
|
+
});
|
|
368
|
+
const featureGatesForTelemetry = {
|
|
369
|
+
disableGroupedBatching,
|
|
370
|
+
disableCompression,
|
|
371
|
+
};
|
|
341
372
|
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
|
|
342
373
|
summaryOptions,
|
|
343
374
|
gcOptions,
|
|
@@ -346,10 +377,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
346
377
|
compressionOptions,
|
|
347
378
|
maxBatchSizeInBytes,
|
|
348
379
|
chunkSizeInBytes,
|
|
349
|
-
|
|
380
|
+
// Requires<> drops undefined from IdCompressorType
|
|
381
|
+
enableRuntimeIdCompressor: enableRuntimeIdCompressor,
|
|
350
382
|
enableOpReentryCheck,
|
|
351
383
|
enableGroupedBatching,
|
|
352
|
-
|
|
384
|
+
explicitSchemaControl,
|
|
385
|
+
}, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
|
|
353
386
|
// Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
|
|
354
387
|
// or zero. This must be done before Container replays saved ops.
|
|
355
388
|
await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
|
|
@@ -378,6 +411,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
378
411
|
get attachState() {
|
|
379
412
|
return this._getAttachState();
|
|
380
413
|
}
|
|
414
|
+
get documentSchema() {
|
|
415
|
+
return this.documentsSchemaController.sessionSchema.runtime;
|
|
416
|
+
}
|
|
417
|
+
get idCompressorMode() {
|
|
418
|
+
return this.documentSchema.idCompressorMode;
|
|
419
|
+
}
|
|
381
420
|
/**
|
|
382
421
|
* See IContainerRuntimeBase.idCompressor() for details.
|
|
383
422
|
*/
|
|
@@ -458,7 +497,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
458
497
|
return this.garbageCollector.throwOnTombstoneUsage;
|
|
459
498
|
}
|
|
460
499
|
/***/
|
|
461
|
-
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor,
|
|
500
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
|
|
462
501
|
// the defaults
|
|
463
502
|
...exports.DefaultSummaryConfiguration,
|
|
464
503
|
// the runtime configuration overrides
|
|
@@ -472,18 +511,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
472
511
|
this.logger = logger;
|
|
473
512
|
this._storage = _storage;
|
|
474
513
|
this.createIdCompressor = createIdCompressor;
|
|
475
|
-
this.
|
|
514
|
+
this.documentsSchemaController = documentsSchemaController;
|
|
476
515
|
this.requestHandler = requestHandler;
|
|
477
516
|
this.summaryConfiguration = summaryConfiguration;
|
|
478
517
|
this.imminentClosure = false;
|
|
479
518
|
// We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
|
|
480
519
|
// Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
|
|
481
520
|
this.pendingIdCompressorOps = [];
|
|
482
|
-
/**
|
|
483
|
-
* True if we have ID compressor loading in-flight (async operation). Useful only for
|
|
484
|
-
* this.idCompressorMode === "delayed" mode
|
|
485
|
-
*/
|
|
486
|
-
this.compressorLoadInitiated = false;
|
|
487
521
|
this.defaultMaxConsecutiveReconnects = 7;
|
|
488
522
|
this._orderSequentiallyCalls = 0;
|
|
489
523
|
this.flushTaskExists = false;
|
|
@@ -513,6 +547,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
513
547
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
514
548
|
});
|
|
515
549
|
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
|
|
550
|
+
this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
|
|
551
|
+
logger: this.logger,
|
|
552
|
+
namespace: "ContainerRuntime",
|
|
553
|
+
});
|
|
554
|
+
// If we support multiple algorithms in the future, then we would need to manage it here carefully.
|
|
555
|
+
// We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
|
|
556
|
+
// If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
|
|
557
|
+
// compression.
|
|
558
|
+
const compressionOptions = {
|
|
559
|
+
minimumBatchSizeInBytes: this.documentSchema.compressionLz4
|
|
560
|
+
? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
|
|
561
|
+
: Number.POSITIVE_INFINITY,
|
|
562
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
563
|
+
};
|
|
516
564
|
this.innerDeltaManager = deltaManager;
|
|
517
565
|
this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
518
566
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
@@ -525,7 +573,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
525
573
|
// Values are generally expected to be set from the runtime side.
|
|
526
574
|
this.options = options ?? {};
|
|
527
575
|
this.clientDetails = clientDetails;
|
|
528
|
-
this.isSummarizerClient = this.clientDetails.type ===
|
|
576
|
+
this.isSummarizerClient = this.clientDetails.type === index_js_3.summarizerClientType;
|
|
529
577
|
this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
|
|
530
578
|
this._getClientId = () => context.clientId;
|
|
531
579
|
this._getAttachState = () => context.attachState;
|
|
@@ -546,10 +594,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
546
594
|
this.disposeFn = disposeFn ?? closeFn;
|
|
547
595
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
548
596
|
this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
|
|
549
|
-
this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
|
|
550
|
-
logger: this.logger,
|
|
551
|
-
namespace: "ContainerRuntime",
|
|
552
|
-
});
|
|
553
597
|
let loadSummaryNumber;
|
|
554
598
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
555
599
|
// get the values from the metadata blob.
|
|
@@ -570,7 +614,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
570
614
|
loadSummaryNumber = 0;
|
|
571
615
|
}
|
|
572
616
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
573
|
-
this.messageAtLastSummary = metadata
|
|
617
|
+
this.messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
574
618
|
// Note that we only need to pull the *initial* connected state from the context.
|
|
575
619
|
// Later updates come through calls to setConnectionState.
|
|
576
620
|
this._connected = connected;
|
|
@@ -578,20 +622,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
578
622
|
eventName: "GCFeatureMatrix",
|
|
579
623
|
metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
|
|
580
624
|
inputs: JSON.stringify({
|
|
581
|
-
gcOptions_gcGeneration: this.runtimeOptions.gcOptions[
|
|
625
|
+
gcOptions_gcGeneration: this.runtimeOptions.gcOptions[index_js_1.gcGenerationOptionName],
|
|
582
626
|
}),
|
|
583
627
|
});
|
|
584
628
|
this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
|
|
585
629
|
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
586
630
|
const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
|
|
587
|
-
const opGroupingManager = new
|
|
631
|
+
const opGroupingManager = new index_js_2.OpGroupingManager({
|
|
588
632
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
589
633
|
opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
|
|
590
634
|
reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
|
|
591
635
|
true,
|
|
592
636
|
}, this.mc.logger);
|
|
593
|
-
const opSplitter = new
|
|
594
|
-
this.remoteMessageProcessor = new
|
|
637
|
+
const opSplitter = new index_js_2.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
638
|
+
this.remoteMessageProcessor = new index_js_2.RemoteMessageProcessor(opSplitter, new index_js_2.OpDecompressor(this.mc.logger), opGroupingManager);
|
|
595
639
|
this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
|
|
596
640
|
if (this.summaryConfiguration.state === "enabled") {
|
|
597
641
|
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
@@ -627,7 +671,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
627
671
|
throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
|
|
628
672
|
}
|
|
629
673
|
}
|
|
630
|
-
this.garbageCollector =
|
|
674
|
+
this.garbageCollector = index_js_1.GarbageCollector.create({
|
|
631
675
|
runtime: this,
|
|
632
676
|
gcOptions: this.runtimeOptions.gcOptions,
|
|
633
677
|
baseSnapshot,
|
|
@@ -643,7 +687,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
643
687
|
sessionExpiryTimerStarted: pendingRuntimeState?.sessionExpiryTimerStarted,
|
|
644
688
|
});
|
|
645
689
|
const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
|
|
646
|
-
this.summarizerNode = (0,
|
|
690
|
+
this.summarizerNode = (0, index_js_3.createRootSummarizerNodeWithGC)((0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
|
|
647
691
|
// Summarize function to call when summarize is called. Summarizer node always tracks summary state.
|
|
648
692
|
async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
|
|
649
693
|
// Latest change sequence number, no changes since summary applied yet
|
|
@@ -687,26 +731,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
687
731
|
clientId: () => this.clientId,
|
|
688
732
|
close: this.closeFn,
|
|
689
733
|
connected: () => this.connected,
|
|
690
|
-
reSubmit:
|
|
734
|
+
reSubmit: (message) => {
|
|
735
|
+
this.reSubmit(message);
|
|
736
|
+
this.flush();
|
|
737
|
+
},
|
|
691
738
|
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
692
739
|
isActiveConnection: () => this.innerDeltaManager.active,
|
|
693
740
|
isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
|
|
694
741
|
}, pendingRuntimeState?.pending, this.logger);
|
|
695
|
-
const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
696
|
-
const compressionOptions = disableCompression === true
|
|
697
|
-
? {
|
|
698
|
-
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
699
|
-
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
700
|
-
}
|
|
701
|
-
: runtimeOptions.compressionOptions;
|
|
702
742
|
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
703
743
|
const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
|
|
704
|
-
this.outbox = new
|
|
744
|
+
this.outbox = new index_js_2.Outbox({
|
|
705
745
|
shouldSend: () => this.canSendOps(),
|
|
706
746
|
pendingStateManager: this.pendingStateManager,
|
|
707
747
|
submitBatchFn: this.submitBatchFn,
|
|
708
748
|
legacySendBatchFn,
|
|
709
|
-
compressor: new
|
|
749
|
+
compressor: new index_js_2.OpCompressor(this.mc.logger),
|
|
710
750
|
splitter: opSplitter,
|
|
711
751
|
config: {
|
|
712
752
|
compressionOptions,
|
|
@@ -733,7 +773,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
733
773
|
this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
|
|
734
774
|
this.validateSummaryBeforeUpload =
|
|
735
775
|
this.mc.config.getBoolean("Fluid.Summarizer.ValidateSummaryBeforeUpload") ?? false;
|
|
736
|
-
this.summaryCollection = new
|
|
776
|
+
this.summaryCollection = new index_js_3.SummaryCollection(this.deltaManager, this.logger);
|
|
737
777
|
this.dirtyContainer =
|
|
738
778
|
this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
|
|
739
779
|
context.updateDirtyContainerState(this.dirtyContainer);
|
|
@@ -745,16 +785,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
745
785
|
logger: this.logger,
|
|
746
786
|
namespace: "OrderedClientElection",
|
|
747
787
|
});
|
|
748
|
-
const orderedClientCollection = new
|
|
749
|
-
const orderedClientElectionForSummarizer = new
|
|
750
|
-
this.summarizerClientElection = new
|
|
788
|
+
const orderedClientCollection = new index_js_3.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
|
|
789
|
+
const orderedClientElectionForSummarizer = new index_js_3.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_3.SummarizerClientElection.isClientEligible);
|
|
790
|
+
this.summarizerClientElection = new index_js_3.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
|
|
751
791
|
if (this.isSummarizerClient) {
|
|
752
|
-
this._summarizer = new
|
|
792
|
+
this._summarizer = new index_js_3.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_3.RunWhileConnectedCoordinator.create(runtime,
|
|
753
793
|
// Summarization runs in summarizer client and needs access to the real (non-proxy) active
|
|
754
794
|
// information. The proxy delta manager would always return false for summarizer client.
|
|
755
795
|
() => this.innerDeltaManager.active));
|
|
756
796
|
}
|
|
757
|
-
else if (
|
|
797
|
+
else if (index_js_3.SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
|
|
758
798
|
// Only create a SummaryManager and SummarizerClientElection
|
|
759
799
|
// if summaries are enabled and we are not the summarizer client.
|
|
760
800
|
const defaultAction = () => {
|
|
@@ -776,7 +816,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
776
816
|
};
|
|
777
817
|
this.summaryCollection.on("default", defaultAction);
|
|
778
818
|
// Create the SummaryManager and mark the initial state
|
|
779
|
-
this.summaryManager = new
|
|
819
|
+
this.summaryManager = new index_js_3.SummaryManager(this.summarizerClientElection, this, // IConnectedState
|
|
780
820
|
this.summaryCollection, this.logger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
|
|
781
821
|
30 * 1000, // 30 sec max delay
|
|
782
822
|
// throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
|
|
@@ -803,10 +843,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
803
843
|
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
804
844
|
gcVersion: metadata?.gcFeature,
|
|
805
845
|
options: JSON.stringify(runtimeOptions),
|
|
806
|
-
idCompressorModeMetadata: metadata?.idCompressorMode,
|
|
846
|
+
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
807
847
|
idCompressorMode: this.idCompressorMode,
|
|
808
848
|
featureGates: JSON.stringify({
|
|
809
|
-
|
|
849
|
+
...featureGatesForTelemetry,
|
|
810
850
|
disableOpReentryCheck,
|
|
811
851
|
disableChunking,
|
|
812
852
|
disableAttachReorder: this.disableAttachReorder,
|
|
@@ -829,6 +869,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
829
869
|
// saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
|
|
830
870
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
831
871
|
}
|
|
872
|
+
onSchemaChange(schema) {
|
|
873
|
+
// Most of the settings will be picked up only by new sessions (i.e. after reload).
|
|
874
|
+
// We can make it better in the future (i.e. start to use op compression right away), but for simplicity
|
|
875
|
+
// this is not done.
|
|
876
|
+
// But ID compressor is special. It's possible, that in future, we will remove "stickiness" of ID compressor setting
|
|
877
|
+
// and will allow to start using it. If that were to happen, we want to ensure that we do not break eventual consistency
|
|
878
|
+
// promises. To do so, we need to initialize id compressor right away.
|
|
879
|
+
// As it's implemented right now (with async initialization), this will only work for "off" -> "delayed" transitions.
|
|
880
|
+
// Anything else is too risky, and requires ability to initialize ID compressor synchronously!
|
|
881
|
+
if (schema.runtime.idCompressorMode !== undefined) {
|
|
882
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
883
|
+
this.loadIdCompressor();
|
|
884
|
+
}
|
|
885
|
+
}
|
|
832
886
|
getCreateChildSummarizerNodeFn(id, createParam) {
|
|
833
887
|
return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
|
|
834
888
|
}
|
|
@@ -840,7 +894,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
840
894
|
(0, core_utils_1.assert)(false, 0x8eb /* should not be called */);
|
|
841
895
|
}
|
|
842
896
|
setChannelDirty(address) {
|
|
843
|
-
(0, core_utils_1.assert)(false,
|
|
897
|
+
(0, core_utils_1.assert)(false, 0x909 /* should not be called */);
|
|
844
898
|
}
|
|
845
899
|
/**
|
|
846
900
|
* Initializes the state from the base snapshot this container runtime loaded from.
|
|
@@ -905,7 +959,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
905
959
|
}),
|
|
906
960
|
});
|
|
907
961
|
// Find the snapshotTree inside the returned snapshot based on the path as given in the request.
|
|
908
|
-
const hasIsolatedChannels = (0,
|
|
962
|
+
const hasIsolatedChannels = (0, index_js_3.rootHasIsolatedChannels)(this.metadata);
|
|
909
963
|
const snapshotTreeForPath = this.getSnapshotTreeForPath(snapshot.snapshotTree, pathParts, hasIsolatedChannels);
|
|
910
964
|
(0, core_utils_1.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
|
|
911
965
|
const snapshotSeqNumber = snapshot.sequenceNumber;
|
|
@@ -1046,44 +1100,56 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1046
1100
|
}
|
|
1047
1101
|
/** Adds the container's metadata to the given summary tree. */
|
|
1048
1102
|
addMetadataToSummary(summaryTree) {
|
|
1103
|
+
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
1104
|
+
// last summary.
|
|
1105
|
+
const message = (0, index_js_3.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
|
|
1106
|
+
this.messageAtLastSummary;
|
|
1107
|
+
const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
|
|
1108
|
+
// Is document schema explicit control on?
|
|
1109
|
+
const explitiSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
1049
1110
|
const metadata = {
|
|
1050
1111
|
...this.createContainerMetadata,
|
|
1051
1112
|
// Increment the summary number for the next summary that will be generated.
|
|
1052
1113
|
summaryNumber: this.nextSummaryNumber++,
|
|
1053
1114
|
summaryFormatVersion: 1,
|
|
1054
1115
|
...this.garbageCollector.getMetadata(),
|
|
1055
|
-
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
1056
|
-
// last summary.
|
|
1057
|
-
message: (0, index_js_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
|
|
1058
|
-
this.messageAtLastSummary,
|
|
1059
1116
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
1060
|
-
|
|
1117
|
+
// If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
|
|
1118
|
+
// Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
|
|
1119
|
+
// runtimes (that preceed document schema control capabilities) to close container on load due to mismatch in
|
|
1120
|
+
// last message's sequence number.
|
|
1121
|
+
// See also lastMessageFromMetadata()
|
|
1122
|
+
message: explitiSchemaControl
|
|
1123
|
+
? { sequenceNumber: -1 }
|
|
1124
|
+
: message,
|
|
1125
|
+
lastMessage: explitiSchemaControl ? message : undefined,
|
|
1126
|
+
documentSchema,
|
|
1061
1127
|
};
|
|
1062
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
1128
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.metadataBlobName, JSON.stringify(metadata));
|
|
1063
1129
|
}
|
|
1064
1130
|
addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
|
|
1065
1131
|
this.addMetadataToSummary(summaryTree);
|
|
1066
1132
|
if (this._idCompressor) {
|
|
1067
1133
|
const idCompressorState = JSON.stringify(this._idCompressor.serialize(false));
|
|
1068
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
1134
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.idCompressorBlobName, idCompressorState);
|
|
1069
1135
|
}
|
|
1070
1136
|
if (this.remoteMessageProcessor.partialMessages.size > 0) {
|
|
1071
1137
|
const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
|
|
1072
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
1138
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.chunksBlobName, content);
|
|
1073
1139
|
}
|
|
1074
1140
|
const dataStoreAliases = this.channelCollection.aliases;
|
|
1075
1141
|
if (dataStoreAliases.size > 0) {
|
|
1076
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
1142
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.aliasBlobName, JSON.stringify([...dataStoreAliases]));
|
|
1077
1143
|
}
|
|
1078
1144
|
if (this.summarizerClientElection) {
|
|
1079
1145
|
const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
|
|
1080
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
1146
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, index_js_3.electedSummarizerBlobName, electedSummarizerContent);
|
|
1081
1147
|
}
|
|
1082
1148
|
const blobManagerSummary = this.blobManager.summarize();
|
|
1083
1149
|
// Some storage (like git) doesn't allow empty tree, so we can omit it.
|
|
1084
1150
|
// and the blob manager can handle the tree not existing when loading
|
|
1085
1151
|
if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
|
|
1086
|
-
(0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree,
|
|
1152
|
+
(0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, index_js_3.blobsTreeName, blobManagerSummary);
|
|
1087
1153
|
}
|
|
1088
1154
|
const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
|
|
1089
1155
|
if (gcSummary !== undefined) {
|
|
@@ -1118,14 +1184,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1118
1184
|
}
|
|
1119
1185
|
return this.consecutiveReconnects < this.maxConsecutiveReconnects;
|
|
1120
1186
|
}
|
|
1121
|
-
resetReconnectCount(
|
|
1122
|
-
|
|
1123
|
-
// in their own batches before the originating batch is sent.
|
|
1124
|
-
// Therefore, receiving them while attempting to send the originating batch
|
|
1125
|
-
// does not mean that the container is making any progress.
|
|
1126
|
-
if (message?.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp) {
|
|
1127
|
-
this.consecutiveReconnects = 0;
|
|
1128
|
-
}
|
|
1187
|
+
resetReconnectCount() {
|
|
1188
|
+
this.consecutiveReconnects = 0;
|
|
1129
1189
|
}
|
|
1130
1190
|
replayPendingStates() {
|
|
1131
1191
|
// We need to be able to send ops to replay states
|
|
@@ -1174,7 +1234,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1174
1234
|
case messageTypes_js_1.ContainerMessageType.Alias:
|
|
1175
1235
|
return this.channelCollection.applyStashedOp(opContents);
|
|
1176
1236
|
case messageTypes_js_1.ContainerMessageType.IdAllocation:
|
|
1177
|
-
(0, core_utils_1.assert)(this.idCompressorMode !==
|
|
1237
|
+
(0, core_utils_1.assert)(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1238
|
+
return;
|
|
1239
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
|
|
1178
1240
|
return;
|
|
1179
1241
|
case messageTypes_js_1.ContainerMessageType.BlobAttach:
|
|
1180
1242
|
return;
|
|
@@ -1205,10 +1267,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1205
1267
|
}
|
|
1206
1268
|
}
|
|
1207
1269
|
}
|
|
1208
|
-
|
|
1209
|
-
if (
|
|
1210
|
-
this.
|
|
1211
|
-
this.
|
|
1270
|
+
async loadIdCompressor() {
|
|
1271
|
+
if (this._idCompressor === undefined &&
|
|
1272
|
+
this.idCompressorMode !== undefined &&
|
|
1273
|
+
this._loadIdCompressor === undefined) {
|
|
1274
|
+
this._loadIdCompressor = this.createIdCompressor()
|
|
1212
1275
|
.then((compressor) => {
|
|
1213
1276
|
this._idCompressor = compressor;
|
|
1214
1277
|
for (const range of this.pendingIdCompressorOps) {
|
|
@@ -1218,8 +1281,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1218
1281
|
})
|
|
1219
1282
|
.catch((error) => {
|
|
1220
1283
|
this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
1284
|
+
throw error;
|
|
1221
1285
|
});
|
|
1222
1286
|
}
|
|
1287
|
+
return this._loadIdCompressor;
|
|
1288
|
+
}
|
|
1289
|
+
setConnectionState(connected, clientId) {
|
|
1290
|
+
if (connected && this.idCompressorMode === "delayed") {
|
|
1291
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1292
|
+
this.loadIdCompressor();
|
|
1293
|
+
}
|
|
1223
1294
|
if (connected === false && this.delayConnectClientId !== undefined) {
|
|
1224
1295
|
this.delayConnectClientId = undefined;
|
|
1225
1296
|
this.mc.logger.sendTelemetryEvent({
|
|
@@ -1228,6 +1299,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1228
1299
|
// Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
|
|
1229
1300
|
return;
|
|
1230
1301
|
}
|
|
1302
|
+
if (!connected) {
|
|
1303
|
+
this.documentsSchemaController.onDisconnect();
|
|
1304
|
+
}
|
|
1231
1305
|
// If there are stashed blobs in the pending state, we need to delay
|
|
1232
1306
|
// propagation of the "connected" event until we have uploaded them to
|
|
1233
1307
|
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
@@ -1330,10 +1404,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1330
1404
|
this.scheduleManager.beforeOpProcessing(message);
|
|
1331
1405
|
this._processedClientSequenceNumber = message.clientSequenceNumber;
|
|
1332
1406
|
try {
|
|
1407
|
+
// See commit that added this assert for more details.
|
|
1408
|
+
// These calls should be made for all but chunked ops:
|
|
1409
|
+
// 1) this.pendingStateManager.processPendingLocalMessage() below
|
|
1410
|
+
// 2) this.resetReconnectCount() below
|
|
1411
|
+
(0, core_utils_1.assert)(message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp, "we should never get here with chunked ops");
|
|
1333
1412
|
let localOpMetadata;
|
|
1334
|
-
if (local &&
|
|
1335
|
-
messageWithContext.modernRuntimeMessage &&
|
|
1336
|
-
message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp) {
|
|
1413
|
+
if (local && messageWithContext.modernRuntimeMessage) {
|
|
1337
1414
|
localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
|
|
1338
1415
|
}
|
|
1339
1416
|
// If there are no more pending messages after processing a local message,
|
|
@@ -1348,7 +1425,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1348
1425
|
// If we have processed a local op, this means that the container is
|
|
1349
1426
|
// making progress and we can reset the counter for how many times
|
|
1350
1427
|
// we have consecutively replayed the pending states
|
|
1351
|
-
this.resetReconnectCount(
|
|
1428
|
+
this.resetReconnectCount();
|
|
1352
1429
|
}
|
|
1353
1430
|
}
|
|
1354
1431
|
catch (e) {
|
|
@@ -1394,8 +1471,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1394
1471
|
this.garbageCollector.processMessage(messageWithContext.message, local);
|
|
1395
1472
|
break;
|
|
1396
1473
|
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|
|
1474
|
+
// From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
|
|
1475
|
+
// Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
|
|
1476
|
+
(0, core_utils_1.assert)(false, "should not even get here");
|
|
1397
1477
|
case messageTypes_js_1.ContainerMessageType.Rejoin:
|
|
1398
1478
|
break;
|
|
1479
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
|
|
1480
|
+
this.documentsSchemaController.processDocumentSchemaOp(messageWithContext.message.contents, messageWithContext.local, messageWithContext.message.sequenceNumber);
|
|
1481
|
+
break;
|
|
1399
1482
|
default: {
|
|
1400
1483
|
// If we didn't necessarily expect a runtime message type, then no worries - just return
|
|
1401
1484
|
// e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
|
|
@@ -1625,6 +1708,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1625
1708
|
}
|
|
1626
1709
|
break;
|
|
1627
1710
|
}
|
|
1711
|
+
case messageTypes_js_1.ContainerMessageType.IdAllocation:
|
|
1712
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
|
|
1628
1713
|
case messageTypes_js_1.ContainerMessageType.GC: {
|
|
1629
1714
|
return false;
|
|
1630
1715
|
}
|
|
@@ -1691,15 +1776,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1691
1776
|
}
|
|
1692
1777
|
const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
|
|
1693
1778
|
// Wrap data store summaries in .channels subtree.
|
|
1694
|
-
(0,
|
|
1779
|
+
(0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
|
|
1695
1780
|
this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
|
|
1696
1781
|
return summarizeResult.summary;
|
|
1697
1782
|
}
|
|
1698
1783
|
async summarizeInternal(fullTree, trackState, telemetryContext) {
|
|
1699
1784
|
const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
|
|
1700
1785
|
// Wrap data store summaries in .channels subtree.
|
|
1701
|
-
(0,
|
|
1786
|
+
(0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
|
|
1702
1787
|
const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
|
|
1788
|
+
// Ensure that ID compressor had a chance to load, if we are using delayed mode.
|
|
1789
|
+
await this.loadIdCompressor();
|
|
1703
1790
|
this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
|
|
1704
1791
|
return {
|
|
1705
1792
|
...summarizeResult,
|
|
@@ -1812,9 +1899,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1812
1899
|
*/
|
|
1813
1900
|
getNodeType(nodePath) {
|
|
1814
1901
|
if (this.isBlobPath(nodePath)) {
|
|
1815
|
-
return
|
|
1902
|
+
return index_js_1.GCNodeType.Blob;
|
|
1816
1903
|
}
|
|
1817
|
-
return this.channelCollection.getGCNodeType(nodePath) ??
|
|
1904
|
+
return this.channelCollection.getGCNodeType(nodePath) ?? index_js_1.GCNodeType.Other;
|
|
1818
1905
|
}
|
|
1819
1906
|
/**
|
|
1820
1907
|
* Called by GC to retrieve the package path of the node with the given path. The node should belong to a
|
|
@@ -1827,10 +1914,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1827
1914
|
return ["_gcRoot"];
|
|
1828
1915
|
}
|
|
1829
1916
|
switch (this.getNodeType(nodePath)) {
|
|
1830
|
-
case
|
|
1917
|
+
case index_js_1.GCNodeType.Blob:
|
|
1831
1918
|
return [blobManager_js_1.BlobManager.basePath];
|
|
1832
|
-
case
|
|
1833
|
-
case
|
|
1919
|
+
case index_js_1.GCNodeType.DataStore:
|
|
1920
|
+
case index_js_1.GCNodeType.SubDataStore:
|
|
1834
1921
|
return this.channelCollection.getDataStorePackagePath(nodePath);
|
|
1835
1922
|
default:
|
|
1836
1923
|
(0, core_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
|
|
@@ -2042,7 +2129,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2042
2129
|
const validateResult = this.summarizerNode.validateSummary();
|
|
2043
2130
|
if (!validateResult.success) {
|
|
2044
2131
|
const { success, ...loggingProps } = validateResult;
|
|
2045
|
-
const error = new
|
|
2132
|
+
const error = new index_js_3.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
|
|
2046
2133
|
return {
|
|
2047
2134
|
stage: "base",
|
|
2048
2135
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
@@ -2189,7 +2276,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2189
2276
|
// based on telemetry while we decide on a stable number.
|
|
2190
2277
|
const retryDelayMs = this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
|
|
2191
2278
|
exports.defaultPendingOpsRetryDelayMs;
|
|
2192
|
-
const error = new
|
|
2279
|
+
const error = new index_js_3.RetriableSummaryError("PendingOpsWhileSummarizing", retryDelayMs / 1000, {
|
|
2193
2280
|
count: this.pendingMessagesCount,
|
|
2194
2281
|
beforeGenerate: beforeSummaryGeneration,
|
|
2195
2282
|
});
|
|
@@ -2242,19 +2329,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2242
2329
|
const idAllocationBatchMessage = {
|
|
2243
2330
|
contents: JSON.stringify(idAllocationMessage),
|
|
2244
2331
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2245
|
-
metadata: undefined,
|
|
2246
|
-
localOpMetadata: undefined,
|
|
2247
|
-
type: messageTypes_js_1.ContainerMessageType.IdAllocation,
|
|
2248
2332
|
};
|
|
2249
2333
|
this.outbox.submitIdAllocation(idAllocationBatchMessage);
|
|
2250
2334
|
}
|
|
2251
2335
|
}
|
|
2252
2336
|
}
|
|
2253
|
-
submit(containerRuntimeMessage, localOpMetadata = undefined, metadata
|
|
2337
|
+
submit(containerRuntimeMessage, localOpMetadata = undefined, metadata) {
|
|
2254
2338
|
this.verifyNotClosed();
|
|
2255
2339
|
this.verifyCanSubmitOps();
|
|
2256
2340
|
// There should be no ops in detached container state!
|
|
2257
2341
|
(0, core_utils_1.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
|
|
2342
|
+
(0, core_utils_1.assert)(metadata === undefined ||
|
|
2343
|
+
containerRuntimeMessage.type === messageTypes_js_1.ContainerMessageType.BlobAttach, "metadata");
|
|
2258
2344
|
const serializedContent = JSON.stringify(containerRuntimeMessage);
|
|
2259
2345
|
// Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
|
|
2260
2346
|
// container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
|
|
@@ -2267,7 +2353,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2267
2353
|
const type = containerRuntimeMessage.type;
|
|
2268
2354
|
const message = {
|
|
2269
2355
|
contents: serializedContent,
|
|
2270
|
-
type,
|
|
2271
2356
|
metadata,
|
|
2272
2357
|
localOpMetadata,
|
|
2273
2358
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
@@ -2282,6 +2367,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2282
2367
|
}
|
|
2283
2368
|
else {
|
|
2284
2369
|
this.submitIdAllocationOpIfNeeded();
|
|
2370
|
+
// Allow document schema controller to send a message if it needs to propose change in document schema.
|
|
2371
|
+
// If it needs to send a message, it will call provided callback with payload of such message and rely
|
|
2372
|
+
// on this callback to do actual sending.
|
|
2373
|
+
this.documentsSchemaController.onMessageSent((contents) => {
|
|
2374
|
+
const msg = {
|
|
2375
|
+
type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
|
|
2376
|
+
contents,
|
|
2377
|
+
};
|
|
2378
|
+
this.outbox.submit({
|
|
2379
|
+
contents: JSON.stringify(msg),
|
|
2380
|
+
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2381
|
+
});
|
|
2382
|
+
});
|
|
2285
2383
|
// If this is attach message for new data store, and we are in a batch, send this op out of order
|
|
2286
2384
|
// Is it safe:
|
|
2287
2385
|
// Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
|
|
@@ -2388,7 +2486,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2388
2486
|
if (this.opReentryCallsToReport > 0) {
|
|
2389
2487
|
this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
|
|
2390
2488
|
// We need to capture the call stack in order to inspect the source of this usage pattern
|
|
2391
|
-
(0,
|
|
2489
|
+
(0, index_js_2.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
|
|
2392
2490
|
this.opReentryCallsToReport--;
|
|
2393
2491
|
}
|
|
2394
2492
|
// Creating ops while processing ops can lead
|
|
@@ -2453,6 +2551,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2453
2551
|
case messageTypes_js_1.ContainerMessageType.GC:
|
|
2454
2552
|
this.submit(message);
|
|
2455
2553
|
break;
|
|
2554
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
|
|
2555
|
+
// There is no need to resend this message. Document schema controller will properly resend it again (if needed)
|
|
2556
|
+
// on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
|
|
2557
|
+
// send any ops, as some other client already changed schema.
|
|
2558
|
+
break;
|
|
2456
2559
|
default: {
|
|
2457
2560
|
// This case should be very rare - it would imply an op was stashed from a
|
|
2458
2561
|
// future version of runtime code and now is being applied on an older version.
|
|
@@ -2655,8 +2758,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2655
2758
|
}
|
|
2656
2759
|
}
|
|
2657
2760
|
get groupedBatchingEnabled() {
|
|
2658
|
-
|
|
2659
|
-
return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
|
|
2761
|
+
return this.documentSchema.opGroupingEnabled === true;
|
|
2660
2762
|
}
|
|
2661
2763
|
}
|
|
2662
2764
|
exports.ContainerRuntime = ContainerRuntime;
|