@fluidframework/container-runtime 2.0.0-dev-rc.3.0.0.250606 → 2.0.0-dev-rc.3.0.0.254274
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 +35 -34
- 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 +31 -23
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +81 -99
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +4 -2
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +75 -72
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +16 -16
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +64 -36
- package/dist/container-runtime-beta.d.ts +28 -28
- package/dist/container-runtime-public.d.ts +28 -28
- package/dist/container-runtime-untrimmed.d.ts +68 -39
- 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 +12 -8
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +197 -162
- 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 +7 -7
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +9 -9
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +72 -62
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +11 -11
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +1 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- 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.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 +2 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +20 -20
- 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 +4 -5
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +3 -2
- 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 +1 -1
- 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/messageTypes.d.ts +2 -2
- package/dist/messageTypes.d.ts.map +1 -1
- 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 +1 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +5 -5
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +12 -12
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +7 -7
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +17 -17
- 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 +13 -13
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +18 -18
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +24 -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 +37 -6
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +58 -21
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +7 -7
- package/dist/summary/orderedClientElection.js.map +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 +1 -1
- 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 +2 -1
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +12 -12
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +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 +2 -1
- 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 +4 -2
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.js +7 -7
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +1 -1
- 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 +3 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +16 -16
- package/dist/summary/summaryGenerator.js.map +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/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 +31 -23
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +46 -64
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +4 -2
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +10 -7
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +2 -2
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +64 -36
- package/lib/container-runtime-beta.d.ts +28 -28
- package/lib/container-runtime-public.d.ts +28 -28
- package/lib/container-runtime-untrimmed.d.ts +68 -39
- 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 +12 -8
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +76 -39
- 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 +9 -9
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +18 -8
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +2 -2
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +1 -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.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 +2 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +4 -4
- 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 +4 -5
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +3 -2
- 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 +1 -1
- 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 +3 -1
- 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/messageTypes.d.ts +2 -2
- package/lib/messageTypes.d.ts.map +1 -1
- 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 +1 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +2 -2
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +2 -2
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +2 -2
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +2 -2
- 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 +2 -2
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +2 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +3 -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 +37 -6
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +48 -11
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +2 -2
- package/lib/summary/orderedClientElection.js.map +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 +1 -1
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +2 -2
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -1
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +2 -2
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +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 +2 -1
- 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 +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 +4 -2
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.js +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +1 -1
- 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 +3 -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.map +1 -1
- package/lib/summary/summaryManager.js +9 -8
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +11 -0
- package/package.json +25 -37
- package/src/batchTracker.ts +3 -2
- package/src/blobManager.ts +87 -56
- package/src/channelCollection.ts +19 -12
- package/src/connectionTelemetry.ts +4 -4
- package/src/containerHandleContext.ts +2 -1
- package/src/containerRuntime.ts +115 -70
- package/src/dataStore.ts +5 -3
- package/src/dataStoreContext.ts +30 -15
- package/src/dataStoreContexts.ts +4 -2
- package/src/dataStoreRegistry.ts +2 -2
- package/src/deltaManagerSummarizerProxy.ts +1 -1
- package/src/deltaScheduler.ts +2 -1
- package/src/error.ts +2 -2
- package/src/gc/garbageCollection.ts +8 -7
- package/src/gc/gcConfigs.ts +5 -8
- package/src/gc/gcDefinitions.ts +4 -4
- package/src/gc/gcHelpers.ts +21 -4
- package/src/gc/gcSummaryStateTracker.ts +5 -3
- package/src/gc/gcTelemetry.ts +7 -1
- package/src/gc/gcUnreferencedStateTracker.ts +3 -2
- package/src/gc/index.ts +1 -0
- package/src/messageTypes.ts +3 -2
- package/src/opLifecycle/batchManager.ts +1 -0
- package/src/opLifecycle/definitions.ts +2 -1
- package/src/opLifecycle/opCompressor.ts +4 -2
- package/src/opLifecycle/opDecompressor.ts +3 -2
- package/src/opLifecycle/opGroupingManager.ts +3 -2
- package/src/opLifecycle/opSplitter.ts +5 -3
- package/src/opLifecycle/outbox.ts +6 -3
- package/src/opLifecycle/remoteMessageProcessor.ts +2 -0
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +4 -4
- package/src/scheduleManager.ts +5 -4
- package/src/storageServiceWithAttachBlobs.ts +2 -2
- package/src/summary/documentSchema.ts +71 -12
- package/src/summary/orderedClientElection.ts +4 -6
- package/src/summary/runWhileConnectedCoordinator.ts +2 -1
- package/src/summary/runningSummarizer.ts +4 -2
- package/src/summary/summarizer.ts +5 -3
- package/src/summary/summarizerClientElection.ts +1 -0
- package/src/summary/summarizerHeuristics.ts +3 -1
- package/src/summary/summarizerNode/summarizerNode.ts +10 -8
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -2
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +14 -6
- package/src/summary/summarizerTypes.ts +6 -2
- package/src/summary/summaryCollection.ts +1 -1
- package/src/summary/summaryFormat.ts +7 -8
- package/src/summary/summaryGenerator.ts +5 -8
- package/src/summary/summaryManager.ts +14 -11
- 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 -138
- package/lib/test/channelCollection.spec.js.map +0 -1
- package/lib/test/containerRuntime.spec.js +0 -1750
- package/lib/test/containerRuntime.spec.js.map +0 -1
- package/lib/test/dataStoreContext.spec.js +0 -771
- package/lib/test/dataStoreContext.spec.js.map +0 -1
- package/lib/test/dataStoreCreation.spec.js +0 -303
- 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/documentSchema.spec.js +0 -282
- package/lib/test/documentSchema.spec.js.map +0 -1
- package/lib/test/fuzz/fuzzUtils.js +0 -70
- package/lib/test/fuzz/fuzzUtils.js.map +0 -1
- package/lib/test/fuzz/summarizer.fuzz.spec.js +0 -33
- package/lib/test/fuzz/summarizer.fuzz.spec.js.map +0 -1
- package/lib/test/fuzz/summarizerFuzzMocks.js +0 -180
- package/lib/test/fuzz/summarizerFuzzMocks.js.map +0 -1
- package/lib/test/fuzz/summarizerFuzzSuite.js +0 -109
- package/lib/test/fuzz/summarizerFuzzSuite.js.map +0 -1
- package/lib/test/gc/garbageCollection.spec.js +0 -1464
- package/lib/test/gc/garbageCollection.spec.js.map +0 -1
- package/lib/test/gc/gcConfigs.spec.js +0 -689
- 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 -390
- 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 -202
- 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 -73
- package/lib/test/opLifecycle/opCompressor.spec.js.map +0 -1
- package/lib/test/opLifecycle/opDecompressor.spec.js +0 -223
- package/lib/test/opLifecycle/opDecompressor.spec.js.map +0 -1
- package/lib/test/opLifecycle/opSplitter.spec.js +0 -287
- package/lib/test/opLifecycle/opSplitter.spec.js.map +0 -1
- package/lib/test/opLifecycle/outbox.spec.js +0 -783
- package/lib/test/opLifecycle/outbox.spec.js.map +0 -1
- package/lib/test/opLifecycle/remoteMessageProcessor.spec.js +0 -220
- 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 -182
- package/lib/test/types/validateContainerRuntimePrevious.generated.js.map +0 -1
package/dist/containerRuntime.js
CHANGED
|
@@ -7,13 +7,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
|
|
8
8
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
10
|
+
const internal_1 = require("@fluidframework/container-definitions/internal");
|
|
11
|
+
const internal_2 = require("@fluidframework/core-utils/internal");
|
|
12
|
+
const internal_3 = require("@fluidframework/driver-definitions/internal");
|
|
13
|
+
const internal_4 = require("@fluidframework/driver-utils/internal");
|
|
13
14
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
15
|
+
const internal_5 = require("@fluidframework/runtime-definitions/internal");
|
|
16
|
+
const internal_6 = require("@fluidframework/runtime-utils/internal");
|
|
17
|
+
const internal_7 = require("@fluidframework/telemetry-utils/internal");
|
|
17
18
|
const uuid_1 = require("uuid");
|
|
18
19
|
const batchTracker_js_1 = require("./batchTracker.js");
|
|
19
20
|
const blobManager_js_1 = require("./blobManager.js");
|
|
@@ -91,7 +92,7 @@ exports.disabledCompressionConfig = {
|
|
|
91
92
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
92
93
|
};
|
|
93
94
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
94
|
-
const defaultFlushMode =
|
|
95
|
+
const defaultFlushMode = internal_5.FlushMode.TurnBased;
|
|
95
96
|
// The actual limit is 1Mb (socket.io and Kafka limits)
|
|
96
97
|
// We can't estimate it fully, as we
|
|
97
98
|
// - do not know what properties relay service will add
|
|
@@ -164,13 +165,13 @@ const summarizerRequestUrl = "_summarizer";
|
|
|
164
165
|
async function createSummarizer(loader, url) {
|
|
165
166
|
const request = {
|
|
166
167
|
headers: {
|
|
167
|
-
[
|
|
168
|
-
[
|
|
168
|
+
[internal_1.LoaderHeader.cache]: false,
|
|
169
|
+
[internal_1.LoaderHeader.clientDetails]: {
|
|
169
170
|
capabilities: { interactive: false },
|
|
170
171
|
type: index_js_3.summarizerClientType,
|
|
171
172
|
},
|
|
172
|
-
[
|
|
173
|
-
[
|
|
173
|
+
[internal_3.DriverHeader.summarizingClient]: true,
|
|
174
|
+
[internal_1.LoaderHeader.reconnect]: false,
|
|
174
175
|
},
|
|
175
176
|
url,
|
|
176
177
|
};
|
|
@@ -186,12 +187,12 @@ async function createSummarizer(loader, url) {
|
|
|
186
187
|
url: `/${summarizerRequestUrl}`,
|
|
187
188
|
});
|
|
188
189
|
if (response.status !== 200 || response.mimeType !== "fluid/object") {
|
|
189
|
-
throw (0,
|
|
190
|
+
throw (0, internal_6.responseToException)(response, request);
|
|
190
191
|
}
|
|
191
192
|
fluidObject = response.value;
|
|
192
193
|
}
|
|
193
194
|
if (fluidObject?.ISummarizer === undefined) {
|
|
194
|
-
throw new
|
|
195
|
+
throw new internal_7.UsageError("Fluid object does not implement ISummarizer");
|
|
195
196
|
}
|
|
196
197
|
return fluidObject.ISummarizer;
|
|
197
198
|
}
|
|
@@ -233,8 +234,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
233
234
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
234
235
|
const backCompatContext = context;
|
|
235
236
|
const passLogger = backCompatContext.taggedLogger ??
|
|
236
|
-
|
|
237
|
-
|
|
237
|
+
// eslint-disable-next-line import/no-deprecated
|
|
238
|
+
new internal_7.TaggedLoggerAdapter(backCompatContext.logger);
|
|
239
|
+
const logger = (0, internal_7.createChildLogger)({
|
|
238
240
|
logger: passLogger,
|
|
239
241
|
properties: {
|
|
240
242
|
all: {
|
|
@@ -242,7 +244,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
242
244
|
},
|
|
243
245
|
},
|
|
244
246
|
});
|
|
245
|
-
const mc = (0,
|
|
247
|
+
const mc = (0, internal_7.loggerToMonitoringContext)(logger);
|
|
246
248
|
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, explicitSchemaControl = false, } = runtimeOptions;
|
|
247
249
|
const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
|
|
248
250
|
const tryFetchBlob = async (blobName) => {
|
|
@@ -250,8 +252,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
250
252
|
if (context.baseSnapshot && blobId) {
|
|
251
253
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
252
254
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
253
|
-
(0,
|
|
254
|
-
return (0,
|
|
255
|
+
(0, internal_2.assert)(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
|
|
256
|
+
return (0, internal_4.readAndParse)(context.storage, blobId);
|
|
255
257
|
}
|
|
256
258
|
};
|
|
257
259
|
const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
|
|
@@ -265,8 +267,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
265
267
|
const blobManagerSnapshot = await blobManager_js_1.BlobManager.load(context.baseSnapshot?.trees[index_js_3.blobsTreeName], async (id) => {
|
|
266
268
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
267
269
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
268
|
-
(0,
|
|
269
|
-
return (0,
|
|
270
|
+
(0, internal_2.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
|
|
271
|
+
return (0, internal_4.readAndParse)(context.storage, id);
|
|
270
272
|
});
|
|
271
273
|
const messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
272
274
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
@@ -284,7 +286,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
284
286
|
// Older runtimes do not understand new schema, and thus could corrupt document if they proceed, thus we are using
|
|
285
287
|
// this poison pill to prevent them from proceeding.
|
|
286
288
|
// "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
|
|
287
|
-
const error = new
|
|
289
|
+
const error = new internal_7.DataCorruptionError(
|
|
288
290
|
// pre-0.58 error message: SummaryMetadataMismatch
|
|
289
291
|
"Summary metadata mismatch", { runtimeVersion: packageVersion_js_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
|
|
290
292
|
if (loadSequenceNumberVerification === "log") {
|
|
@@ -295,6 +297,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
299
|
}
|
|
300
|
+
let desiredIdCompressorMode;
|
|
301
|
+
switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
|
|
302
|
+
case true:
|
|
303
|
+
desiredIdCompressorMode = "on";
|
|
304
|
+
break;
|
|
305
|
+
case false:
|
|
306
|
+
desiredIdCompressorMode = undefined;
|
|
307
|
+
break;
|
|
308
|
+
default:
|
|
309
|
+
desiredIdCompressorMode = enableRuntimeIdCompressor;
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
298
312
|
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
299
313
|
// allow new containers to turn it on.
|
|
300
314
|
let idCompressorMode;
|
|
@@ -306,27 +320,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
306
320
|
// 3) Same logic applies for "delayed" mode
|
|
307
321
|
// Maybe in the future we will need to enabled (and figure how to do it safely) "delayed" -> "on" change.
|
|
308
322
|
// We could do "off" -> "on" transition too, if all clients start loading compressor (but not using it initially) and
|
|
309
|
-
// do so for a while - this will allow clients to eventually
|
|
323
|
+
// do so for a while - this will allow clients to eventually disregard "off" setting (when it's safe so) and start
|
|
310
324
|
// using compressor in future sessions.
|
|
311
325
|
// Everyting is possible, but it needs to be designed and executed carefully, when such need arises.
|
|
312
326
|
idCompressorMode = metadata?.documentSchema?.runtime
|
|
313
327
|
?.idCompressorMode;
|
|
328
|
+
// This is the only exception to the rule above - we have proper plumbing to load ID compressor on schema change
|
|
329
|
+
// event. It is loaded async (relative to op processing), so this conversion is only safe for off -> delayed conversion!
|
|
330
|
+
if (idCompressorMode === undefined && desiredIdCompressorMode === "delayed") {
|
|
331
|
+
idCompressorMode = desiredIdCompressorMode;
|
|
332
|
+
}
|
|
314
333
|
}
|
|
315
334
|
else {
|
|
316
|
-
|
|
317
|
-
case true:
|
|
318
|
-
idCompressorMode = "on";
|
|
319
|
-
break;
|
|
320
|
-
case false:
|
|
321
|
-
idCompressorMode = undefined;
|
|
322
|
-
break;
|
|
323
|
-
default:
|
|
324
|
-
idCompressorMode = enableRuntimeIdCompressor;
|
|
325
|
-
break;
|
|
326
|
-
}
|
|
335
|
+
idCompressorMode = desiredIdCompressorMode;
|
|
327
336
|
}
|
|
328
337
|
const createIdCompressorFn = async () => {
|
|
329
|
-
const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor");
|
|
338
|
+
const { createIdCompressor, deserializeIdCompressor, createSessionId } = await import("@fluidframework/id-compressor/internal");
|
|
330
339
|
/**
|
|
331
340
|
* Because the IdCompressor emits so much telemetry, this function is used to sample
|
|
332
341
|
* approximately 5% of all clients. Only the given percentage of sessions will emit telemetry.
|
|
@@ -339,7 +348,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
339
348
|
},
|
|
340
349
|
};
|
|
341
350
|
})();
|
|
342
|
-
const compressorLogger = (0,
|
|
351
|
+
const compressorLogger = (0, internal_7.createSampledLogger)(logger, idCompressorEventSampler);
|
|
343
352
|
const pendingLocalState = context.pendingLocalState;
|
|
344
353
|
if (pendingLocalState?.pendingIdCompressorState !== undefined) {
|
|
345
354
|
return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
|
|
@@ -362,6 +371,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
362
371
|
compressionLz4,
|
|
363
372
|
idCompressorMode,
|
|
364
373
|
opGroupingEnabled,
|
|
374
|
+
disallowedVersions: [],
|
|
365
375
|
}, (schema) => {
|
|
366
376
|
runtime.onSchemaChange(schema);
|
|
367
377
|
});
|
|
@@ -383,6 +393,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
383
393
|
enableGroupedBatching,
|
|
384
394
|
explicitSchemaControl,
|
|
385
395
|
}, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
|
|
396
|
+
runtime.blobManager.trackPendingStashedUploads().then(() => {
|
|
397
|
+
// make sure we didn't reconnect before the promise resolved
|
|
398
|
+
if (runtime.delayConnectClientId !== undefined && !runtime.disposed) {
|
|
399
|
+
runtime.delayConnectClientId = undefined;
|
|
400
|
+
runtime.setConnectionStateCore(true, runtime.delayConnectClientId);
|
|
401
|
+
}
|
|
402
|
+
}, (error) => runtime.closeFn(error));
|
|
386
403
|
// Apply stashed ops with a reference sequence number equal to the sequence number of the snapshot,
|
|
387
404
|
// or zero. This must be done before Container replays saved ops.
|
|
388
405
|
await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
|
|
@@ -426,7 +443,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
426
443
|
// That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
|
|
427
444
|
// to reason over such things as session ID space.
|
|
428
445
|
if (this.idCompressorMode === "on") {
|
|
429
|
-
(0,
|
|
446
|
+
(0, internal_2.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
|
|
430
447
|
return this._idCompressor;
|
|
431
448
|
}
|
|
432
449
|
}
|
|
@@ -467,7 +484,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
467
484
|
return this._disposed;
|
|
468
485
|
}
|
|
469
486
|
get summarizer() {
|
|
470
|
-
(0,
|
|
487
|
+
(0, internal_2.assert)(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
|
|
471
488
|
return this._summarizer;
|
|
472
489
|
}
|
|
473
490
|
isSummariesDisabled() {
|
|
@@ -543,11 +560,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
543
560
|
* It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
|
|
544
561
|
* Starting with 1 min and based on recorded usage we can tweak it later on.
|
|
545
562
|
*/
|
|
546
|
-
this.snapshotCacheForLoadingGroupIds = new
|
|
563
|
+
this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
|
|
547
564
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
548
565
|
});
|
|
549
566
|
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
|
|
550
|
-
this.mc = (0,
|
|
567
|
+
this.mc = (0, internal_7.createChildMonitoringContext)({
|
|
551
568
|
logger: this.logger,
|
|
552
569
|
namespace: "ContainerRuntime",
|
|
553
570
|
});
|
|
@@ -651,11 +668,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
651
668
|
this.maxConsecutiveReconnects =
|
|
652
669
|
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
|
|
653
670
|
this.defaultMaxConsecutiveReconnects;
|
|
654
|
-
if (runtimeOptions.flushMode ===
|
|
671
|
+
if (runtimeOptions.flushMode === internal_5.FlushModeExperimental.Async &&
|
|
655
672
|
supportedFeatures?.get("referenceSequenceNumbers") !== true) {
|
|
656
673
|
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
657
674
|
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
658
|
-
this._flushMode =
|
|
675
|
+
this._flushMode = internal_5.FlushMode.TurnBased;
|
|
659
676
|
}
|
|
660
677
|
else {
|
|
661
678
|
this._flushMode = runtimeOptions.flushMode;
|
|
@@ -668,7 +685,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
668
685
|
// This is a runtime enforcement of what's already explicit in the policy's type itself,
|
|
669
686
|
// which dictates the value is either undefined or exactly 5 days in ms.
|
|
670
687
|
// As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
|
|
671
|
-
throw new
|
|
688
|
+
throw new internal_7.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
|
|
672
689
|
}
|
|
673
690
|
}
|
|
674
691
|
this.garbageCollector = index_js_1.GarbageCollector.create({
|
|
@@ -682,12 +699,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
682
699
|
isSummarizerClient: this.isSummarizerClient,
|
|
683
700
|
getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
|
|
684
701
|
getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
|
|
685
|
-
readAndParseBlob: async (id) => (0,
|
|
702
|
+
readAndParseBlob: async (id) => (0, internal_4.readAndParse)(this.storage, id),
|
|
686
703
|
submitMessage: (message) => this.submit(message),
|
|
687
704
|
sessionExpiryTimerStarted: pendingRuntimeState?.sessionExpiryTimerStarted,
|
|
688
705
|
});
|
|
689
706
|
const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
|
|
690
|
-
this.summarizerNode = (0, index_js_3.createRootSummarizerNodeWithGC)((0,
|
|
707
|
+
this.summarizerNode = (0, index_js_3.createRootSummarizerNodeWithGC)((0, internal_7.createChildLogger)({ logger: this.logger, namespace: "SummarizerNode" }),
|
|
691
708
|
// Summarize function to call when summarize is called. Summarizer node always tracks summary state.
|
|
692
709
|
async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
|
|
693
710
|
// Latest change sequence number, no changes since summary applied yet
|
|
@@ -717,15 +734,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
717
734
|
return this.submitSignalFn(envelope2, targetClientId);
|
|
718
735
|
};
|
|
719
736
|
this.channelCollection = new channelCollection_js_1.ChannelCollection((0, channelCollection_js_1.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);
|
|
720
|
-
this.blobManager = new blobManager_js_1.BlobManager(
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
737
|
+
this.blobManager = new blobManager_js_1.BlobManager({
|
|
738
|
+
routeContext: this.handleContext,
|
|
739
|
+
snapshot: blobManagerSnapshot,
|
|
740
|
+
getStorage: () => this.storage,
|
|
741
|
+
sendBlobAttachOp: (localId, blobId) => {
|
|
742
|
+
if (!this.disposed) {
|
|
743
|
+
this.submit({ type: messageTypes_js_1.ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
|
|
744
|
+
localId,
|
|
745
|
+
blobId,
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
blobRequested: (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"),
|
|
750
|
+
isBlobDeleted: (blobPath) => this.garbageCollector.isNodeDeleted(blobPath),
|
|
751
|
+
runtime: this,
|
|
752
|
+
stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
|
|
753
|
+
closeContainer: (error) => this.closeFn(error),
|
|
754
|
+
});
|
|
755
|
+
this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
|
|
729
756
|
this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
|
|
730
757
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
731
758
|
clientId: () => this.clientId,
|
|
@@ -781,7 +808,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
781
808
|
this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
|
|
782
809
|
}
|
|
783
810
|
else {
|
|
784
|
-
const orderedClientLogger = (0,
|
|
811
|
+
const orderedClientLogger = (0, internal_7.createChildLogger)({
|
|
785
812
|
logger: this.logger,
|
|
786
813
|
namespace: "OrderedClientElection",
|
|
787
814
|
});
|
|
@@ -858,9 +885,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
858
885
|
});
|
|
859
886
|
(0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this, this.logger);
|
|
860
887
|
(0, batchTracker_js_1.BindBatchTracker)(this, this.logger);
|
|
861
|
-
this.entryPoint = new
|
|
888
|
+
this.entryPoint = new internal_2.LazyPromise(async () => {
|
|
862
889
|
if (this.isSummarizerClient) {
|
|
863
|
-
(0,
|
|
890
|
+
(0, internal_2.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
|
|
864
891
|
return this._summarizer;
|
|
865
892
|
}
|
|
866
893
|
return provideEntryPoint(this);
|
|
@@ -891,10 +918,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
891
918
|
}
|
|
892
919
|
/* IFluidParentContext APIs that should not be called on Root */
|
|
893
920
|
makeLocallyVisible() {
|
|
894
|
-
(0,
|
|
921
|
+
(0, internal_2.assert)(false, 0x8eb /* should not be called */);
|
|
895
922
|
}
|
|
896
923
|
setChannelDirty(address) {
|
|
897
|
-
(0,
|
|
924
|
+
(0, internal_2.assert)(false, 0x909 /* should not be called */);
|
|
898
925
|
}
|
|
899
926
|
/**
|
|
900
927
|
* Initializes the state from the base snapshot this container runtime loaded from.
|
|
@@ -903,7 +930,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
903
930
|
if (this.idCompressorMode === "on" ||
|
|
904
931
|
(this.idCompressorMode === "delayed" && this.connected)) {
|
|
905
932
|
// This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
|
|
906
|
-
(0,
|
|
933
|
+
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
|
|
907
934
|
this._idCompressor = await this.createIdCompressor();
|
|
908
935
|
}
|
|
909
936
|
await this.garbageCollector.initializeBaseState();
|
|
@@ -937,13 +964,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
937
964
|
*/
|
|
938
965
|
async getSnapshotForLoadingGroupId(loadingGroupIds, pathParts) {
|
|
939
966
|
const sortedLoadingGroupIds = loadingGroupIds.sort();
|
|
940
|
-
(0,
|
|
967
|
+
(0, internal_2.assert)(this.storage.getSnapshot !== undefined, 0x8ed /* getSnapshot api should be defined if used */);
|
|
941
968
|
let loadedFromCache = true;
|
|
942
969
|
// Lookup up in the cache, if not present then make the network call as multiple datastores could
|
|
943
970
|
// be in same loading group. So, once we have fetched the snapshot for that loading group on
|
|
944
971
|
// any request, then cache that as same group could be requested in future too.
|
|
945
972
|
const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
|
|
946
|
-
(0,
|
|
973
|
+
(0, internal_2.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
|
|
947
974
|
loadedFromCache = false;
|
|
948
975
|
return this.storage.getSnapshot({
|
|
949
976
|
cacheSnapshot: false,
|
|
@@ -961,14 +988,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
961
988
|
// Find the snapshotTree inside the returned snapshot based on the path as given in the request.
|
|
962
989
|
const hasIsolatedChannels = (0, index_js_3.rootHasIsolatedChannels)(this.metadata);
|
|
963
990
|
const snapshotTreeForPath = this.getSnapshotTreeForPath(snapshot.snapshotTree, pathParts, hasIsolatedChannels);
|
|
964
|
-
(0,
|
|
991
|
+
(0, internal_2.assert)(snapshotTreeForPath !== undefined, 0x8ef /* no snapshotTree for the path */);
|
|
965
992
|
const snapshotSeqNumber = snapshot.sequenceNumber;
|
|
966
|
-
(0,
|
|
993
|
+
(0, internal_2.assert)(snapshotSeqNumber !== undefined, 0x8f0 /* snapshotSeqNumber should be present */);
|
|
967
994
|
// This assert fires if we get a snapshot older than the snapshot we loaded from. This is a service issue.
|
|
968
995
|
// Snapshots should only move forward. If we observe an older snapshot than the one we loaded from, then likely
|
|
969
996
|
// the file has been overwritten or service lost data.
|
|
970
997
|
if (snapshotSeqNumber < this.deltaManager.initialSequenceNumber) {
|
|
971
|
-
throw
|
|
998
|
+
throw internal_7.DataProcessingError.create("Downloaded snapshot older than snapshot we loaded from", "getSnapshotForLoadingGroupId", undefined, {
|
|
972
999
|
loadingGroupIds: sortedLoadingGroupIds.join(","),
|
|
973
1000
|
snapshotSeqNumber,
|
|
974
1001
|
initialSequenceNumber: this.deltaManager.initialSequenceNumber,
|
|
@@ -991,7 +1018,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
991
1018
|
targetSequenceNumber: snapshotSeqNumber,
|
|
992
1019
|
sequenceNumber: this.deltaManager.lastSequenceNumber, // This is so we reuse some columns in telemetry
|
|
993
1020
|
};
|
|
994
|
-
const event =
|
|
1021
|
+
const event = internal_7.PerformanceEvent.start(this.mc.logger, {
|
|
995
1022
|
...props,
|
|
996
1023
|
});
|
|
997
1024
|
// If the inbound deltas queue is paused or disconnected, we expect a reconnect and unpause
|
|
@@ -999,7 +1026,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
999
1026
|
if (this.deltaManager.inbound.paused) {
|
|
1000
1027
|
props.inboundPaused = this.deltaManager.inbound.paused; // reusing telemetry
|
|
1001
1028
|
}
|
|
1002
|
-
const defP = new
|
|
1029
|
+
const defP = new internal_2.Deferred();
|
|
1003
1030
|
this.deltaManager.on("op", (message) => {
|
|
1004
1031
|
if (message.sequenceNumber >= snapshotSeqNumber) {
|
|
1005
1032
|
defP.resolve(true);
|
|
@@ -1022,7 +1049,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1022
1049
|
let childTree = snapshotTree;
|
|
1023
1050
|
for (const part of pathParts) {
|
|
1024
1051
|
if (hasIsolatedChannels) {
|
|
1025
|
-
childTree = childTree?.trees[
|
|
1052
|
+
childTree = childTree?.trees[internal_5.channelsTreeName];
|
|
1026
1053
|
}
|
|
1027
1054
|
childTree = childTree?.trees[part];
|
|
1028
1055
|
}
|
|
@@ -1036,7 +1063,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1036
1063
|
// @ts-expect-error expected to be used by LTS Loaders and Containers
|
|
1037
1064
|
async request(request) {
|
|
1038
1065
|
try {
|
|
1039
|
-
const parser =
|
|
1066
|
+
const parser = internal_6.RequestParser.create(request);
|
|
1040
1067
|
const id = parser.pathParts[0];
|
|
1041
1068
|
if (id === summarizerRequestUrl && parser.pathParts.length === 1) {
|
|
1042
1069
|
if (this._summarizer !== undefined) {
|
|
@@ -1046,16 +1073,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1046
1073
|
value: this.summarizer,
|
|
1047
1074
|
};
|
|
1048
1075
|
}
|
|
1049
|
-
return (0,
|
|
1076
|
+
return (0, internal_6.create404Response)(request);
|
|
1050
1077
|
}
|
|
1051
1078
|
if (this.requestHandler !== undefined) {
|
|
1052
1079
|
// eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
|
|
1053
1080
|
return this.requestHandler(parser, this);
|
|
1054
1081
|
}
|
|
1055
|
-
return (0,
|
|
1082
|
+
return (0, internal_6.create404Response)(request);
|
|
1056
1083
|
}
|
|
1057
1084
|
catch (error) {
|
|
1058
|
-
return (0,
|
|
1085
|
+
return (0, internal_6.exceptionToResponse)(error);
|
|
1059
1086
|
}
|
|
1060
1087
|
}
|
|
1061
1088
|
/**
|
|
@@ -1064,7 +1091,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1064
1091
|
*/
|
|
1065
1092
|
async resolveHandle(request) {
|
|
1066
1093
|
try {
|
|
1067
|
-
const requestParser =
|
|
1094
|
+
const requestParser = internal_6.RequestParser.create(request);
|
|
1068
1095
|
const id = requestParser.pathParts[0];
|
|
1069
1096
|
if (id === "_channels") {
|
|
1070
1097
|
// eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
|
|
@@ -1078,15 +1105,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1078
1105
|
mimeType: "fluid/object",
|
|
1079
1106
|
value: blob,
|
|
1080
1107
|
}
|
|
1081
|
-
: (0,
|
|
1108
|
+
: (0, internal_6.create404Response)(request);
|
|
1082
1109
|
}
|
|
1083
1110
|
else if (requestParser.pathParts.length > 0) {
|
|
1084
1111
|
return await this.channelCollection.request(request);
|
|
1085
1112
|
}
|
|
1086
|
-
return (0,
|
|
1113
|
+
return (0, internal_6.create404Response)(request);
|
|
1087
1114
|
}
|
|
1088
1115
|
catch (error) {
|
|
1089
|
-
return (0,
|
|
1116
|
+
return (0, internal_6.exceptionToResponse)(error);
|
|
1090
1117
|
}
|
|
1091
1118
|
}
|
|
1092
1119
|
/**
|
|
@@ -1125,35 +1152,35 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1125
1152
|
lastMessage: explitiSchemaControl ? message : undefined,
|
|
1126
1153
|
documentSchema,
|
|
1127
1154
|
};
|
|
1128
|
-
(0,
|
|
1155
|
+
(0, internal_6.addBlobToSummary)(summaryTree, index_js_3.metadataBlobName, JSON.stringify(metadata));
|
|
1129
1156
|
}
|
|
1130
1157
|
addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
|
|
1131
1158
|
this.addMetadataToSummary(summaryTree);
|
|
1132
1159
|
if (this._idCompressor) {
|
|
1133
1160
|
const idCompressorState = JSON.stringify(this._idCompressor.serialize(false));
|
|
1134
|
-
(0,
|
|
1161
|
+
(0, internal_6.addBlobToSummary)(summaryTree, index_js_3.idCompressorBlobName, idCompressorState);
|
|
1135
1162
|
}
|
|
1136
1163
|
if (this.remoteMessageProcessor.partialMessages.size > 0) {
|
|
1137
1164
|
const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
|
|
1138
|
-
(0,
|
|
1165
|
+
(0, internal_6.addBlobToSummary)(summaryTree, index_js_3.chunksBlobName, content);
|
|
1139
1166
|
}
|
|
1140
1167
|
const dataStoreAliases = this.channelCollection.aliases;
|
|
1141
1168
|
if (dataStoreAliases.size > 0) {
|
|
1142
|
-
(0,
|
|
1169
|
+
(0, internal_6.addBlobToSummary)(summaryTree, index_js_3.aliasBlobName, JSON.stringify([...dataStoreAliases]));
|
|
1143
1170
|
}
|
|
1144
1171
|
if (this.summarizerClientElection) {
|
|
1145
1172
|
const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
|
|
1146
|
-
(0,
|
|
1173
|
+
(0, internal_6.addBlobToSummary)(summaryTree, index_js_3.electedSummarizerBlobName, electedSummarizerContent);
|
|
1147
1174
|
}
|
|
1148
1175
|
const blobManagerSummary = this.blobManager.summarize();
|
|
1149
1176
|
// Some storage (like git) doesn't allow empty tree, so we can omit it.
|
|
1150
1177
|
// and the blob manager can handle the tree not existing when loading
|
|
1151
1178
|
if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
|
|
1152
|
-
(0,
|
|
1179
|
+
(0, internal_6.addSummarizeResultToSummary)(summaryTree, index_js_3.blobsTreeName, blobManagerSummary);
|
|
1153
1180
|
}
|
|
1154
1181
|
const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
|
|
1155
1182
|
if (gcSummary !== undefined) {
|
|
1156
|
-
(0,
|
|
1183
|
+
(0, internal_6.addSummarizeResultToSummary)(summaryTree, internal_5.gcTreeKey, gcSummary);
|
|
1157
1184
|
}
|
|
1158
1185
|
}
|
|
1159
1186
|
// Track how many times the container tries to reconnect with pending messages.
|
|
@@ -1198,7 +1225,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1198
1225
|
// Save the old state, reset to false, disable event emit
|
|
1199
1226
|
const oldState = this.dirtyContainer;
|
|
1200
1227
|
this.dirtyContainer = false;
|
|
1201
|
-
(0,
|
|
1228
|
+
(0, internal_2.assert)(this.emitDirtyDocumentEvent, 0x127 /* "dirty document event not set on replay" */);
|
|
1202
1229
|
this.emitDirtyDocumentEvent = false;
|
|
1203
1230
|
let newState;
|
|
1204
1231
|
try {
|
|
@@ -1220,9 +1247,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1220
1247
|
*/
|
|
1221
1248
|
// TODO: markfields: confirm Local- versus Outbound- ContainerRuntimeMessage typing
|
|
1222
1249
|
parseLocalOpContent(serializedContents) {
|
|
1223
|
-
(0,
|
|
1250
|
+
(0, internal_2.assert)(serializedContents !== undefined, 0x6d5 /* content must be defined */);
|
|
1224
1251
|
const message = JSON.parse(serializedContents);
|
|
1225
|
-
(0,
|
|
1252
|
+
(0, internal_2.assert)(message.type !== undefined, 0x6d6 /* incorrect op content format */);
|
|
1226
1253
|
return message;
|
|
1227
1254
|
}
|
|
1228
1255
|
async applyStashedOp(serializedOpContent) {
|
|
@@ -1234,7 +1261,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1234
1261
|
case messageTypes_js_1.ContainerMessageType.Alias:
|
|
1235
1262
|
return this.channelCollection.applyStashedOp(opContents);
|
|
1236
1263
|
case messageTypes_js_1.ContainerMessageType.IdAllocation:
|
|
1237
|
-
|
|
1264
|
+
// IDs allocation ops in stashed state are ignored because the tip state of the compressor
|
|
1265
|
+
// is serialized into the pending state. This is done because generation of new IDs during
|
|
1266
|
+
// stashed op application (or, later, resubmit) must generate new IDs and if the compressor
|
|
1267
|
+
// was loaded from a state serialized at the same time as the summary tree in the stashed state
|
|
1268
|
+
// then it would generate IDs that collide with any in later stashed ops.
|
|
1269
|
+
// In the future, IdCompressor could be extended to have an "applyStashedOp" or similar method
|
|
1270
|
+
// and the runtime could filter out all ID allocation ops from the stashed state and apply them
|
|
1271
|
+
// before applying the rest of the stashed ops. This would accomplish the same thing but with
|
|
1272
|
+
// better performance in future incremental stashed state creation.
|
|
1273
|
+
(0, internal_2.assert)(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1238
1274
|
return;
|
|
1239
1275
|
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
|
|
1240
1276
|
return;
|
|
@@ -1246,14 +1282,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1246
1282
|
throw new Error("rejoin not expected here");
|
|
1247
1283
|
case messageTypes_js_1.ContainerMessageType.GC:
|
|
1248
1284
|
// GC op is only sent in summarizer which should never have stashed ops.
|
|
1249
|
-
throw new
|
|
1285
|
+
throw new internal_7.LoggingError("GC op not expected to be stashed in summarizer");
|
|
1250
1286
|
default: {
|
|
1251
1287
|
// This should be extremely rare for stashed ops.
|
|
1252
1288
|
// It would require a newer runtime stashing ops and then an older one applying them,
|
|
1253
1289
|
// e.g. if an app rolled back its container version
|
|
1254
1290
|
const compatBehavior = opContents.compatDetails?.behavior;
|
|
1255
1291
|
if (!compatBehaviorAllowsMessageType(opContents.type, compatBehavior)) {
|
|
1256
|
-
const error =
|
|
1292
|
+
const error = internal_7.DataProcessingError.create("Stashed runtime message of unknown type", "applyStashedOp", undefined /* sequencedMessage */, {
|
|
1257
1293
|
messageDetails: JSON.stringify({
|
|
1258
1294
|
type: opContents.type,
|
|
1259
1295
|
compatBehavior,
|
|
@@ -1274,6 +1310,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1274
1310
|
this._loadIdCompressor = this.createIdCompressor()
|
|
1275
1311
|
.then((compressor) => {
|
|
1276
1312
|
this._idCompressor = compressor;
|
|
1313
|
+
// Finalize any ranges we received while the compressor was turned off.
|
|
1277
1314
|
for (const range of this.pendingIdCompressorOps) {
|
|
1278
1315
|
this._idCompressor.finalizeCreationRange(range);
|
|
1279
1316
|
}
|
|
@@ -1306,23 +1343,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1306
1343
|
// propagation of the "connected" event until we have uploaded them to
|
|
1307
1344
|
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
1308
1345
|
const connecting = connected && !this._connected;
|
|
1309
|
-
if (connecting && this.blobManager.
|
|
1310
|
-
(0,
|
|
1311
|
-
(0,
|
|
1346
|
+
if (connecting && this.blobManager.hasPendingStashedUploads()) {
|
|
1347
|
+
(0, internal_2.assert)(!this.delayConnectClientId, 0x791 /* Connect event delay must be canceled before subsequent connect event */);
|
|
1348
|
+
(0, internal_2.assert)(!!clientId, 0x792 /* Must have clientId when connecting */);
|
|
1312
1349
|
this.delayConnectClientId = clientId;
|
|
1313
|
-
this.blobManager.processStashedChanges().then(() => {
|
|
1314
|
-
// make sure we didn't reconnect before the promise resolved
|
|
1315
|
-
if (this.delayConnectClientId === clientId && !this.disposed) {
|
|
1316
|
-
this.delayConnectClientId = undefined;
|
|
1317
|
-
this.setConnectionStateCore(connected, clientId);
|
|
1318
|
-
}
|
|
1319
|
-
}, (error) => this.closeFn(error));
|
|
1320
1350
|
return;
|
|
1321
1351
|
}
|
|
1322
1352
|
this.setConnectionStateCore(connected, clientId);
|
|
1323
1353
|
}
|
|
1324
1354
|
setConnectionStateCore(connected, clientId) {
|
|
1325
|
-
(0,
|
|
1355
|
+
(0, internal_2.assert)(!this.delayConnectClientId, 0x394 /* connect event delay must be cleared before propagating connect event */);
|
|
1326
1356
|
this.verifyNotClosed();
|
|
1327
1357
|
// There might be no change of state due to Container calling this API after loading runtime.
|
|
1328
1358
|
const changeOfState = this._connected !== connected;
|
|
@@ -1340,13 +1370,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1340
1370
|
this._perfSignalData.trackingSignalSequenceNumber = undefined;
|
|
1341
1371
|
}
|
|
1342
1372
|
else {
|
|
1343
|
-
(0,
|
|
1373
|
+
(0, internal_2.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x3cd /* Connection is possible only if container exists in storage */);
|
|
1344
1374
|
}
|
|
1345
1375
|
// Fail while disconnected
|
|
1346
1376
|
if (reconnection) {
|
|
1347
1377
|
this.consecutiveReconnects++;
|
|
1348
1378
|
if (!this.shouldContinueReconnecting()) {
|
|
1349
|
-
this.closeFn(
|
|
1379
|
+
this.closeFn(internal_7.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
|
|
1350
1380
|
dataLoss: 1,
|
|
1351
1381
|
attempts: this.consecutiveReconnects,
|
|
1352
1382
|
pendingMessages: this.pendingMessagesCount,
|
|
@@ -1359,7 +1389,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1359
1389
|
}
|
|
1360
1390
|
this.channelCollection.setConnectionState(connected, clientId);
|
|
1361
1391
|
this.garbageCollector.setConnectionState(connected, clientId);
|
|
1362
|
-
(0,
|
|
1392
|
+
(0, internal_7.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
|
|
1363
1393
|
}
|
|
1364
1394
|
async notifyOpReplay(message) {
|
|
1365
1395
|
await this.pendingStateManager.applyStashedOpsAt(message.sequenceNumber);
|
|
@@ -1408,7 +1438,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1408
1438
|
// These calls should be made for all but chunked ops:
|
|
1409
1439
|
// 1) this.pendingStateManager.processPendingLocalMessage() below
|
|
1410
1440
|
// 2) this.resetReconnectCount() below
|
|
1411
|
-
(0,
|
|
1441
|
+
(0, internal_2.assert)(message.type !== messageTypes_js_1.ContainerMessageType.ChunkedOp, "we should never get here with chunked ops");
|
|
1412
1442
|
let localOpMetadata;
|
|
1413
1443
|
if (local && messageWithContext.modernRuntimeMessage) {
|
|
1414
1444
|
localOpMetadata = this.pendingStateManager.processPendingLocalMessage(messageWithContext.message);
|
|
@@ -1459,7 +1489,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1459
1489
|
messageWithContext.message.metadata?.savedOp ===
|
|
1460
1490
|
true)) {
|
|
1461
1491
|
const range = messageWithContext.message.contents;
|
|
1492
|
+
// Some other client turned on the id compressor. If we have not turned it on,
|
|
1493
|
+
// put it in a pending queue and delay finalization.
|
|
1462
1494
|
if (this._idCompressor === undefined) {
|
|
1495
|
+
(0, internal_2.assert)(this.idCompressorMode !== undefined, "id compressor should be enabled");
|
|
1463
1496
|
this.pendingIdCompressorOps.push(range);
|
|
1464
1497
|
}
|
|
1465
1498
|
else {
|
|
@@ -1473,7 +1506,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1473
1506
|
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|
|
1474
1507
|
// From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
|
|
1475
1508
|
// Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
|
|
1476
|
-
(0,
|
|
1509
|
+
(0, internal_2.assert)(false, "should not even get here");
|
|
1477
1510
|
case messageTypes_js_1.ContainerMessageType.Rejoin:
|
|
1478
1511
|
break;
|
|
1479
1512
|
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange:
|
|
@@ -1488,7 +1521,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1488
1521
|
const compatBehavior = messageWithContext.message.compatDetails?.behavior;
|
|
1489
1522
|
if (!compatBehaviorAllowsMessageType(messageWithContext.message.type, compatBehavior)) {
|
|
1490
1523
|
const { message } = messageWithContext;
|
|
1491
|
-
const error =
|
|
1524
|
+
const error = internal_7.DataProcessingError.create(
|
|
1492
1525
|
// Former assert 0x3ce
|
|
1493
1526
|
"Runtime message of unknown type", "OpProcessing", message, {
|
|
1494
1527
|
local,
|
|
@@ -1572,9 +1605,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1572
1605
|
* This method is expected to be called at the end of a batch.
|
|
1573
1606
|
*/
|
|
1574
1607
|
flush() {
|
|
1575
|
-
(0,
|
|
1608
|
+
(0, internal_2.assert)(this._orderSequentiallyCalls === 0, 0x24c /* "Cannot call `flush()` from `orderSequentially`'s callback" */);
|
|
1576
1609
|
this.outbox.flush();
|
|
1577
|
-
(0,
|
|
1610
|
+
(0, internal_2.assert)(this.outbox.isEmpty, 0x3cf /* reentrancy */);
|
|
1578
1611
|
}
|
|
1579
1612
|
/**
|
|
1580
1613
|
* {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.orderSequentially}
|
|
@@ -1599,15 +1632,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1599
1632
|
checkpoint.rollback((message) => this.rollback(message.contents, message.localOpMetadata));
|
|
1600
1633
|
}
|
|
1601
1634
|
catch (err) {
|
|
1602
|
-
const error2 = (0,
|
|
1603
|
-
return
|
|
1635
|
+
const error2 = (0, internal_7.wrapError)(err, (message) => {
|
|
1636
|
+
return internal_7.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
|
|
1604
1637
|
});
|
|
1605
1638
|
this.closeFn(error2);
|
|
1606
1639
|
throw error2;
|
|
1607
1640
|
}
|
|
1608
1641
|
}
|
|
1609
1642
|
else {
|
|
1610
|
-
this.closeFn((0,
|
|
1643
|
+
this.closeFn((0, internal_7.wrapError)(error, (errorMessage) => new internal_7.GenericError(`orderSequentially callback exception: ${errorMessage}`, error, {
|
|
1611
1644
|
orderSequentiallyCalls: this._orderSequentiallyCalls,
|
|
1612
1645
|
})));
|
|
1613
1646
|
}
|
|
@@ -1617,7 +1650,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1617
1650
|
this._orderSequentiallyCalls--;
|
|
1618
1651
|
}
|
|
1619
1652
|
// We don't flush on TurnBased since we expect all messages in the same JS turn to be part of the same batch
|
|
1620
|
-
if (this.flushMode !==
|
|
1653
|
+
if (this.flushMode !== internal_5.FlushMode.TurnBased && this._orderSequentiallyCalls === 0) {
|
|
1621
1654
|
this.flush();
|
|
1622
1655
|
}
|
|
1623
1656
|
return result;
|
|
@@ -1646,7 +1679,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1646
1679
|
}
|
|
1647
1680
|
const channel = await context.realize();
|
|
1648
1681
|
if (channel.entryPoint === undefined) {
|
|
1649
|
-
throw new
|
|
1682
|
+
throw new internal_7.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
|
|
1650
1683
|
}
|
|
1651
1684
|
this.garbageCollector.nodeUpdated(`/${internalId}`, "Loaded", undefined /* timestampMs */, context.packagePath);
|
|
1652
1685
|
return channel.entryPoint;
|
|
@@ -1675,7 +1708,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1675
1708
|
* Are we in the middle of batching ops together?
|
|
1676
1709
|
*/
|
|
1677
1710
|
currentlyBatching() {
|
|
1678
|
-
return this.flushMode !==
|
|
1711
|
+
return this.flushMode !== internal_5.FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
|
|
1679
1712
|
}
|
|
1680
1713
|
getQuorum() {
|
|
1681
1714
|
return this._quorum;
|
|
@@ -1736,7 +1769,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1736
1769
|
/**
|
|
1737
1770
|
* Submits the signal to be sent to other clients.
|
|
1738
1771
|
* @param type - Type of the signal.
|
|
1739
|
-
* @param content - Content of the signal.
|
|
1772
|
+
* @param content - Content of the signal. Should be a JSON serializable object or primitive.
|
|
1740
1773
|
* @param targetClientId - When specified, the signal is only sent to the provided client id.
|
|
1741
1774
|
*/
|
|
1742
1775
|
submitSignal(type, content, targetClientId) {
|
|
@@ -1746,10 +1779,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1746
1779
|
}
|
|
1747
1780
|
setAttachState(attachState) {
|
|
1748
1781
|
if (attachState === container_definitions_1.AttachState.Attaching) {
|
|
1749
|
-
(0,
|
|
1782
|
+
(0, internal_2.assert)(this.attachState === container_definitions_1.AttachState.Attaching, 0x12d /* "Container Context should already be in attaching state" */);
|
|
1750
1783
|
}
|
|
1751
1784
|
else {
|
|
1752
|
-
(0,
|
|
1785
|
+
(0, internal_2.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x12e /* "Container Context should already be in attached state" */);
|
|
1753
1786
|
this.emit("attached");
|
|
1754
1787
|
}
|
|
1755
1788
|
if (attachState === container_definitions_1.AttachState.Attached && !this.hasPendingMessages()) {
|
|
@@ -1772,6 +1805,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1772
1805
|
// We can finalize any allocated IDs since we're the only client
|
|
1773
1806
|
const idRange = this._idCompressor?.takeNextCreationRange();
|
|
1774
1807
|
if (idRange !== undefined) {
|
|
1808
|
+
(0, internal_2.assert)(idRange.ids === undefined || idRange.ids.firstGenCount === 1, "No other ranges should be taken while container is detached.");
|
|
1775
1809
|
this._idCompressor?.finalizeCreationRange(idRange);
|
|
1776
1810
|
}
|
|
1777
1811
|
const summarizeResult = this.channelCollection.getAttachSummary(telemetryContext);
|
|
@@ -1784,7 +1818,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1784
1818
|
const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
|
|
1785
1819
|
// Wrap data store summaries in .channels subtree.
|
|
1786
1820
|
(0, index_js_3.wrapSummaryInChannelsTree)(summarizeResult);
|
|
1787
|
-
const pathPartsForChildren = [
|
|
1821
|
+
const pathPartsForChildren = [internal_5.channelsTreeName];
|
|
1788
1822
|
// Ensure that ID compressor had a chance to load, if we are using delayed mode.
|
|
1789
1823
|
await this.loadIdCompressor();
|
|
1790
1824
|
this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
|
|
@@ -1800,7 +1834,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1800
1834
|
async summarize(options) {
|
|
1801
1835
|
this.verifyNotClosed();
|
|
1802
1836
|
const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
|
|
1803
|
-
const telemetryContext = new
|
|
1837
|
+
const telemetryContext = new internal_6.TelemetryContext();
|
|
1804
1838
|
// Add the options that are used to generate this summary to the telemetry context.
|
|
1805
1839
|
telemetryContext.setMultiple("fluid_Summarize", "Options", {
|
|
1806
1840
|
fullTree,
|
|
@@ -1814,7 +1848,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1814
1848
|
await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
|
|
1815
1849
|
}
|
|
1816
1850
|
const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
|
|
1817
|
-
(0,
|
|
1851
|
+
(0, internal_2.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
|
|
1818
1852
|
return { stats, summary };
|
|
1819
1853
|
}
|
|
1820
1854
|
finally {
|
|
@@ -1842,7 +1876,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1842
1876
|
* @see IGarbageCollectionRuntime.getGCData
|
|
1843
1877
|
*/
|
|
1844
1878
|
async getGCData(fullGC) {
|
|
1845
|
-
const builder = new
|
|
1879
|
+
const builder = new internal_6.GCDataBuilder();
|
|
1846
1880
|
const dsGCData = await this.summarizerNode.getGCData(fullGC);
|
|
1847
1881
|
builder.addNodes(dsGCData.gcNodes);
|
|
1848
1882
|
const blobsGCData = this.blobManager.getGCData(fullGC);
|
|
@@ -1920,7 +1954,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1920
1954
|
case index_js_1.GCNodeType.SubDataStore:
|
|
1921
1955
|
return this.channelCollection.getDataStorePackagePath(nodePath);
|
|
1922
1956
|
default:
|
|
1923
|
-
(0,
|
|
1957
|
+
(0, internal_2.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
|
|
1924
1958
|
}
|
|
1925
1959
|
}
|
|
1926
1960
|
/**
|
|
@@ -1981,16 +2015,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1981
2015
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
1982
2016
|
// use it for all events logged during this summary.
|
|
1983
2017
|
const summaryNumber = this.nextSummaryNumber;
|
|
1984
|
-
const summaryNumberLogger = (0,
|
|
2018
|
+
const summaryNumberLogger = (0, internal_7.createChildLogger)({
|
|
1985
2019
|
logger: summaryLogger,
|
|
1986
2020
|
properties: {
|
|
1987
2021
|
all: { summaryNumber },
|
|
1988
2022
|
},
|
|
1989
2023
|
});
|
|
1990
|
-
(0,
|
|
2024
|
+
(0, internal_2.assert)(this.outbox.isEmpty, 0x3d1 /* Can't trigger summary in the middle of a batch */);
|
|
1991
2025
|
// We close the summarizer and download a new snapshot and reload the container
|
|
1992
2026
|
if (refreshLatestAck === true) {
|
|
1993
|
-
return this.prefetchLatestSummaryThenClose((0,
|
|
2027
|
+
return this.prefetchLatestSummaryThenClose((0, internal_7.createChildLogger)({
|
|
1994
2028
|
logger: summaryNumberLogger,
|
|
1995
2029
|
properties: { all: { safeSummary: true } },
|
|
1996
2030
|
}));
|
|
@@ -2074,7 +2108,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2074
2108
|
// That said, we rely on submitSystemMessage() that today only works in connected state.
|
|
2075
2109
|
// So if we fail here, it either means that RunWhileConnectedCoordinator does not work correctly,
|
|
2076
2110
|
// OR that design changed and we need to remove this check and fix submitSystemMessage.
|
|
2077
|
-
(0,
|
|
2111
|
+
(0, internal_2.assert)(this.connected, 0x258 /* "connected" */);
|
|
2078
2112
|
// Ensure that lastSequenceNumber has not changed after pausing.
|
|
2079
2113
|
// We need the summary op's reference sequence number to match our summary sequence number,
|
|
2080
2114
|
// otherwise we'll get the wrong sequence number stamped on the summary's .protocol attributes.
|
|
@@ -2084,7 +2118,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2084
2118
|
error: `lastSequenceNumber changed before uploading to storage. ${this.deltaManager.lastSequenceNumber} !== ${summaryRefSeqNum}`,
|
|
2085
2119
|
};
|
|
2086
2120
|
}
|
|
2087
|
-
(0,
|
|
2121
|
+
(0, internal_2.assert)(summaryRefSeqNum === this.deltaManager.lastMessage?.sequenceNumber, 0x395 /* it's one and the same thing */);
|
|
2088
2122
|
if (lastAck !== this.summaryCollection.latestAck) {
|
|
2089
2123
|
return {
|
|
2090
2124
|
continue: false,
|
|
@@ -2148,11 +2182,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2148
2182
|
// Counting dataStores and handles
|
|
2149
2183
|
// Because handles are unchanged dataStores in the current logic,
|
|
2150
2184
|
// summarized dataStore count is total dataStore count minus handle count
|
|
2151
|
-
const dataStoreTree = summaryTree.tree[
|
|
2152
|
-
(0,
|
|
2185
|
+
const dataStoreTree = summaryTree.tree[internal_5.channelsTreeName];
|
|
2186
|
+
(0, internal_2.assert)(dataStoreTree.type === protocol_definitions_1.SummaryType.Tree, 0x1fc /* "summary is not a tree" */);
|
|
2153
2187
|
const handleCount = Object.values(dataStoreTree.tree).filter((value) => value.type === protocol_definitions_1.SummaryType.Handle).length;
|
|
2154
|
-
const gcSummaryTreeStats = summaryTree.tree[
|
|
2155
|
-
? (0,
|
|
2188
|
+
const gcSummaryTreeStats = summaryTree.tree[internal_5.gcTreeKey]
|
|
2189
|
+
? (0, internal_6.calculateStats)(summaryTree.tree[internal_5.gcTreeKey])
|
|
2156
2190
|
: undefined;
|
|
2157
2191
|
const summaryStats = {
|
|
2158
2192
|
dataStoreCount: this.channelCollection.size,
|
|
@@ -2263,7 +2297,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2263
2297
|
// the summarizer.
|
|
2264
2298
|
if (finalAttempt &&
|
|
2265
2299
|
this.mc.config.getBoolean("Fluid.Summarizer.SkipFailingIncorrectSummary")) {
|
|
2266
|
-
const error =
|
|
2300
|
+
const error = internal_7.DataProcessingError.create("Pending ops during summarization", "submitSummary", undefined, { pendingMessages: this.pendingMessagesCount });
|
|
2267
2301
|
logger.sendErrorEvent({
|
|
2268
2302
|
eventName: "SkipFailingIncorrectSummary",
|
|
2269
2303
|
referenceSequenceNumber,
|
|
@@ -2296,11 +2330,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2296
2330
|
}
|
|
2297
2331
|
updateDocumentDirtyState(dirty) {
|
|
2298
2332
|
if (this.attachState !== container_definitions_1.AttachState.Attached) {
|
|
2299
|
-
(0,
|
|
2333
|
+
(0, internal_2.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
|
|
2300
2334
|
}
|
|
2301
2335
|
else {
|
|
2302
2336
|
// Other way is not true = see this.isContainerMessageDirtyable()
|
|
2303
|
-
(0,
|
|
2337
|
+
(0, internal_2.assert)(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
|
|
2304
2338
|
}
|
|
2305
2339
|
if (this.dirtyContainer === dirty) {
|
|
2306
2340
|
return;
|
|
@@ -2338,8 +2372,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2338
2372
|
this.verifyNotClosed();
|
|
2339
2373
|
this.verifyCanSubmitOps();
|
|
2340
2374
|
// There should be no ops in detached container state!
|
|
2341
|
-
(0,
|
|
2342
|
-
(0,
|
|
2375
|
+
(0, internal_2.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
|
|
2376
|
+
(0, internal_2.assert)(metadata === undefined ||
|
|
2343
2377
|
containerRuntimeMessage.type === messageTypes_js_1.ContainerMessageType.BlobAttach, "metadata");
|
|
2344
2378
|
const serializedContent = JSON.stringify(containerRuntimeMessage);
|
|
2345
2379
|
// Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
|
|
@@ -2370,7 +2404,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2370
2404
|
// Allow document schema controller to send a message if it needs to propose change in document schema.
|
|
2371
2405
|
// If it needs to send a message, it will call provided callback with payload of such message and rely
|
|
2372
2406
|
// on this callback to do actual sending.
|
|
2373
|
-
this.documentsSchemaController.
|
|
2407
|
+
const contents = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2408
|
+
if (contents) {
|
|
2374
2409
|
const msg = {
|
|
2375
2410
|
type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
|
|
2376
2411
|
contents,
|
|
@@ -2379,7 +2414,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2379
2414
|
contents: JSON.stringify(msg),
|
|
2380
2415
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2381
2416
|
});
|
|
2382
|
-
}
|
|
2417
|
+
}
|
|
2383
2418
|
// If this is attach message for new data store, and we are in a batch, send this op out of order
|
|
2384
2419
|
// Is it safe:
|
|
2385
2420
|
// Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
|
|
@@ -2443,29 +2478,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2443
2478
|
}
|
|
2444
2479
|
};
|
|
2445
2480
|
switch (this.flushMode) {
|
|
2446
|
-
case
|
|
2481
|
+
case internal_5.FlushMode.TurnBased:
|
|
2447
2482
|
// When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
2448
2483
|
// batch at the end of the turn
|
|
2449
2484
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
2450
2485
|
Promise.resolve().then(flush);
|
|
2451
2486
|
break;
|
|
2452
2487
|
// FlushModeExperimental is experimental and not exposed directly in the runtime APIs
|
|
2453
|
-
case
|
|
2488
|
+
case internal_5.FlushModeExperimental.Async:
|
|
2454
2489
|
// When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
|
|
2455
2490
|
// batch when all micro-tasks are complete.
|
|
2456
2491
|
// Compared to TurnBased, this flush mode will capture more ops into the same batch.
|
|
2457
2492
|
setTimeout(flush, 0);
|
|
2458
2493
|
break;
|
|
2459
2494
|
default:
|
|
2460
|
-
(0,
|
|
2495
|
+
(0, internal_2.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
|
|
2461
2496
|
break;
|
|
2462
2497
|
}
|
|
2463
2498
|
}
|
|
2464
2499
|
submitSummaryMessage(contents, referenceSequenceNumber) {
|
|
2465
2500
|
this.verifyNotClosed();
|
|
2466
|
-
(0,
|
|
2501
|
+
(0, internal_2.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
|
|
2467
2502
|
// System message should not be sent in the middle of the batch.
|
|
2468
|
-
(0,
|
|
2503
|
+
(0, internal_2.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
|
|
2469
2504
|
// back-compat: ADO #1385: Make this call unconditional in the future
|
|
2470
2505
|
return this.submitSummaryFn !== undefined
|
|
2471
2506
|
? this.submitSummaryFn(contents, referenceSequenceNumber)
|
|
@@ -2486,7 +2521,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2486
2521
|
if (this.opReentryCallsToReport > 0) {
|
|
2487
2522
|
this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
|
|
2488
2523
|
// We need to capture the call stack in order to inspect the source of this usage pattern
|
|
2489
|
-
(0, index_js_2.getLongStack)(() => new
|
|
2524
|
+
(0, index_js_2.getLongStack)(() => new internal_7.UsageError(errorMessage)));
|
|
2490
2525
|
this.opReentryCallsToReport--;
|
|
2491
2526
|
}
|
|
2492
2527
|
// Creating ops while processing ops can lead
|
|
@@ -2502,7 +2537,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2502
2537
|
// The runtime must enforce op coherence by not allowing ops to be submitted
|
|
2503
2538
|
// while ops are being processed.
|
|
2504
2539
|
if (this.enableOpReentryCheck) {
|
|
2505
|
-
throw new
|
|
2540
|
+
throw new internal_7.UsageError(errorMessage);
|
|
2506
2541
|
}
|
|
2507
2542
|
}
|
|
2508
2543
|
}
|
|
@@ -2527,7 +2562,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2527
2562
|
* @param localOpMetadata - The local metadata associated with the original message.
|
|
2528
2563
|
*/
|
|
2529
2564
|
reSubmitCore(message, localOpMetadata, opMetadata) {
|
|
2530
|
-
(0,
|
|
2565
|
+
(0, internal_2.assert)(!this.isSummarizerClient, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
|
|
2531
2566
|
switch (message.type) {
|
|
2532
2567
|
case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
|
|
2533
2568
|
case messageTypes_js_1.ContainerMessageType.Attach:
|
|
@@ -2568,7 +2603,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2568
2603
|
});
|
|
2569
2604
|
}
|
|
2570
2605
|
else {
|
|
2571
|
-
const error =
|
|
2606
|
+
const error = internal_7.DataProcessingError.create("Resubmitting runtime message of unknown type", "reSubmitCore", undefined /* sequencedMessage */, {
|
|
2572
2607
|
messageDetails: JSON.stringify({
|
|
2573
2608
|
type: message.type,
|
|
2574
2609
|
compatBehavior,
|
|
@@ -2598,8 +2633,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2598
2633
|
async refreshLatestSummaryAck(options) {
|
|
2599
2634
|
const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
|
|
2600
2635
|
// proposalHandle is always passed from RunningSummarizer.
|
|
2601
|
-
(0,
|
|
2602
|
-
const readAndParseBlob = async (id) => (0,
|
|
2636
|
+
(0, internal_2.assert)(proposalHandle !== undefined, 0x766 /* proposalHandle should be available */);
|
|
2637
|
+
const readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
|
|
2603
2638
|
const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq);
|
|
2604
2639
|
/**
|
|
2605
2640
|
* When refreshing a summary ack, this check indicates a new ack of a summary that is newer than the
|
|
@@ -2626,7 +2661,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2626
2661
|
* @returns a generic summarization error
|
|
2627
2662
|
*/
|
|
2628
2663
|
async prefetchLatestSummaryThenClose(summaryLogger) {
|
|
2629
|
-
const readAndParseBlob = async (id) => (0,
|
|
2664
|
+
const readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
|
|
2630
2665
|
// This is a performance optimization as the same parent is likely to be elected again, and would use its
|
|
2631
2666
|
// cache to fetch the snapshot instead of the network.
|
|
2632
2667
|
await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
@@ -2642,7 +2677,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2642
2677
|
}
|
|
2643
2678
|
async closeStaleSummarizer() {
|
|
2644
2679
|
// Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
|
|
2645
|
-
await (0,
|
|
2680
|
+
await (0, internal_2.delay)(this.closeSummarizerDelayMs);
|
|
2646
2681
|
this._summarizer?.stop("latestSummaryStateStale");
|
|
2647
2682
|
this.disposeFn();
|
|
2648
2683
|
}
|
|
@@ -2652,16 +2687,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2652
2687
|
* overridden via options.
|
|
2653
2688
|
*/
|
|
2654
2689
|
async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
|
|
2655
|
-
return
|
|
2690
|
+
return internal_7.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2656
2691
|
const stats = {};
|
|
2657
2692
|
const trace = client_utils_1.Trace.start();
|
|
2658
|
-
const versions = await this.storage.getVersions(null, 1, "prefetchLatestSummaryBeforeClose",
|
|
2659
|
-
(0,
|
|
2693
|
+
const versions = await this.storage.getVersions(null, 1, "prefetchLatestSummaryBeforeClose", internal_3.FetchSource.noCache);
|
|
2694
|
+
(0, internal_2.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
2660
2695
|
stats.getVersionDuration = trace.trace().duration;
|
|
2661
2696
|
const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
|
|
2662
|
-
(0,
|
|
2697
|
+
(0, internal_2.assert)(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
|
|
2663
2698
|
stats.getSnapshotDuration = trace.trace().duration;
|
|
2664
|
-
const latestSnapshotRefSeq = await (0,
|
|
2699
|
+
const latestSnapshotRefSeq = await (0, internal_6.seqFromTree)(maybeSnapshot, readAndParseBlob);
|
|
2665
2700
|
stats.snapshotRefSeq = latestSnapshotRefSeq;
|
|
2666
2701
|
stats.snapshotVersion = versions[0].id;
|
|
2667
2702
|
perfEvent.end(stats);
|
|
@@ -2675,7 +2710,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2675
2710
|
getPendingLocalState(props) {
|
|
2676
2711
|
this.verifyNotClosed();
|
|
2677
2712
|
if (this._orderSequentiallyCalls !== 0) {
|
|
2678
|
-
throw new
|
|
2713
|
+
throw new internal_7.UsageError("can't get state during orderSequentially");
|
|
2679
2714
|
}
|
|
2680
2715
|
this.imminentClosure || (this.imminentClosure = props?.notifyImminentClosure ?? false);
|
|
2681
2716
|
const getSyncState = (pendingAttachmentBlobs) => {
|
|
@@ -2707,8 +2742,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2707
2742
|
// to close current batch.
|
|
2708
2743
|
this.flush();
|
|
2709
2744
|
return props?.notifyImminentClosure === true
|
|
2710
|
-
?
|
|
2711
|
-
:
|
|
2745
|
+
? internal_7.PerformanceEvent.timedExecAsync(this.mc.logger, perfEvent, async (event) => logAndReturnPendingState(event, getSyncState(await this.blobManager.attachAndGetPendingBlobs(props?.stopBlobAttachingSignal))))
|
|
2746
|
+
: internal_7.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
|
|
2712
2747
|
}
|
|
2713
2748
|
summarizeOnDemand(options) {
|
|
2714
2749
|
if (this.isSummarizerClient) {
|
|
@@ -2721,7 +2756,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2721
2756
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
2722
2757
|
// disableSummaries is turned on. We are throwing instead of returning a failure here,
|
|
2723
2758
|
// because it is a misuse of the API rather than an expected failure.
|
|
2724
|
-
throw new
|
|
2759
|
+
throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
2725
2760
|
}
|
|
2726
2761
|
}
|
|
2727
2762
|
enqueueSummarize(options) {
|
|
@@ -2735,7 +2770,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2735
2770
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
2736
2771
|
// generateSummaries is turned off. We are throwing instead of returning a failure here,
|
|
2737
2772
|
// because it is a misuse of the API rather than an expected failure.
|
|
2738
|
-
throw new
|
|
2773
|
+
throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
2739
2774
|
}
|
|
2740
2775
|
}
|
|
2741
2776
|
/**
|
|
@@ -2750,11 +2785,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2750
2785
|
// eslint-disable-next-line no-restricted-syntax
|
|
2751
2786
|
for (const prop in configuration) {
|
|
2752
2787
|
if (typeof configuration[prop] === "number" && configuration[prop] < 0) {
|
|
2753
|
-
throw new
|
|
2788
|
+
throw new internal_7.UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
|
|
2754
2789
|
}
|
|
2755
2790
|
}
|
|
2756
2791
|
if (configuration.minIdleTime > configuration.maxIdleTime) {
|
|
2757
|
-
throw new
|
|
2792
|
+
throw new internal_7.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
|
|
2758
2793
|
}
|
|
2759
2794
|
}
|
|
2760
2795
|
get groupedBatchingEnabled() {
|