@fluidframework/container-runtime 2.0.0-rc.2.0.2 → 2.0.0-rc.3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/api-report/container-runtime.api.md +471 -52
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +4 -4
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +33 -30
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +82 -107
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +27 -22
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +155 -165
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +3 -3
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +17 -17
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +2 -2
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +42 -39
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +425 -292
- 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 +8 -8
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +58 -19
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +169 -114
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -0
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +12 -11
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +5 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +4 -4
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/dist/deltaManagerSummarizerProxy.js.map +1 -1
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +6 -6
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +4 -4
- package/dist/error.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +3 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +23 -23
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +2 -2
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +4 -5
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +4 -5
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +5 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +21 -12
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +2 -2
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +11 -11
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +2 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +11 -9
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +6 -6
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +91 -0
- 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/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +2 -20
- 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 +5 -6
- 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 +62 -63
- 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 +14 -16
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +12 -4
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +63 -53
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +30 -29
- 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 +18 -18
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/public.d.ts +12 -0
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +28 -24
- package/dist/scheduleManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts +2 -2
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js +2 -2
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +209 -0
- package/dist/summary/documentSchema.d.ts.map +1 -0
- package/dist/summary/documentSchema.js +390 -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 +12 -7
- 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 +3 -3
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +3 -3
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +16 -16
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +3 -2
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +13 -13
- 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 +2 -2
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +3 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +28 -28
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -3
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +14 -14
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +5 -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 +7 -7
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +6 -17
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +8 -8
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +4 -3
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +17 -17
- 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 +15 -14
- package/dist/summary/summaryManager.js.map +1 -1
- package/internal.d.ts +11 -0
- package/legacy.d.ts +11 -0
- 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 +33 -30
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +48 -73
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +27 -22
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +96 -106
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +3 -3
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +3 -3
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +42 -39
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +276 -141
- 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 +3 -3
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +58 -19
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +107 -52
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -0
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +3 -2
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +5 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/lib/deltaManagerSummarizerProxy.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/error.d.ts +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +2 -2
- package/lib/error.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +3 -2
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +8 -8
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +2 -2
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +4 -5
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +4 -5
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +5 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +10 -2
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +2 -2
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +2 -2
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +2 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +4 -2
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +2 -2
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +5 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -2
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +91 -0
- 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/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +2 -20
- 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 +61 -62
- 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 +9 -12
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +12 -4
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +47 -38
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +19 -18
- 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 +2 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/public.d.ts +12 -0
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +7 -3
- package/lib/scheduleManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts +2 -2
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js +1 -1
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +209 -0
- package/lib/summary/documentSchema.d.ts.map +1 -0
- package/lib/summary/documentSchema.js +386 -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 +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +3 -3
- 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 +3 -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 +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +3 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +5 -5
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +5 -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 +6 -17
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +3 -3
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +4 -3
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +4 -4
- 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 +9 -8
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +57 -65
- package/src/batchTracker.ts +4 -3
- package/src/blobManager.ts +100 -77
- package/src/channelCollection.ts +180 -165
- package/src/connectionTelemetry.ts +12 -12
- package/src/containerHandleContext.ts +3 -2
- package/src/containerRuntime.ts +481 -277
- package/src/dataStore.ts +9 -4
- package/src/dataStoreContext.ts +195 -93
- package/src/dataStoreContexts.ts +5 -2
- package/src/dataStoreRegistry.ts +3 -2
- package/src/deltaManagerSummarizerProxy.ts +1 -1
- package/src/deltaScheduler.ts +2 -1
- package/src/error.ts +2 -2
- package/src/gc/garbageCollection.ts +21 -20
- package/src/gc/gcConfigs.ts +15 -18
- package/src/gc/gcDefinitions.ts +6 -8
- package/src/gc/gcHelpers.ts +22 -5
- package/src/gc/gcSummaryStateTracker.ts +7 -5
- package/src/gc/gcTelemetry.ts +13 -7
- package/src/gc/gcUnreferencedStateTracker.ts +3 -2
- package/src/gc/index.ts +1 -0
- package/src/index.ts +22 -1
- package/src/messageTypes.ts +20 -6
- package/src/opLifecycle/README.md +89 -0
- package/src/opLifecycle/batchManager.ts +1 -0
- package/src/opLifecycle/definitions.ts +3 -21
- package/src/opLifecycle/index.ts +3 -9
- package/src/opLifecycle/opCompressor.ts +6 -5
- package/src/opLifecycle/opDecompressor.ts +90 -100
- package/src/opLifecycle/opGroupingManager.ts +12 -14
- package/src/opLifecycle/opSplitter.ts +76 -48
- package/src/opLifecycle/outbox.ts +30 -38
- package/src/opLifecycle/remoteMessageProcessor.ts +43 -55
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +6 -6
- package/src/scheduleManager.ts +10 -8
- package/src/storageServiceWithAttachBlobs.ts +2 -2
- package/src/summary/documentSchema.ts +631 -0
- package/src/summary/index.ts +10 -1
- package/src/summary/orderedClientElection.ts +7 -7
- package/src/summary/runWhileConnectedCoordinator.ts +3 -2
- package/src/summary/runningSummarizer.ts +22 -20
- package/src/summary/summarizer.ts +17 -15
- package/src/summary/summarizerClientElection.ts +3 -2
- package/src/summary/summarizerHeuristics.ts +4 -2
- package/src/summary/summarizerNode/summarizerNode.ts +20 -18
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -2
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +16 -8
- package/src/summary/summarizerTypes.ts +7 -3
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +14 -26
- package/src/summary/summaryGenerator.ts +12 -15
- package/src/summary/summaryManager.ts +16 -13
- package/api-extractor-cjs.json +0 -8
- package/dist/container-runtime-alpha.d.ts +0 -1753
- package/dist/container-runtime-beta.d.ts +0 -268
- package/dist/container-runtime-public.d.ts +0 -268
- package/dist/container-runtime-untrimmed.d.ts +0 -1893
- package/lib/container-runtime-alpha.d.ts +0 -1753
- package/lib/container-runtime-beta.d.ts +0 -268
- package/lib/container-runtime-public.d.ts +0 -268
- package/lib/container-runtime-untrimmed.d.ts +0 -1893
- package/lib/test/batchTracker.spec.js +0 -88
- package/lib/test/batchTracker.spec.js.map +0 -1
- package/lib/test/blobManager.spec.js +0 -835
- package/lib/test/blobManager.spec.js.map +0 -1
- package/lib/test/channelCollection.spec.js +0 -141
- package/lib/test/channelCollection.spec.js.map +0 -1
- package/lib/test/containerRuntime.spec.js +0 -1748
- package/lib/test/containerRuntime.spec.js.map +0 -1
- package/lib/test/dataStoreContext.spec.js +0 -801
- package/lib/test/dataStoreContext.spec.js.map +0 -1
- package/lib/test/dataStoreCreation.spec.js +0 -312
- package/lib/test/dataStoreCreation.spec.js.map +0 -1
- package/lib/test/dataStoreRegistry.spec.js +0 -26
- package/lib/test/dataStoreRegistry.spec.js.map +0 -1
- package/lib/test/fuzz/fuzzUtils.js +0 -66
- package/lib/test/fuzz/fuzzUtils.js.map +0 -1
- package/lib/test/fuzz/summarizer.fuzz.spec.js +0 -31
- package/lib/test/fuzz/summarizer.fuzz.spec.js.map +0 -1
- package/lib/test/fuzz/summarizerFuzzMocks.js +0 -162
- package/lib/test/fuzz/summarizerFuzzMocks.js.map +0 -1
- package/lib/test/fuzz/summarizerFuzzSuite.js +0 -106
- package/lib/test/fuzz/summarizerFuzzSuite.js.map +0 -1
- package/lib/test/gc/garbageCollection.spec.js +0 -1465
- package/lib/test/gc/garbageCollection.spec.js.map +0 -1
- package/lib/test/gc/gcConfigs.spec.js +0 -690
- package/lib/test/gc/gcConfigs.spec.js.map +0 -1
- package/lib/test/gc/gcHelpers.spec.js +0 -110
- package/lib/test/gc/gcHelpers.spec.js.map +0 -1
- package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js +0 -68
- package/lib/test/gc/gcReferenceGraphAlgorithm.spec.js.map +0 -1
- package/lib/test/gc/gcStats.spec.js +0 -391
- package/lib/test/gc/gcStats.spec.js.map +0 -1
- package/lib/test/gc/gcSummaryStateTracker.spec.js +0 -228
- package/lib/test/gc/gcSummaryStateTracker.spec.js.map +0 -1
- package/lib/test/gc/gcTelemetry.spec.js +0 -530
- package/lib/test/gc/gcTelemetry.spec.js.map +0 -1
- package/lib/test/gc/gcUnitTestHelpers.js +0 -29
- package/lib/test/gc/gcUnitTestHelpers.js.map +0 -1
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js +0 -192
- package/lib/test/gc/gcUnreferencedStateTracker.spec.js.map +0 -1
- package/lib/test/getPendingBlobs.spec.js +0 -193
- package/lib/test/getPendingBlobs.spec.js.map +0 -1
- package/lib/test/hardwareStats.spec.js +0 -93
- package/lib/test/hardwareStats.spec.js.map +0 -1
- package/lib/test/index.js +0 -6
- package/lib/test/index.js.map +0 -1
- package/lib/test/opLifecycle/OpGroupingManager.spec.js +0 -225
- package/lib/test/opLifecycle/OpGroupingManager.spec.js.map +0 -1
- package/lib/test/opLifecycle/batchManager.spec.js +0 -189
- package/lib/test/opLifecycle/batchManager.spec.js.map +0 -1
- package/lib/test/opLifecycle/opCompressor.spec.js +0 -74
- package/lib/test/opLifecycle/opCompressor.spec.js.map +0 -1
- package/lib/test/opLifecycle/opDecompressor.spec.js +0 -218
- package/lib/test/opLifecycle/opDecompressor.spec.js.map +0 -1
- package/lib/test/opLifecycle/opSplitter.spec.js +0 -272
- package/lib/test/opLifecycle/opSplitter.spec.js.map +0 -1
- package/lib/test/opLifecycle/outbox.spec.js +0 -675
- package/lib/test/opLifecycle/outbox.spec.js.map +0 -1
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +0 -196
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js.map +0 -1
- package/lib/test/pendingStateManager.spec.js +0 -329
- package/lib/test/pendingStateManager.spec.js.map +0 -1
- package/lib/test/scheduleManager.spec.js +0 -270
- package/lib/test/scheduleManager.spec.js.map +0 -1
- package/lib/test/summarizerNode.spec.js +0 -326
- package/lib/test/summarizerNode.spec.js.map +0 -1
- package/lib/test/summarizerNodeWithGc.spec.js +0 -318
- package/lib/test/summarizerNodeWithGc.spec.js.map +0 -1
- package/lib/test/summary/orderedClientElection.spec.js +0 -535
- package/lib/test/summary/orderedClientElection.spec.js.map +0 -1
- package/lib/test/summary/runningSummarizer.spec.js +0 -1349
- package/lib/test/summary/runningSummarizer.spec.js.map +0 -1
- package/lib/test/summary/summarizer.spec.js +0 -29
- package/lib/test/summary/summarizer.spec.js.map +0 -1
- package/lib/test/summary/summarizerClientElection.spec.js +0 -436
- package/lib/test/summary/summarizerClientElection.spec.js.map +0 -1
- package/lib/test/summary/summarizerHeuristics.spec.js +0 -289
- package/lib/test/summary/summarizerHeuristics.spec.js.map +0 -1
- package/lib/test/summary/summaryCollection.spec.js +0 -200
- package/lib/test/summary/summaryCollection.spec.js.map +0 -1
- package/lib/test/summary/summaryManager.spec.js +0 -430
- package/lib/test/summary/summaryManager.spec.js.map +0 -1
- package/lib/test/summary/testQuorumClients.js +0 -34
- package/lib/test/summary/testQuorumClients.js.map +0 -1
- package/lib/test/throttler.spec.js +0 -175
- package/lib/test/throttler.spec.js.map +0 -1
- package/lib/test/types/validateContainerRuntimePrevious.generated.js +0 -180
- package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +0 -1
- /package/{dist → lib}/tsdoc-metadata.json +0 -0
package/lib/containerRuntime.js
CHANGED
|
@@ -1,29 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
3
5
|
import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
6
|
+
import { AttachState, } from "@fluidframework/container-definitions";
|
|
7
|
+
import { LoaderHeader, } from "@fluidframework/container-definitions/internal";
|
|
8
|
+
import { assert, Deferred, LazyPromise, PromiseCache, delay, } from "@fluidframework/core-utils/internal";
|
|
9
|
+
import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions/internal";
|
|
10
|
+
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
7
11
|
import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { FlushMode, FlushModeExperimental,
|
|
9
|
-
import {
|
|
12
|
+
import { FlushMode, FlushModeExperimental, channelsTreeName, gcTreeKey, } from "@fluidframework/runtime-definitions/internal";
|
|
13
|
+
import { GCDataBuilder, RequestParser, TelemetryContext, addBlobToSummary, addSummarizeResultToSummary, calculateStats, create404Response, exceptionToResponse, responseToException, seqFromTree, } from "@fluidframework/runtime-utils/internal";
|
|
14
|
+
import { DataCorruptionError, DataProcessingError, GenericError, LoggingError, PerformanceEvent,
|
|
15
|
+
// eslint-disable-next-line import/no-deprecated
|
|
16
|
+
TaggedLoggerAdapter, UsageError, createChildLogger, createChildMonitoringContext, createSampledLogger, loggerToMonitoringContext, raiseConnectedEvent, wrapError, } from "@fluidframework/telemetry-utils/internal";
|
|
10
17
|
import { v4 as uuid } from "uuid";
|
|
11
|
-
import {
|
|
12
|
-
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
13
|
-
import { ReportOpPerfTelemetry } from "./connectionTelemetry.js";
|
|
14
|
-
import { PendingStateManager, } from "./pendingStateManager.js";
|
|
15
|
-
import { pkgVersion } from "./packageVersion.js";
|
|
18
|
+
import { BindBatchTracker } from "./batchTracker.js";
|
|
16
19
|
import { BlobManager } from "./blobManager.js";
|
|
17
20
|
import { ChannelCollection, getSummaryForDatastores, wrapContext } from "./channelCollection.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { GarbageCollector, GCNodeType, gcGenerationOptionName, } from "./gc/index.js";
|
|
21
|
+
import { ReportOpPerfTelemetry } from "./connectionTelemetry.js";
|
|
22
|
+
import { ContainerFluidHandleContext } from "./containerHandleContext.js";
|
|
21
23
|
import { channelToDataStore } from "./dataStore.js";
|
|
22
|
-
import {
|
|
23
|
-
import { ScheduleManager } from "./scheduleManager.js";
|
|
24
|
-
import { OpCompressor, OpDecompressor, Outbox, OpSplitter, RemoteMessageProcessor, OpGroupingManager, getLongStack, } from "./opLifecycle/index.js";
|
|
24
|
+
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
25
25
|
import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy.js";
|
|
26
|
+
import { GCNodeType, GarbageCollector, gcGenerationOptionName, } from "./gc/index.js";
|
|
26
27
|
import { ContainerMessageType, } from "./messageTypes.js";
|
|
28
|
+
import { OpCompressor, OpDecompressor, OpGroupingManager, OpSplitter, Outbox, RemoteMessageProcessor, getLongStack, } from "./opLifecycle/index.js";
|
|
29
|
+
import { pkgVersion } from "./packageVersion.js";
|
|
30
|
+
import { PendingStateManager, } from "./pendingStateManager.js";
|
|
31
|
+
import { ScheduleManager } from "./scheduleManager.js";
|
|
32
|
+
import { DocumentsSchemaController, OrderedClientCollection, OrderedClientElection, RetriableSummaryError, RunWhileConnectedCoordinator, Summarizer, SummarizerClientElection, SummaryCollection, SummaryManager, aliasBlobName, blobsTreeName, chunksBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, rootHasIsolatedChannels, summarizerClientType, wrapSummaryInChannelsTree, } from "./summary/index.js";
|
|
33
|
+
import { Throttler, formExponentialFn } from "./throttler.js";
|
|
27
34
|
/**
|
|
28
35
|
* Utility to implement compat behaviors given an unknown message type
|
|
29
36
|
* The parameters are typed to support compile-time enforcement of handling all known types/behaviors
|
|
@@ -78,6 +85,11 @@ export var CompressionAlgorithms;
|
|
|
78
85
|
(function (CompressionAlgorithms) {
|
|
79
86
|
CompressionAlgorithms["lz4"] = "lz4";
|
|
80
87
|
})(CompressionAlgorithms || (CompressionAlgorithms = {}));
|
|
88
|
+
/** @alpha */
|
|
89
|
+
export const disabledCompressionConfig = {
|
|
90
|
+
minimumBatchSizeInBytes: Infinity,
|
|
91
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
92
|
+
};
|
|
81
93
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
82
94
|
const defaultFlushMode = FlushMode.TurnBased;
|
|
83
95
|
// The actual limit is 1Mb (socket.io and Kafka limits)
|
|
@@ -101,26 +113,12 @@ export const defaultPendingOpsRetryDelayMs = 1000;
|
|
|
101
113
|
* This delay's goal is to prevent tight restart loops
|
|
102
114
|
*/
|
|
103
115
|
const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
|
|
104
|
-
/**
|
|
105
|
-
* @deprecated use ContainerRuntimeMessageType instead
|
|
106
|
-
* @internal
|
|
107
|
-
*/
|
|
108
|
-
export var RuntimeMessage;
|
|
109
|
-
(function (RuntimeMessage) {
|
|
110
|
-
RuntimeMessage["FluidDataStoreOp"] = "component";
|
|
111
|
-
RuntimeMessage["Attach"] = "attach";
|
|
112
|
-
RuntimeMessage["ChunkedOp"] = "chunkedOp";
|
|
113
|
-
RuntimeMessage["BlobAttach"] = "blobAttach";
|
|
114
|
-
RuntimeMessage["Rejoin"] = "rejoin";
|
|
115
|
-
RuntimeMessage["Alias"] = "alias";
|
|
116
|
-
RuntimeMessage["Operation"] = "op";
|
|
117
|
-
})(RuntimeMessage || (RuntimeMessage = {}));
|
|
118
116
|
/**
|
|
119
117
|
* @deprecated please use version in driver-utils
|
|
120
118
|
* @internal
|
|
121
119
|
*/
|
|
122
120
|
export function isRuntimeMessage(message) {
|
|
123
|
-
return Object.values(
|
|
121
|
+
return Object.values(ContainerMessageType).includes(message.type);
|
|
124
122
|
}
|
|
125
123
|
/**
|
|
126
124
|
* Legacy ID for the built-in AgentScheduler. To minimize disruption while removing it, retaining this as a
|
|
@@ -194,6 +192,17 @@ async function createSummarizer(loader, url) {
|
|
|
194
192
|
}
|
|
195
193
|
return fluidObject.ISummarizer;
|
|
196
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Extract last message from the snapshot metadata.
|
|
197
|
+
* Uses legacy property if not using explicit schema control, otherwise uses the new property.
|
|
198
|
+
* This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
|
|
199
|
+
* Please see addMetadataToSummary() as well
|
|
200
|
+
*/
|
|
201
|
+
function lastMessageFromMetadata(metadata) {
|
|
202
|
+
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
203
|
+
? metadata?.lastMessage
|
|
204
|
+
: metadata?.message;
|
|
205
|
+
}
|
|
197
206
|
/**
|
|
198
207
|
* Represents the runtime of the container. Contains helper functions/state of the container.
|
|
199
208
|
* It will define the store level mappings.
|
|
@@ -221,6 +230,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
221
230
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
222
231
|
const backCompatContext = context;
|
|
223
232
|
const passLogger = backCompatContext.taggedLogger ??
|
|
233
|
+
// eslint-disable-next-line import/no-deprecated
|
|
224
234
|
new TaggedLoggerAdapter(backCompatContext.logger);
|
|
225
235
|
const logger = createChildLogger({
|
|
226
236
|
logger: passLogger,
|
|
@@ -231,7 +241,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
231
241
|
},
|
|
232
242
|
});
|
|
233
243
|
const mc = loggerToMonitoringContext(logger);
|
|
234
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor
|
|
244
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, explicitSchemaControl = false, } = runtimeOptions;
|
|
235
245
|
const registry = new FluidDataStoreRegistry(registryEntries);
|
|
236
246
|
const tryFetchBlob = async (blobName) => {
|
|
237
247
|
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
@@ -256,14 +266,21 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
256
266
|
assert(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
|
|
257
267
|
return readAndParse(context.storage, id);
|
|
258
268
|
});
|
|
269
|
+
const messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
259
270
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
260
|
-
const runtimeSequenceNumber =
|
|
271
|
+
const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
|
|
261
272
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
262
273
|
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
263
274
|
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
264
275
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
265
276
|
if (loadSequenceNumberVerification !== "bypass" &&
|
|
266
277
|
runtimeSequenceNumber !== protocolSequenceNumber) {
|
|
278
|
+
// Message to OCEs:
|
|
279
|
+
// You can hit this error with runtimeSequenceNumber === -1 in < 2.0 RC3 builds.
|
|
280
|
+
// This would indicate that explicit schema control is enabled in current (2.0 RC3+) builds and it
|
|
281
|
+
// results in addMetadataToSummary() creating a poison pill for older runtimes in the form of a -1 sequence number.
|
|
282
|
+
// Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
|
|
283
|
+
// this poison pill to prevent them from proceeding.
|
|
267
284
|
// "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
|
|
268
285
|
const error = new DataCorruptionError(
|
|
269
286
|
// pre-0.58 error message: SummaryMetadataMismatch
|
|
@@ -276,8 +293,20 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
276
293
|
}
|
|
277
294
|
}
|
|
278
295
|
}
|
|
296
|
+
let desiredIdCompressorMode;
|
|
297
|
+
switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
|
|
298
|
+
case true:
|
|
299
|
+
desiredIdCompressorMode = "on";
|
|
300
|
+
break;
|
|
301
|
+
case false:
|
|
302
|
+
desiredIdCompressorMode = undefined;
|
|
303
|
+
break;
|
|
304
|
+
default:
|
|
305
|
+
desiredIdCompressorMode = enableRuntimeIdCompressor;
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
279
308
|
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
280
|
-
// allow new containers to turn it on
|
|
309
|
+
// allow new containers to turn it on.
|
|
281
310
|
let idCompressorMode;
|
|
282
311
|
if (existing) {
|
|
283
312
|
// This setting has to be sticky for correctness:
|
|
@@ -286,28 +315,30 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
286
315
|
// 2) if it's ON, then all sessions should load compressor right away
|
|
287
316
|
// 3) Same logic applies for "delayed" mode
|
|
288
317
|
// Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
|
|
289
|
-
// We could do "off" -> "on"
|
|
290
|
-
// this will allow clients to eventually
|
|
318
|
+
// We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
|
|
319
|
+
// do so for a while - this will allow clients to eventually disregard "off" setting (when it's safe so) and start
|
|
320
|
+
// using compressor in future sessions.
|
|
291
321
|
// Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
|
|
292
|
-
idCompressorMode = metadata?.
|
|
322
|
+
idCompressorMode = metadata?.documentSchema?.runtime
|
|
323
|
+
?.idCompressorMode;
|
|
324
|
+
// This is the only exception to the rule above - we have proper plumbing to load ID compressor on schema change
|
|
325
|
+
// event. It is loaded async (relative to op processing), so this conversion is only safe for off -> delayed conversion!
|
|
326
|
+
// Clients do not expect ID compressor ops unless ID compressor is On for them, and that could be achieved only through
|
|
327
|
+
// explicit schema change, i.e. only if explicitSchemaControl is on.
|
|
328
|
+
// Note: it would be better if we throw on combination of options (explicitSchemaControl = off, desiredIdCompressorMode === "delayed")
|
|
329
|
+
// that is not supported. But our service tests are oblivious to these problems and throwing here will cause a ton of failures
|
|
330
|
+
// We ignored incompatible ID compressor changes from the start (they were sticky), so that's not a new problem being introduced...
|
|
331
|
+
if (idCompressorMode === undefined &&
|
|
332
|
+
desiredIdCompressorMode === "delayed" &&
|
|
333
|
+
explicitSchemaControl) {
|
|
334
|
+
idCompressorMode = desiredIdCompressorMode;
|
|
335
|
+
}
|
|
293
336
|
}
|
|
294
337
|
else {
|
|
295
|
-
|
|
296
|
-
const enabled = mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled");
|
|
297
|
-
switch (enabled) {
|
|
298
|
-
case true:
|
|
299
|
-
idCompressorMode = "on";
|
|
300
|
-
break;
|
|
301
|
-
case false:
|
|
302
|
-
idCompressorMode = "off";
|
|
303
|
-
break;
|
|
304
|
-
default:
|
|
305
|
-
idCompressorMode = enableRuntimeIdCompressor;
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
338
|
+
idCompressorMode = desiredIdCompressorMode;
|
|
308
339
|
}
|
|
309
340
|
const createIdCompressorFn = async () => {
|
|
310
|
-
const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor");
|
|
341
|
+
const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor/internal");
|
|
311
342
|
/**
|
|
312
343
|
* Because the IdCompressor emits so much telemetry, this function is used to sample
|
|
313
344
|
* approximately 5% of all clients. Only the given percentage of sessions will emit telemetry.
|
|
@@ -332,6 +363,25 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
332
363
|
return createIdCompressor(compressorLogger);
|
|
333
364
|
}
|
|
334
365
|
};
|
|
366
|
+
const disableGroupedBatching = mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
|
|
367
|
+
const disableCompression = mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
368
|
+
const compressionLz4 = disableCompression !== true &&
|
|
369
|
+
compressionOptions.minimumBatchSizeInBytes !== Infinity &&
|
|
370
|
+
compressionOptions.compressionAlgorithm === "lz4";
|
|
371
|
+
const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
|
|
372
|
+
const documentSchemaController = new DocumentsSchemaController(existing, metadata?.documentSchema, {
|
|
373
|
+
explicitSchemaControl,
|
|
374
|
+
compressionLz4,
|
|
375
|
+
idCompressorMode,
|
|
376
|
+
opGroupingEnabled,
|
|
377
|
+
disallowedVersions: [],
|
|
378
|
+
}, (schema) => {
|
|
379
|
+
runtime.onSchemaChange(schema);
|
|
380
|
+
});
|
|
381
|
+
const featureGatesForTelemetry = {
|
|
382
|
+
disableGroupedBatching,
|
|
383
|
+
disableCompression,
|
|
384
|
+
};
|
|
335
385
|
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
|
|
336
386
|
summaryOptions,
|
|
337
387
|
gcOptions,
|
|
@@ -340,10 +390,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
340
390
|
compressionOptions,
|
|
341
391
|
maxBatchSizeInBytes,
|
|
342
392
|
chunkSizeInBytes,
|
|
343
|
-
|
|
393
|
+
// Requires<> drops undefined from IdCompressorType
|
|
394
|
+
enableRuntimeIdCompressor: enableRuntimeIdCompressor,
|
|
344
395
|
enableOpReentryCheck,
|
|
345
396
|
enableGroupedBatching,
|
|
346
|
-
|
|
397
|
+
explicitSchemaControl,
|
|
398
|
+
}, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
|
|
399
|
+
runtime.blobManager.trackPendingStashedUploads().then(() => {
|
|
400
|
+
// make sure we didn't reconnect before the promise resolved
|
|
401
|
+
if (runtime.delayConnectClientId !== undefined && !runtime.disposed) {
|
|
402
|
+
runtime.delayConnectClientId = undefined;
|
|
403
|
+
runtime.setConnectionStateCore(true, runtime.delayConnectClientId);
|
|
404
|
+
}
|
|
405
|
+
}, (error) => runtime.closeFn(error));
|
|
347
406
|
// Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
|
|
348
407
|
// or zero. This must be done before Container replays saved ops.
|
|
349
408
|
await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
|
|
@@ -372,6 +431,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
372
431
|
get attachState() {
|
|
373
432
|
return this._getAttachState();
|
|
374
433
|
}
|
|
434
|
+
get documentSchema() {
|
|
435
|
+
return this.documentsSchemaController.sessionSchema.runtime;
|
|
436
|
+
}
|
|
437
|
+
get idCompressorMode() {
|
|
438
|
+
return this.documentSchema.idCompressorMode;
|
|
439
|
+
}
|
|
375
440
|
/**
|
|
376
441
|
* See IContainerRuntimeBase.idCompressor() for details.
|
|
377
442
|
*/
|
|
@@ -452,7 +517,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
452
517
|
return this.garbageCollector.throwOnTombstoneUsage;
|
|
453
518
|
}
|
|
454
519
|
/***/
|
|
455
|
-
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor,
|
|
520
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
|
|
456
521
|
// the defaults
|
|
457
522
|
...DefaultSummaryConfiguration,
|
|
458
523
|
// the runtime configuration overrides
|
|
@@ -466,18 +531,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
466
531
|
this.logger = logger;
|
|
467
532
|
this._storage = _storage;
|
|
468
533
|
this.createIdCompressor = createIdCompressor;
|
|
469
|
-
this.
|
|
534
|
+
this.documentsSchemaController = documentsSchemaController;
|
|
470
535
|
this.requestHandler = requestHandler;
|
|
471
536
|
this.summaryConfiguration = summaryConfiguration;
|
|
472
537
|
this.imminentClosure = false;
|
|
473
538
|
// We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
|
|
474
539
|
// Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
|
|
475
540
|
this.pendingIdCompressorOps = [];
|
|
476
|
-
/**
|
|
477
|
-
* True if we have ID compressor loading in-flight (async operation). Useful only for
|
|
478
|
-
* this.idCompressorMode === "delayed" mode
|
|
479
|
-
*/
|
|
480
|
-
this.compressorLoadInitiated = false;
|
|
481
541
|
this.defaultMaxConsecutiveReconnects = 7;
|
|
482
542
|
this._orderSequentiallyCalls = 0;
|
|
483
543
|
this.flushTaskExists = false;
|
|
@@ -507,6 +567,20 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
507
567
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
508
568
|
});
|
|
509
569
|
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
|
|
570
|
+
this.mc = createChildMonitoringContext({
|
|
571
|
+
logger: this.logger,
|
|
572
|
+
namespace: "ContainerRuntime",
|
|
573
|
+
});
|
|
574
|
+
// If we support multiple algorithms in the future, then we would need to manage it here carefully.
|
|
575
|
+
// We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
|
|
576
|
+
// If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
|
|
577
|
+
// compression.
|
|
578
|
+
const compressionOptions = {
|
|
579
|
+
minimumBatchSizeInBytes: this.documentSchema.compressionLz4
|
|
580
|
+
? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
|
|
581
|
+
: Number.POSITIVE_INFINITY,
|
|
582
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
583
|
+
};
|
|
510
584
|
this.innerDeltaManager = deltaManager;
|
|
511
585
|
this.deltaManager = new DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
512
586
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
@@ -540,10 +614,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
540
614
|
this.disposeFn = disposeFn ?? closeFn;
|
|
541
615
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
542
616
|
this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
|
|
543
|
-
this.mc = createChildMonitoringContext({
|
|
544
|
-
logger: this.logger,
|
|
545
|
-
namespace: "ContainerRuntime",
|
|
546
|
-
});
|
|
547
617
|
let loadSummaryNumber;
|
|
548
618
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
549
619
|
// get the values from the metadata blob.
|
|
@@ -564,7 +634,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
564
634
|
loadSummaryNumber = 0;
|
|
565
635
|
}
|
|
566
636
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
567
|
-
this.messageAtLastSummary = metadata
|
|
637
|
+
this.messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
568
638
|
// Note that we only need to pull the *initial* connected state from the context.
|
|
569
639
|
// Later updates come through calls to setConnectionState.
|
|
570
640
|
this._connected = connected;
|
|
@@ -667,32 +737,38 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
667
737
|
return this.submitSignalFn(envelope2, targetClientId);
|
|
668
738
|
};
|
|
669
739
|
this.channelCollection = new ChannelCollection(getSummaryForDatastores(baseSnapshot, metadata), parentContext, this.mc.logger, (path, reason, timestampMs, packagePath, request, headerData) => this.garbageCollector.nodeUpdated(path, reason, timestampMs, packagePath, request, headerData), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap), async (runtime) => provideEntryPoint);
|
|
670
|
-
this.blobManager = new BlobManager(
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
740
|
+
this.blobManager = new BlobManager({
|
|
741
|
+
routeContext: this.handleContext,
|
|
742
|
+
snapshot: blobManagerSnapshot,
|
|
743
|
+
getStorage: () => this.storage,
|
|
744
|
+
sendBlobAttachOp: (localId, blobId) => {
|
|
745
|
+
if (!this.disposed) {
|
|
746
|
+
this.submit({ type: ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
|
|
747
|
+
localId,
|
|
748
|
+
blobId,
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
blobRequested: (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"),
|
|
753
|
+
isBlobDeleted: (blobPath) => this.garbageCollector.isNodeDeleted(blobPath),
|
|
754
|
+
runtime: this,
|
|
755
|
+
stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
|
|
756
|
+
closeContainer: (error) => this.closeFn(error),
|
|
757
|
+
});
|
|
678
758
|
this.scheduleManager = new ScheduleManager(this.innerDeltaManager, this, () => this.clientId, createChildLogger({ logger: this.logger, namespace: "ScheduleManager" }));
|
|
679
759
|
this.pendingStateManager = new PendingStateManager({
|
|
680
760
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
681
761
|
clientId: () => this.clientId,
|
|
682
762
|
close: this.closeFn,
|
|
683
763
|
connected: () => this.connected,
|
|
684
|
-
reSubmit:
|
|
764
|
+
reSubmit: (message) => {
|
|
765
|
+
this.reSubmit(message);
|
|
766
|
+
this.flush();
|
|
767
|
+
},
|
|
685
768
|
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
686
769
|
isActiveConnection: () => this.innerDeltaManager.active,
|
|
687
770
|
isAttached: () => this.attachState !== AttachState.Detached,
|
|
688
771
|
}, pendingRuntimeState?.pending, this.logger);
|
|
689
|
-
const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
690
|
-
const compressionOptions = disableCompression === true
|
|
691
|
-
? {
|
|
692
|
-
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
693
|
-
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
694
|
-
}
|
|
695
|
-
: runtimeOptions.compressionOptions;
|
|
696
772
|
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
697
773
|
const legacySendBatchFn = makeLegacySendBatchFn(this.submitFn, this.innerDeltaManager);
|
|
698
774
|
this.outbox = new Outbox({
|
|
@@ -797,10 +873,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
797
873
|
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
798
874
|
gcVersion: metadata?.gcFeature,
|
|
799
875
|
options: JSON.stringify(runtimeOptions),
|
|
800
|
-
idCompressorModeMetadata: metadata?.idCompressorMode,
|
|
876
|
+
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
801
877
|
idCompressorMode: this.idCompressorMode,
|
|
802
878
|
featureGates: JSON.stringify({
|
|
803
|
-
|
|
879
|
+
...featureGatesForTelemetry,
|
|
804
880
|
disableOpReentryCheck,
|
|
805
881
|
disableChunking,
|
|
806
882
|
disableAttachReorder: this.disableAttachReorder,
|
|
@@ -823,15 +899,33 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
823
899
|
// saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
|
|
824
900
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
825
901
|
}
|
|
902
|
+
onSchemaChange(schema) {
|
|
903
|
+
// Most of the settings will be picked up only by new sessions (i.e. after reload).
|
|
904
|
+
// We can make it better in the future (i.e. start to use op compression right away), but for simplicity
|
|
905
|
+
// this is not done.
|
|
906
|
+
// But ID compressor is special. It's possible, that in future, we will remove "stickiness" of ID compressor setting
|
|
907
|
+
// and will allow to start using it. If that were to happen, we want to ensure that we do not break eventual consistency
|
|
908
|
+
// promises. To do so, we need to initialize id compressor right away.
|
|
909
|
+
// As it's implemented right now (with async initialization), this will only work for "off" -> "delayed" transitions.
|
|
910
|
+
// Anything else is too risky, and requires ability to initialize ID compressor synchronously!
|
|
911
|
+
if (schema.runtime.idCompressorMode !== undefined) {
|
|
912
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
913
|
+
this.loadIdCompressor();
|
|
914
|
+
}
|
|
915
|
+
}
|
|
826
916
|
getCreateChildSummarizerNodeFn(id, createParam) {
|
|
827
917
|
return (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn);
|
|
828
918
|
}
|
|
829
919
|
deleteChildSummarizerNode(id) {
|
|
830
920
|
return this.summarizerNode.deleteChild(id);
|
|
831
921
|
}
|
|
922
|
+
/* IFluidParentContext APIs that should not be called on Root */
|
|
832
923
|
makeLocallyVisible() {
|
|
833
924
|
assert(false, 0x8eb /* should not be called */);
|
|
834
925
|
}
|
|
926
|
+
setChannelDirty(address) {
|
|
927
|
+
assert(false, 0x909 /* should not be called */);
|
|
928
|
+
}
|
|
835
929
|
/**
|
|
836
930
|
* Initializes the state from the base snapshot this container runtime loaded from.
|
|
837
931
|
*/
|
|
@@ -1036,18 +1130,30 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1036
1130
|
}
|
|
1037
1131
|
/** Adds the container's metadata to the given summary tree. */
|
|
1038
1132
|
addMetadataToSummary(summaryTree) {
|
|
1133
|
+
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
1134
|
+
// last summary.
|
|
1135
|
+
const message = extractSummaryMetadataMessage(this.deltaManager.lastMessage) ??
|
|
1136
|
+
this.messageAtLastSummary;
|
|
1137
|
+
const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
|
|
1138
|
+
// Is document schema explicit control on?
|
|
1139
|
+
const explitiSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
1039
1140
|
const metadata = {
|
|
1040
1141
|
...this.createContainerMetadata,
|
|
1041
1142
|
// Increment the summary number for the next summary that will be generated.
|
|
1042
1143
|
summaryNumber: this.nextSummaryNumber++,
|
|
1043
1144
|
summaryFormatVersion: 1,
|
|
1044
1145
|
...this.garbageCollector.getMetadata(),
|
|
1045
|
-
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
1046
|
-
// last summary.
|
|
1047
|
-
message: extractSummaryMetadataMessage(this.deltaManager.lastMessage) ??
|
|
1048
|
-
this.messageAtLastSummary,
|
|
1049
1146
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
1050
|
-
|
|
1147
|
+
// If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
|
|
1148
|
+
// Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
|
|
1149
|
+
// runtimes (that preceed document schema control capabilities) to close container on load due to mismatch in
|
|
1150
|
+
// last message's sequence number.
|
|
1151
|
+
// See also lastMessageFromMetadata()
|
|
1152
|
+
message: explitiSchemaControl
|
|
1153
|
+
? { sequenceNumber: -1 }
|
|
1154
|
+
: message,
|
|
1155
|
+
lastMessage: explitiSchemaControl ? message : undefined,
|
|
1156
|
+
documentSchema,
|
|
1051
1157
|
};
|
|
1052
1158
|
addBlobToSummary(summaryTree, metadataBlobName, JSON.stringify(metadata));
|
|
1053
1159
|
}
|
|
@@ -1108,14 +1214,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1108
1214
|
}
|
|
1109
1215
|
return this.consecutiveReconnects < this.maxConsecutiveReconnects;
|
|
1110
1216
|
}
|
|
1111
|
-
resetReconnectCount(
|
|
1112
|
-
|
|
1113
|
-
// in their own batches before the originating batch is sent.
|
|
1114
|
-
// Therefore, receiving them while attempting to send the originating batch
|
|
1115
|
-
// does not mean that the container is making any progress.
|
|
1116
|
-
if (message?.type !== ContainerMessageType.ChunkedOp) {
|
|
1117
|
-
this.consecutiveReconnects = 0;
|
|
1118
|
-
}
|
|
1217
|
+
resetReconnectCount() {
|
|
1218
|
+
this.consecutiveReconnects = 0;
|
|
1119
1219
|
}
|
|
1120
1220
|
replayPendingStates() {
|
|
1121
1221
|
// We need to be able to send ops to replay states
|
|
@@ -1164,7 +1264,18 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1164
1264
|
case ContainerMessageType.Alias:
|
|
1165
1265
|
return this.channelCollection.applyStashedOp(opContents);
|
|
1166
1266
|
case ContainerMessageType.IdAllocation:
|
|
1167
|
-
|
|
1267
|
+
// IDs allocation ops in stashed state are ignored because the tip state of the compressor
|
|
1268
|
+
// is serialized into the pending state. This is done because generation of new IDs during
|
|
1269
|
+
// stashed op application (or, later, resubmit) must generate new IDs and if the compressor
|
|
1270
|
+
// was loaded from a state serialized at the same time as the summary tree in the stashed state
|
|
1271
|
+
// then it would generate IDs that collide with any in later stashed ops.
|
|
1272
|
+
// In the future, IdCompressor could be extended to have an "applyStashedOp" or similar method
|
|
1273
|
+
// and the runtime could filter out all ID allocation ops from the stashed state and apply them
|
|
1274
|
+
// before applying the rest of the stashed ops. This would accomplish the same thing but with
|
|
1275
|
+
// better performance in future incremental stashed state creation.
|
|
1276
|
+
assert(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1277
|
+
return;
|
|
1278
|
+
case ContainerMessageType.DocumentSchemaChange:
|
|
1168
1279
|
return;
|
|
1169
1280
|
case ContainerMessageType.BlobAttach:
|
|
1170
1281
|
return;
|
|
@@ -1195,12 +1306,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1195
1306
|
}
|
|
1196
1307
|
}
|
|
1197
1308
|
}
|
|
1198
|
-
|
|
1199
|
-
if (
|
|
1200
|
-
this.
|
|
1201
|
-
this.
|
|
1309
|
+
async loadIdCompressor() {
|
|
1310
|
+
if (this._idCompressor === undefined &&
|
|
1311
|
+
this.idCompressorMode !== undefined &&
|
|
1312
|
+
this._loadIdCompressor === undefined) {
|
|
1313
|
+
this._loadIdCompressor = this.createIdCompressor()
|
|
1202
1314
|
.then((compressor) => {
|
|
1203
1315
|
this._idCompressor = compressor;
|
|
1316
|
+
// Finalize any ranges we received while the compressor was turned off.
|
|
1204
1317
|
for (const range of this.pendingIdCompressorOps) {
|
|
1205
1318
|
this._idCompressor.finalizeCreationRange(range);
|
|
1206
1319
|
}
|
|
@@ -1208,8 +1321,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1208
1321
|
})
|
|
1209
1322
|
.catch((error) => {
|
|
1210
1323
|
this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
1324
|
+
throw error;
|
|
1211
1325
|
});
|
|
1212
1326
|
}
|
|
1327
|
+
return this._loadIdCompressor;
|
|
1328
|
+
}
|
|
1329
|
+
setConnectionState(connected, clientId) {
|
|
1330
|
+
if (connected && this.idCompressorMode === "delayed") {
|
|
1331
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1332
|
+
this.loadIdCompressor();
|
|
1333
|
+
}
|
|
1213
1334
|
if (connected === false && this.delayConnectClientId !== undefined) {
|
|
1214
1335
|
this.delayConnectClientId = undefined;
|
|
1215
1336
|
this.mc.logger.sendTelemetryEvent({
|
|
@@ -1218,21 +1339,17 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1218
1339
|
// Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
|
|
1219
1340
|
return;
|
|
1220
1341
|
}
|
|
1342
|
+
if (!connected) {
|
|
1343
|
+
this.documentsSchemaController.onDisconnect();
|
|
1344
|
+
}
|
|
1221
1345
|
// If there are stashed blobs in the pending state, we need to delay
|
|
1222
1346
|
// propagation of the "connected" event until we have uploaded them to
|
|
1223
1347
|
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
1224
1348
|
const connecting = connected && !this._connected;
|
|
1225
|
-
if (connecting && this.blobManager.
|
|
1349
|
+
if (connecting && this.blobManager.hasPendingStashedUploads()) {
|
|
1226
1350
|
assert(!this.delayConnectClientId, 0x791 /* Connect event delay must be canceled before subsequent connect event */);
|
|
1227
1351
|
assert(!!clientId, 0x792 /* Must have clientId when connecting */);
|
|
1228
1352
|
this.delayConnectClientId = clientId;
|
|
1229
|
-
this.blobManager.processStashedChanges().then(() => {
|
|
1230
|
-
// make sure we didn't reconnect before the promise resolved
|
|
1231
|
-
if (this.delayConnectClientId === clientId && !this.disposed) {
|
|
1232
|
-
this.delayConnectClientId = undefined;
|
|
1233
|
-
this.setConnectionStateCore(connected, clientId);
|
|
1234
|
-
}
|
|
1235
|
-
}, (error) => this.closeFn(error));
|
|
1236
1353
|
return;
|
|
1237
1354
|
}
|
|
1238
1355
|
this.setConnectionStateCore(connected, clientId);
|
|
@@ -1320,10 +1437,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1320
1437
|
this.scheduleManager.beforeOpProcessing(message);
|
|
1321
1438
|
this._processedClientSequenceNumber = message.clientSequenceNumber;
|
|
1322
1439
|
try {
|
|
1440
|
+
// See commit that added this assert for more details.
|
|
1441
|
+
// These calls should be made for all but chunked ops:
|
|
1442
|
+
// 1) this.pendingStateManager.processPendingLocalMessage() below
|
|
1443
|
+
// 2) this.resetReconnectCount() below
|
|
1444
|
+
assert(message.type !== ContainerMessageType.ChunkedOp, 0x93b /* we should never get here with chunked ops */);
|
|
1323
1445
|
let localOpMetadata;
|
|
1324
|
-
if (local &&
|
|
1325
|
-
messageWithContext.modernRuntimeMessage &&
|
|
1326
|
-
message.type !== ContainerMessageType.ChunkedOp) {
|
|
1446
|
+
if (local && messageWithContext.modernRuntimeMessage) {
|
|
1327
1447
|
localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
|
|
1328
1448
|
}
|
|
1329
1449
|
// If there are no more pending messages after processing a local message,
|
|
@@ -1338,7 +1458,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1338
1458
|
// If we have processed a local op, this means that the container is
|
|
1339
1459
|
// making progress and we can reset the counter for how many times
|
|
1340
1460
|
// we have consecutively replayed the pending states
|
|
1341
|
-
this.resetReconnectCount(
|
|
1461
|
+
this.resetReconnectCount();
|
|
1342
1462
|
}
|
|
1343
1463
|
}
|
|
1344
1464
|
catch (e) {
|
|
@@ -1372,7 +1492,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1372
1492
|
messageWithContext.message.metadata?.savedOp ===
|
|
1373
1493
|
true)) {
|
|
1374
1494
|
const range = messageWithContext.message.contents;
|
|
1495
|
+
// Some other client turned on the id compressor. If we have not turned it on,
|
|
1496
|
+
// put it in a pending queue and delay finalization.
|
|
1375
1497
|
if (this._idCompressor === undefined) {
|
|
1498
|
+
assert(this.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
|
|
1376
1499
|
this.pendingIdCompressorOps.push(range);
|
|
1377
1500
|
}
|
|
1378
1501
|
else {
|
|
@@ -1384,8 +1507,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1384
1507
|
this.garbageCollector.processMessage(messageWithContext.message, local);
|
|
1385
1508
|
break;
|
|
1386
1509
|
case ContainerMessageType.ChunkedOp:
|
|
1510
|
+
// From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
|
|
1511
|
+
// Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
|
|
1512
|
+
assert(false, 0x93d /* should not even get here */);
|
|
1387
1513
|
case ContainerMessageType.Rejoin:
|
|
1388
1514
|
break;
|
|
1515
|
+
case ContainerMessageType.DocumentSchemaChange:
|
|
1516
|
+
this.documentsSchemaController.processDocumentSchemaOp(messageWithContext.message.contents, messageWithContext.local, messageWithContext.message.sequenceNumber);
|
|
1517
|
+
break;
|
|
1389
1518
|
default: {
|
|
1390
1519
|
// If we didn't necessarily expect a runtime message type, then no worries - just return
|
|
1391
1520
|
// e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
|
|
@@ -1559,10 +1688,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1559
1688
|
return channel.entryPoint;
|
|
1560
1689
|
}
|
|
1561
1690
|
createDetachedDataStore(pkg, loadingGroupId) {
|
|
1562
|
-
return this.channelCollection.
|
|
1691
|
+
return this.channelCollection.createDetachedDataStore(pkg, loadingGroupId);
|
|
1563
1692
|
}
|
|
1564
1693
|
async createDataStore(pkg, loadingGroupId) {
|
|
1565
|
-
const context = this.channelCollection.
|
|
1694
|
+
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], undefined, // props
|
|
1566
1695
|
loadingGroupId);
|
|
1567
1696
|
return channelToDataStore(await context.realize(), context.id, this.channelCollection, this.mc.logger);
|
|
1568
1697
|
}
|
|
@@ -1570,7 +1699,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1570
1699
|
* @deprecated 0.16 Issue #1537, #3631
|
|
1571
1700
|
*/
|
|
1572
1701
|
async _createDataStoreWithProps(pkg, props) {
|
|
1573
|
-
const context = this.channelCollection.
|
|
1702
|
+
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
|
|
1574
1703
|
return channelToDataStore(await context.realize(), context.id, this.channelCollection, this.mc.logger);
|
|
1575
1704
|
}
|
|
1576
1705
|
canSendOps() {
|
|
@@ -1615,6 +1744,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1615
1744
|
}
|
|
1616
1745
|
break;
|
|
1617
1746
|
}
|
|
1747
|
+
case ContainerMessageType.IdAllocation:
|
|
1748
|
+
case ContainerMessageType.DocumentSchemaChange:
|
|
1618
1749
|
case ContainerMessageType.GC: {
|
|
1619
1750
|
return false;
|
|
1620
1751
|
}
|
|
@@ -1641,7 +1772,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1641
1772
|
/**
|
|
1642
1773
|
* Submits the signal to be sent to other clients.
|
|
1643
1774
|
* @param type - Type of the signal.
|
|
1644
|
-
* @param content - Content of the signal.
|
|
1775
|
+
* @param content - Content of the signal. Should be a JSON serializable object or primitive.
|
|
1645
1776
|
* @param targetClientId - When specified, the signal is only sent to the provided client id.
|
|
1646
1777
|
*/
|
|
1647
1778
|
submitSignal(type, content, targetClientId) {
|
|
@@ -1677,6 +1808,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1677
1808
|
// We can finalize any allocated IDs since we're the only client
|
|
1678
1809
|
const idRange = this._idCompressor?.takeNextCreationRange();
|
|
1679
1810
|
if (idRange !== undefined) {
|
|
1811
|
+
assert(idRange.ids === undefined || idRange.ids.firstGenCount === 1, 0x93e /* No other ranges should be taken while container is detached. */);
|
|
1680
1812
|
this._idCompressor?.finalizeCreationRange(idRange);
|
|
1681
1813
|
}
|
|
1682
1814
|
const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
|
|
@@ -1690,6 +1822,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1690
1822
|
// Wrap data store summaries in .channels subtree.
|
|
1691
1823
|
wrapSummaryInChannelsTree(summarizeResult);
|
|
1692
1824
|
const pathPartsForChildren = [channelsTreeName];
|
|
1825
|
+
// Ensure that ID compressor had a chance to load, if we are using delayed mode.
|
|
1826
|
+
await this.loadIdCompressor();
|
|
1693
1827
|
this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
|
|
1694
1828
|
return {
|
|
1695
1829
|
...summarizeResult,
|
|
@@ -1765,21 +1899,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1765
1899
|
const { dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(usedRoutes);
|
|
1766
1900
|
this.channelCollection.updateUsedRoutes(dataStoreRoutes);
|
|
1767
1901
|
}
|
|
1768
|
-
/**
|
|
1769
|
-
* This is called to update objects whose routes are unused.
|
|
1770
|
-
* @param unusedRoutes - Data store and attachment blob routes that are unused in this Container.
|
|
1771
|
-
*/
|
|
1772
|
-
updateUnusedRoutes(unusedRoutes) {
|
|
1773
|
-
const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(unusedRoutes);
|
|
1774
|
-
this.blobManager.updateUnusedRoutes(blobManagerRoutes);
|
|
1775
|
-
this.channelCollection.updateUnusedRoutes(dataStoreRoutes);
|
|
1776
|
-
}
|
|
1777
|
-
/**
|
|
1778
|
-
* @deprecated Replaced by deleteSweepReadyNodes.
|
|
1779
|
-
*/
|
|
1780
|
-
deleteUnusedNodes(unusedRoutes) {
|
|
1781
|
-
throw new Error("deleteUnusedRoutes should not be called");
|
|
1782
|
-
}
|
|
1783
1902
|
/**
|
|
1784
1903
|
* After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
|
|
1785
1904
|
* @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
|
|
@@ -2247,19 +2366,18 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2247
2366
|
const idAllocationBatchMessage = {
|
|
2248
2367
|
contents: JSON.stringify(idAllocationMessage),
|
|
2249
2368
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2250
|
-
metadata: undefined,
|
|
2251
|
-
localOpMetadata: undefined,
|
|
2252
|
-
type: ContainerMessageType.IdAllocation,
|
|
2253
2369
|
};
|
|
2254
2370
|
this.outbox.submitIdAllocation(idAllocationBatchMessage);
|
|
2255
2371
|
}
|
|
2256
2372
|
}
|
|
2257
2373
|
}
|
|
2258
|
-
submit(containerRuntimeMessage, localOpMetadata = undefined, metadata
|
|
2374
|
+
submit(containerRuntimeMessage, localOpMetadata = undefined, metadata) {
|
|
2259
2375
|
this.verifyNotClosed();
|
|
2260
2376
|
this.verifyCanSubmitOps();
|
|
2261
2377
|
// There should be no ops in detached container state!
|
|
2262
2378
|
assert(this.attachState !== AttachState.Detached, 0x132 /* "sending ops in detached container" */);
|
|
2379
|
+
assert(metadata === undefined ||
|
|
2380
|
+
containerRuntimeMessage.type === ContainerMessageType.BlobAttach, 0x93f /* metadata */);
|
|
2263
2381
|
const serializedContent = JSON.stringify(containerRuntimeMessage);
|
|
2264
2382
|
// Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
|
|
2265
2383
|
// container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
|
|
@@ -2272,7 +2390,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2272
2390
|
const type = containerRuntimeMessage.type;
|
|
2273
2391
|
const message = {
|
|
2274
2392
|
contents: serializedContent,
|
|
2275
|
-
type,
|
|
2276
2393
|
metadata,
|
|
2277
2394
|
localOpMetadata,
|
|
2278
2395
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
@@ -2287,6 +2404,20 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2287
2404
|
}
|
|
2288
2405
|
else {
|
|
2289
2406
|
this.submitIdAllocationOpIfNeeded();
|
|
2407
|
+
// Allow document schema controller to send a message if it needs to propose change in document schema.
|
|
2408
|
+
// If it needs to send a message, it will call provided callback with payload of such message and rely
|
|
2409
|
+
// on this callback to do actual sending.
|
|
2410
|
+
const contents = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2411
|
+
if (contents) {
|
|
2412
|
+
const msg = {
|
|
2413
|
+
type: ContainerMessageType.DocumentSchemaChange,
|
|
2414
|
+
contents,
|
|
2415
|
+
};
|
|
2416
|
+
this.outbox.submit({
|
|
2417
|
+
contents: JSON.stringify(msg),
|
|
2418
|
+
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2419
|
+
});
|
|
2420
|
+
}
|
|
2290
2421
|
// If this is attach message for new data store, and we are in a batch, send this op out of order
|
|
2291
2422
|
// Is it safe:
|
|
2292
2423
|
// Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
|
|
@@ -2458,6 +2589,11 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2458
2589
|
case ContainerMessageType.GC:
|
|
2459
2590
|
this.submit(message);
|
|
2460
2591
|
break;
|
|
2592
|
+
case ContainerMessageType.DocumentSchemaChange:
|
|
2593
|
+
// There is no need to resend this message. Document schema controller will properly resend it again (if needed)
|
|
2594
|
+
// on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
|
|
2595
|
+
// send any ops, as some other client already changed schema.
|
|
2596
|
+
break;
|
|
2461
2597
|
default: {
|
|
2462
2598
|
// This case should be very rare - it would imply an op was stashed from a
|
|
2463
2599
|
// future version of runtime code and now is being applied on an older version.
|
|
@@ -2660,8 +2796,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2660
2796
|
}
|
|
2661
2797
|
}
|
|
2662
2798
|
get groupedBatchingEnabled() {
|
|
2663
|
-
|
|
2664
|
-
return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
|
|
2799
|
+
return this.documentSchema.opGroupingEnabled === true;
|
|
2665
2800
|
}
|
|
2666
2801
|
}
|
|
2667
2802
|
//# sourceMappingURL=containerRuntime.js.map
|