@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
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { decompress } from "lz4js";
|
|
7
|
-
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { assert } from "@fluidframework/core-utils";
|
|
9
6
|
import { IsoBuffer, Uint8ArrayToString } from "@fluid-internal/client-utils";
|
|
10
|
-
import { createChildLogger } from "@fluidframework/telemetry-utils";
|
|
11
7
|
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
|
+
import { assert } from "@fluidframework/core-utils";
|
|
9
|
+
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
10
|
+
import { createChildLogger } from "@fluidframework/telemetry-utils";
|
|
11
|
+
import { decompress } from "lz4js";
|
|
12
12
|
import { CompressionAlgorithms } from "../containerRuntime.js";
|
|
13
13
|
import { IBatchMetadata } from "../metadata.js";
|
|
14
|
-
import { IMessageProcessingResult } from "./definitions.js";
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Compression makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
|
|
@@ -38,100 +37,7 @@ export class OpDecompressor {
|
|
|
38
37
|
this.logger = createChildLogger({ logger, namespace: "OpDecompressor" });
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
public
|
|
42
|
-
assert(
|
|
43
|
-
message.compression === undefined || message.compression === CompressionAlgorithms.lz4,
|
|
44
|
-
0x511 /* Only lz4 compression is supported */,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
(message.metadata as IBatchMetadata | undefined)?.batch === true &&
|
|
49
|
-
this.isCompressed(message)
|
|
50
|
-
) {
|
|
51
|
-
// Beginning of a compressed batch
|
|
52
|
-
assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
|
|
53
|
-
this.activeBatch = true;
|
|
54
|
-
|
|
55
|
-
const contents = IsoBuffer.from(
|
|
56
|
-
(message.contents as IPackedContentsContents).packedContents,
|
|
57
|
-
"base64",
|
|
58
|
-
);
|
|
59
|
-
const decompressedMessage = decompress(contents);
|
|
60
|
-
const intoString = Uint8ArrayToString(decompressedMessage);
|
|
61
|
-
const asObj = JSON.parse(intoString);
|
|
62
|
-
this.rootMessageContents = asObj;
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
message: newMessage(message, this.rootMessageContents[this.processedCount++]),
|
|
66
|
-
state: "Accepted",
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
this.rootMessageContents !== undefined &&
|
|
72
|
-
(message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
|
|
73
|
-
this.activeBatch
|
|
74
|
-
) {
|
|
75
|
-
assert(message.contents === undefined, 0x512 /* Expecting empty message */);
|
|
76
|
-
|
|
77
|
-
// Continuation of compressed batch
|
|
78
|
-
return {
|
|
79
|
-
message: newMessage(message, this.rootMessageContents[this.processedCount++]),
|
|
80
|
-
state: "Accepted",
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
this.rootMessageContents !== undefined &&
|
|
86
|
-
(message.metadata as IBatchMetadata | undefined)?.batch === false
|
|
87
|
-
) {
|
|
88
|
-
// End of compressed batch
|
|
89
|
-
const returnMessage = newMessage(
|
|
90
|
-
message,
|
|
91
|
-
this.rootMessageContents[this.processedCount++],
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
this.activeBatch = false;
|
|
95
|
-
this.rootMessageContents = undefined;
|
|
96
|
-
this.processedCount = 0;
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
message: returnMessage,
|
|
100
|
-
state: "Processed",
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
(message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
|
|
106
|
-
this.isCompressed(message)
|
|
107
|
-
) {
|
|
108
|
-
// Single compressed message
|
|
109
|
-
assert(
|
|
110
|
-
this.activeBatch === false,
|
|
111
|
-
0x4ba /* shouldn't receive compressed message in middle of a batch */,
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
const contents = IsoBuffer.from(
|
|
115
|
-
(message.contents as IPackedContentsContents).packedContents,
|
|
116
|
-
"base64",
|
|
117
|
-
);
|
|
118
|
-
const decompressedMessage = decompress(contents);
|
|
119
|
-
const intoString = new TextDecoder().decode(decompressedMessage);
|
|
120
|
-
const asObj = JSON.parse(intoString);
|
|
121
|
-
|
|
122
|
-
return {
|
|
123
|
-
message: newMessage(message, asObj[0]),
|
|
124
|
-
state: "Processed",
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
message,
|
|
130
|
-
state: "Skipped",
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
private isCompressed(message: ISequencedDocumentMessage) {
|
|
40
|
+
public isCompressedMessage(message: ISequencedDocumentMessage): boolean {
|
|
135
41
|
if (message.compression === CompressionAlgorithms.lz4) {
|
|
136
42
|
return true;
|
|
137
43
|
}
|
|
@@ -174,6 +80,80 @@ export class OpDecompressor {
|
|
|
174
80
|
|
|
175
81
|
return false;
|
|
176
82
|
}
|
|
83
|
+
|
|
84
|
+
public get currentlyUnrolling() {
|
|
85
|
+
return this.activeBatch;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Is the decompressed and stored batch only comprised of a single message */
|
|
89
|
+
private isSingleMessageBatch = false;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Decompress the given compressed message and store it to be subsequently unrolled.
|
|
93
|
+
* The stored message will be of type `any[]` where each element represents a message's `contents`
|
|
94
|
+
*/
|
|
95
|
+
public decompressAndStore(message: ISequencedDocumentMessage): void {
|
|
96
|
+
assert(
|
|
97
|
+
message.compression === undefined || message.compression === CompressionAlgorithms.lz4,
|
|
98
|
+
0x511 /* Only lz4 compression is supported */,
|
|
99
|
+
);
|
|
100
|
+
assert(this.isCompressedMessage(message), "provided message should be compressed");
|
|
101
|
+
|
|
102
|
+
assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
|
|
103
|
+
this.activeBatch = true;
|
|
104
|
+
|
|
105
|
+
const batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;
|
|
106
|
+
if (batchMetadata === undefined) {
|
|
107
|
+
this.isSingleMessageBatch = true;
|
|
108
|
+
} else {
|
|
109
|
+
assert(batchMetadata === true, "invalid batch metadata");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const contents = IsoBuffer.from(
|
|
113
|
+
(message.contents as IPackedContentsContents).packedContents,
|
|
114
|
+
"base64",
|
|
115
|
+
);
|
|
116
|
+
const decompressedMessage = decompress(contents);
|
|
117
|
+
const intoString = Uint8ArrayToString(decompressedMessage);
|
|
118
|
+
const asObj = JSON.parse(intoString);
|
|
119
|
+
this.rootMessageContents = asObj;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Unroll the next message from the decompressed content provided to {@link decompressAndStore}
|
|
124
|
+
* @returns the unrolled `ISequencedDocumentMessage`
|
|
125
|
+
*/
|
|
126
|
+
public unroll(message: ISequencedDocumentMessage): ISequencedDocumentMessage {
|
|
127
|
+
assert(this.currentlyUnrolling, "not currently unrolling");
|
|
128
|
+
assert(this.rootMessageContents !== undefined, "missing rootMessageContents");
|
|
129
|
+
assert(this.rootMessageContents.length > this.processedCount, "no more content to unroll");
|
|
130
|
+
|
|
131
|
+
const batchMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;
|
|
132
|
+
|
|
133
|
+
if (batchMetadata === false || this.isSingleMessageBatch) {
|
|
134
|
+
// End of compressed batch
|
|
135
|
+
const returnMessage = newMessage(
|
|
136
|
+
message,
|
|
137
|
+
this.rootMessageContents[this.processedCount],
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
this.activeBatch = false;
|
|
141
|
+
this.isSingleMessageBatch = false;
|
|
142
|
+
this.rootMessageContents = undefined;
|
|
143
|
+
this.processedCount = 0;
|
|
144
|
+
|
|
145
|
+
return returnMessage;
|
|
146
|
+
} else if (batchMetadata === true) {
|
|
147
|
+
// Start of compressed batch
|
|
148
|
+
return newMessage(message, this.rootMessageContents[this.processedCount++]);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
assert(batchMetadata === undefined, "invalid batch metadata");
|
|
152
|
+
assert(message.contents === undefined, 0x512 /* Expecting empty message */);
|
|
153
|
+
|
|
154
|
+
// Continuation of compressed batch
|
|
155
|
+
return newMessage(message, this.rootMessageContents[this.processedCount++]);
|
|
156
|
+
}
|
|
177
157
|
}
|
|
178
158
|
|
|
179
159
|
// We should not be mutating the input message nor its metadata
|
|
@@ -186,5 +166,8 @@ const newMessage = (
|
|
|
186
166
|
compression: undefined,
|
|
187
167
|
// TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.
|
|
188
168
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
189
|
-
metadata:
|
|
169
|
+
metadata:
|
|
170
|
+
originalMessage.metadata === undefined
|
|
171
|
+
? undefined
|
|
172
|
+
: { ...(originalMessage.metadata as any) },
|
|
190
173
|
});
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
6
7
|
import { assert } from "@fluidframework/core-utils";
|
|
7
8
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
8
9
|
import { createChildLogger } from "@fluidframework/telemetry-utils";
|
|
9
|
-
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
10
|
-
import { ContainerMessageType } from "../messageTypes.js";
|
|
11
10
|
import { IBatch } from "./definitions.js";
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -28,6 +27,10 @@ function isGroupContents(opContents: any): opContents is IGroupedBatchMessageCon
|
|
|
28
27
|
return opContents?.type === OpGroupingManager.groupedBatchOp;
|
|
29
28
|
}
|
|
30
29
|
|
|
30
|
+
export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
|
|
31
|
+
return isGroupContents(op.contents);
|
|
32
|
+
}
|
|
33
|
+
|
|
31
34
|
export interface OpGroupingManagerConfig {
|
|
32
35
|
readonly groupedBatchingEnabled: boolean;
|
|
33
36
|
readonly opCountThreshold: number;
|
|
@@ -46,9 +49,7 @@ export class OpGroupingManager {
|
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
public groupBatch(batch: IBatch): IBatch {
|
|
49
|
-
|
|
50
|
-
return batch;
|
|
51
|
-
}
|
|
52
|
+
assert(this.shouldGroup(batch), "cannot group the provided batch");
|
|
52
53
|
|
|
53
54
|
if (batch.content.length >= 1000) {
|
|
54
55
|
this.logger.sendTelemetryEvent({
|
|
@@ -84,11 +85,9 @@ export class OpGroupingManager {
|
|
|
84
85
|
...batch,
|
|
85
86
|
content: [
|
|
86
87
|
{
|
|
87
|
-
localOpMetadata: undefined,
|
|
88
88
|
metadata: undefined,
|
|
89
89
|
referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
|
|
90
90
|
contents: serializedContent,
|
|
91
|
-
type: OpGroupingManager.groupedBatchOp as ContainerMessageType,
|
|
92
91
|
},
|
|
93
92
|
],
|
|
94
93
|
};
|
|
@@ -96,13 +95,11 @@ export class OpGroupingManager {
|
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
public ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
98
|
+
assert(isGroupContents(op.contents), "can only ungroup a grouped batch");
|
|
99
|
+
const contents: IGroupedBatchMessageContents = op.contents;
|
|
102
100
|
|
|
103
|
-
const messages = op.contents.contents;
|
|
104
101
|
let fakeCsn = 1;
|
|
105
|
-
return
|
|
102
|
+
return contents.contents.map((subMessage) => ({
|
|
106
103
|
...op,
|
|
107
104
|
clientSequenceNumber: fakeCsn++,
|
|
108
105
|
contents: subMessage.contents,
|
|
@@ -3,18 +3,31 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { IBatchMessage } from "@fluidframework/container-definitions";
|
|
7
|
+
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
|
+
import { assert } from "@fluidframework/core-utils";
|
|
9
|
+
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
6
10
|
import {
|
|
7
|
-
createChildLogger,
|
|
8
11
|
DataCorruptionError,
|
|
12
|
+
createChildLogger,
|
|
9
13
|
extractSafePropertiesFromMessage,
|
|
10
14
|
} from "@fluidframework/telemetry-utils";
|
|
11
|
-
import { assert } from "@fluidframework/core-utils";
|
|
12
|
-
import { IBatchMessage } from "@fluidframework/container-definitions";
|
|
13
|
-
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
14
|
-
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
15
15
|
import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
|
|
16
16
|
import { estimateSocketSize } from "./batchManager.js";
|
|
17
|
-
import { BatchMessage, IBatch, IChunkedOp
|
|
17
|
+
import { BatchMessage, IBatch, IChunkedOp } from "./definitions.js";
|
|
18
|
+
|
|
19
|
+
export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
|
|
20
|
+
return isChunkedContents(message.contents);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface IChunkedContents {
|
|
24
|
+
type: typeof ContainerMessageType.ChunkedOp;
|
|
25
|
+
contents: IChunkedOp;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isChunkedContents(contents: any): contents is IChunkedContents {
|
|
29
|
+
return contents?.type === ContainerMessageType.ChunkedOp;
|
|
30
|
+
}
|
|
18
31
|
|
|
19
32
|
/**
|
|
20
33
|
* Responsible for creating and reconstructing chunked messages.
|
|
@@ -45,44 +58,6 @@ export class OpSplitter {
|
|
|
45
58
|
return this.chunkMap;
|
|
46
59
|
}
|
|
47
60
|
|
|
48
|
-
public processRemoteMessage(message: ISequencedDocumentMessage): IMessageProcessingResult {
|
|
49
|
-
if (message.type !== ContainerMessageType.ChunkedOp) {
|
|
50
|
-
return {
|
|
51
|
-
message,
|
|
52
|
-
state: "Skipped",
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
58
|
-
const clientId = message.clientId as string;
|
|
59
|
-
const chunkedContent = message.contents as IChunkedOp;
|
|
60
|
-
this.addChunk(clientId, chunkedContent, message);
|
|
61
|
-
|
|
62
|
-
if (chunkedContent.chunkId < chunkedContent.totalChunks) {
|
|
63
|
-
// We are processing the op in chunks but haven't reached
|
|
64
|
-
// the last chunk yet in order to reconstruct the original op
|
|
65
|
-
return {
|
|
66
|
-
message,
|
|
67
|
-
state: "Accepted",
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
72
|
-
const serializedContent = this.chunkMap.get(clientId)!.join("");
|
|
73
|
-
this.clearPartialChunks(clientId);
|
|
74
|
-
|
|
75
|
-
const newMessage = { ...message };
|
|
76
|
-
newMessage.contents = serializedContent === "" ? undefined : JSON.parse(serializedContent);
|
|
77
|
-
newMessage.type = chunkedContent.originalType;
|
|
78
|
-
newMessage.metadata = chunkedContent.originalMetadata;
|
|
79
|
-
newMessage.compression = chunkedContent.originalCompression;
|
|
80
|
-
return {
|
|
81
|
-
message: newMessage,
|
|
82
|
-
state: "Processed",
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
61
|
public clearPartialChunks(clientId: string) {
|
|
87
62
|
if (this.chunkMap.has(clientId)) {
|
|
88
63
|
this.chunkMap.delete(clientId);
|
|
@@ -203,8 +178,53 @@ export class OpSplitter {
|
|
|
203
178
|
referenceSequenceNumber: batch.referenceSequenceNumber,
|
|
204
179
|
};
|
|
205
180
|
}
|
|
181
|
+
|
|
182
|
+
public processChunk(message: ISequencedDocumentMessage): ProcessChunkResult {
|
|
183
|
+
assert(isChunkedContents(message.contents), "message not of type ChunkedOp");
|
|
184
|
+
const contents: IChunkedContents = message.contents;
|
|
185
|
+
|
|
186
|
+
// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
|
|
187
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
188
|
+
const clientId = message.clientId as string;
|
|
189
|
+
const chunkedContent = contents.contents;
|
|
190
|
+
this.addChunk(clientId, chunkedContent, message);
|
|
191
|
+
|
|
192
|
+
if (chunkedContent.chunkId < chunkedContent.totalChunks) {
|
|
193
|
+
// We are processing the op in chunks but haven't reached
|
|
194
|
+
// the last chunk yet in order to reconstruct the original op
|
|
195
|
+
return {
|
|
196
|
+
isFinalChunk: false,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
201
|
+
const serializedContent = this.chunkMap.get(clientId)!.join("");
|
|
202
|
+
this.clearPartialChunks(clientId);
|
|
203
|
+
|
|
204
|
+
const newMessage = { ...message };
|
|
205
|
+
newMessage.contents = serializedContent === "" ? undefined : JSON.parse(serializedContent);
|
|
206
|
+
// back-compat with 1.x builds
|
|
207
|
+
// This is only required / present for non-compressed, chunked ops
|
|
208
|
+
// For compressed ops, we have op grouping enabled, and type of each op is preserved within compressed content.
|
|
209
|
+
newMessage.type = (chunkedContent as any).originalType;
|
|
210
|
+
newMessage.metadata = chunkedContent.originalMetadata;
|
|
211
|
+
newMessage.compression = chunkedContent.originalCompression;
|
|
212
|
+
return {
|
|
213
|
+
message: newMessage,
|
|
214
|
+
isFinalChunk: true,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
206
217
|
}
|
|
207
218
|
|
|
219
|
+
type ProcessChunkResult =
|
|
220
|
+
| {
|
|
221
|
+
readonly isFinalChunk: false;
|
|
222
|
+
}
|
|
223
|
+
| {
|
|
224
|
+
readonly isFinalChunk: true;
|
|
225
|
+
readonly message: ISequencedDocumentMessage;
|
|
226
|
+
};
|
|
227
|
+
|
|
208
228
|
const chunkToBatchMessage = (
|
|
209
229
|
chunk: IChunkedOp,
|
|
210
230
|
referenceSequenceNumber: number,
|
|
@@ -216,9 +236,7 @@ const chunkToBatchMessage = (
|
|
|
216
236
|
};
|
|
217
237
|
return {
|
|
218
238
|
contents: JSON.stringify(payload),
|
|
219
|
-
type: payload.type,
|
|
220
239
|
metadata,
|
|
221
|
-
localOpMetadata: undefined,
|
|
222
240
|
referenceSequenceNumber,
|
|
223
241
|
};
|
|
224
242
|
};
|
|
@@ -253,7 +271,6 @@ export const splitOp = (
|
|
|
253
271
|
const chunk: IChunkedOp = {
|
|
254
272
|
chunkId,
|
|
255
273
|
contents: op.contents.substr(offset, chunkSizeInBytes),
|
|
256
|
-
originalType: op.type,
|
|
257
274
|
totalChunks: chunkCount,
|
|
258
275
|
};
|
|
259
276
|
|
|
@@ -263,6 +280,15 @@ export const splitOp = (
|
|
|
263
280
|
// last chunk, therefore it is the only one that needs it.
|
|
264
281
|
chunk.originalMetadata = op.metadata;
|
|
265
282
|
chunk.originalCompression = op.compression;
|
|
283
|
+
|
|
284
|
+
// back-compat with 1.x builds
|
|
285
|
+
// 2.x builds only do chunking for compressed ops.
|
|
286
|
+
// originalType is no longer used in such cases, as each op preserves its type within compressed payload.
|
|
287
|
+
// But, if 1.x builds see this op, and there is no type on the message, then it will ignore this message silently.
|
|
288
|
+
// This is really bad, as we will crash on later ops and it's very hard to debug these cases.
|
|
289
|
+
// If we put some known type here, then we will crash on it (as 1.x does not understand compression, and thus will not
|
|
290
|
+
// find info on the op like address of the channel to deliver the op)
|
|
291
|
+
(chunk as any).originalType = "component";
|
|
266
292
|
}
|
|
267
293
|
|
|
268
294
|
chunks.push(chunk);
|
|
@@ -3,18 +3,17 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { IBatchMessage, ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
7
|
+
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
|
+
import { assert } from "@fluidframework/core-utils";
|
|
6
9
|
import {
|
|
7
|
-
createChildMonitoringContext,
|
|
8
10
|
GenericError,
|
|
9
11
|
MonitoringContext,
|
|
10
12
|
UsageError,
|
|
13
|
+
createChildMonitoringContext,
|
|
11
14
|
} from "@fluidframework/telemetry-utils";
|
|
12
|
-
import { assert } from "@fluidframework/core-utils";
|
|
13
|
-
import { IBatchMessage, ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
14
|
-
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
15
15
|
import { ICompressionRuntimeOptions } from "../containerRuntime.js";
|
|
16
16
|
import { IPendingBatchMessage, PendingStateManager } from "../pendingStateManager.js";
|
|
17
|
-
import { ContainerMessageType } from "../messageTypes.js";
|
|
18
17
|
import {
|
|
19
18
|
BatchManager,
|
|
20
19
|
BatchSequenceNumbers,
|
|
@@ -120,7 +119,12 @@ export class Outbox {
|
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
public get messageCount(): number {
|
|
123
|
-
return
|
|
122
|
+
return (
|
|
123
|
+
this.attachFlowBatch.length +
|
|
124
|
+
this.mainBatch.length +
|
|
125
|
+
this.blobAttachBatch.length +
|
|
126
|
+
this.idAllocationBatch.length
|
|
127
|
+
);
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
public get isEmpty(): boolean {
|
|
@@ -182,20 +186,12 @@ export class Outbox {
|
|
|
182
186
|
}
|
|
183
187
|
|
|
184
188
|
public submit(message: BatchMessage) {
|
|
185
|
-
assert(
|
|
186
|
-
message.type !== ContainerMessageType.IdAllocation,
|
|
187
|
-
0x8f8 /* Allocation message submitted to mainBatch. */,
|
|
188
|
-
);
|
|
189
189
|
this.maybeFlushPartialBatch();
|
|
190
190
|
|
|
191
191
|
this.addMessageToBatchManager(this.mainBatch, message);
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
public submitAttach(message: BatchMessage) {
|
|
195
|
-
assert(
|
|
196
|
-
message.type === ContainerMessageType.Attach,
|
|
197
|
-
0x8f9 /* Non attach message submitted to attachFlowBatch. */,
|
|
198
|
-
);
|
|
199
195
|
this.maybeFlushPartialBatch();
|
|
200
196
|
|
|
201
197
|
if (
|
|
@@ -227,10 +223,6 @@ export class Outbox {
|
|
|
227
223
|
}
|
|
228
224
|
|
|
229
225
|
public submitBlobAttach(message: BatchMessage) {
|
|
230
|
-
assert(
|
|
231
|
-
message.type === ContainerMessageType.BlobAttach,
|
|
232
|
-
0x8fa /* Non blobAttach message submitted to blobAttachBatch. */,
|
|
233
|
-
);
|
|
234
226
|
this.maybeFlushPartialBatch();
|
|
235
227
|
|
|
236
228
|
this.addMessageToBatchManager(this.blobAttachBatch, message);
|
|
@@ -249,10 +241,6 @@ export class Outbox {
|
|
|
249
241
|
}
|
|
250
242
|
|
|
251
243
|
public submitIdAllocation(message: BatchMessage) {
|
|
252
|
-
assert(
|
|
253
|
-
message.type === ContainerMessageType.IdAllocation,
|
|
254
|
-
0x8fb /* Non allocation message submitted to idAllocationBatch. */,
|
|
255
|
-
);
|
|
256
244
|
this.maybeFlushPartialBatch();
|
|
257
245
|
|
|
258
246
|
if (
|
|
@@ -323,10 +311,9 @@ export class Outbox {
|
|
|
323
311
|
}
|
|
324
312
|
|
|
325
313
|
const rawBatch = batchManager.popBatch();
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
) {
|
|
314
|
+
const shouldGroup =
|
|
315
|
+
!disableGroupedBatching && this.params.groupingManager.shouldGroup(rawBatch);
|
|
316
|
+
if (rawBatch.hasReentrantOps === true && shouldGroup) {
|
|
330
317
|
assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
|
|
331
318
|
// If a batch contains reentrant ops (ops created as a result from processing another op)
|
|
332
319
|
// it needs to be rebased so that we can ensure consistent reference sequence numbers
|
|
@@ -335,8 +322,15 @@ export class Outbox {
|
|
|
335
322
|
return;
|
|
336
323
|
}
|
|
337
324
|
|
|
338
|
-
|
|
339
|
-
|
|
325
|
+
// Did we disconnect?
|
|
326
|
+
// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
|
|
327
|
+
// Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
|
|
328
|
+
if (this.params.shouldSend()) {
|
|
329
|
+
const processedBatch = this.compressBatch(
|
|
330
|
+
shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
|
|
331
|
+
);
|
|
332
|
+
this.sendBatch(processedBatch);
|
|
333
|
+
}
|
|
340
334
|
|
|
341
335
|
this.persistBatch(rawBatch.content);
|
|
342
336
|
}
|
|
@@ -380,7 +374,7 @@ export class Outbox {
|
|
|
380
374
|
return this.params.opReentrancy() && !this.rebasing;
|
|
381
375
|
}
|
|
382
376
|
|
|
383
|
-
private compressBatch(batch: IBatch
|
|
377
|
+
private compressBatch(batch: IBatch): IBatch {
|
|
384
378
|
if (
|
|
385
379
|
batch.content.length === 0 ||
|
|
386
380
|
this.params.config.compressionOptions === undefined ||
|
|
@@ -389,12 +383,10 @@ export class Outbox {
|
|
|
389
383
|
this.params.submitBatchFn === undefined
|
|
390
384
|
) {
|
|
391
385
|
// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
|
|
392
|
-
return
|
|
386
|
+
return batch;
|
|
393
387
|
}
|
|
394
388
|
|
|
395
|
-
const compressedBatch = this.params.compressor.compressBatch(
|
|
396
|
-
disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch),
|
|
397
|
-
);
|
|
389
|
+
const compressedBatch = this.params.compressor.compressBatch(batch);
|
|
398
390
|
|
|
399
391
|
if (this.params.splitter.isBatchChunkingEnabled) {
|
|
400
392
|
return compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes
|
|
@@ -424,10 +416,7 @@ export class Outbox {
|
|
|
424
416
|
*/
|
|
425
417
|
private sendBatch(batch: IBatch) {
|
|
426
418
|
const length = batch.content.length;
|
|
427
|
-
|
|
428
|
-
// Did we disconnect in the middle of turn-based batch?
|
|
429
|
-
// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
|
|
430
|
-
if (length === 0 || !this.params.shouldSend()) {
|
|
419
|
+
if (length === 0) {
|
|
431
420
|
return;
|
|
432
421
|
}
|
|
433
422
|
|