@fluidframework/container-runtime 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.225277
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/.eslintrc.js +19 -29
- package/.mocharc.js +12 -0
- package/CHANGELOG.md +427 -0
- package/README.md +69 -0
- package/api-extractor-esm.json +4 -0
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +2 -2
- package/api-report/container-runtime.api.md +863 -0
- package/dist/{batchTracker.js → batchTracker.cjs} +9 -8
- package/dist/batchTracker.cjs.map +1 -0
- package/dist/batchTracker.d.ts +6 -5
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/blobManager.cjs +709 -0
- package/dist/blobManager.cjs.map +1 -0
- package/dist/blobManager.d.ts +140 -39
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/connectionTelemetry.cjs +230 -0
- package/dist/connectionTelemetry.cjs.map +1 -0
- package/dist/connectionTelemetry.d.ts +2 -2
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/container-runtime-alpha.d.ts +1690 -0
- package/dist/container-runtime-beta.d.ts +250 -0
- package/dist/container-runtime-public.d.ts +250 -0
- package/dist/container-runtime-untrimmed.d.ts +1805 -0
- package/dist/{containerHandleContext.js → containerHandleContext.cjs} +4 -2
- package/dist/containerHandleContext.cjs.map +1 -0
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerRuntime.cjs +2535 -0
- package/dist/containerRuntime.cjs.map +1 -0
- package/dist/containerRuntime.d.ts +458 -256
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/{dataStore.js → dataStore.cjs} +54 -45
- package/dist/dataStore.cjs.map +1 -0
- package/dist/dataStore.d.ts +2 -2
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/{dataStoreContext.js → dataStoreContext.cjs} +343 -247
- package/dist/dataStoreContext.cjs.map +1 -0
- package/dist/dataStoreContext.d.ts +73 -41
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/{dataStoreContexts.js → dataStoreContexts.cjs} +19 -15
- package/dist/dataStoreContexts.cjs.map +1 -0
- package/dist/dataStoreContexts.d.ts +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/{dataStoreRegistry.js → dataStoreRegistry.cjs} +9 -4
- package/dist/dataStoreRegistry.cjs.map +1 -0
- package/dist/dataStoreRegistry.d.ts +3 -0
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/{dataStores.js → dataStores.cjs} +276 -124
- package/dist/dataStores.cjs.map +1 -0
- package/dist/dataStores.d.ts +56 -23
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/deltaManagerProxyBase.cjs +77 -0
- package/dist/deltaManagerProxyBase.cjs.map +1 -0
- package/dist/deltaManagerProxyBase.d.ts +35 -0
- package/dist/deltaManagerProxyBase.d.ts.map +1 -0
- package/dist/deltaManagerSummarizerProxy.cjs +42 -0
- package/dist/deltaManagerSummarizerProxy.cjs.map +1 -0
- package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/dist/{deltaScheduler.js → deltaScheduler.cjs} +25 -18
- package/dist/deltaScheduler.cjs.map +1 -0
- package/dist/deltaScheduler.d.ts +8 -6
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/error.cjs +21 -0
- package/dist/error.cjs.map +1 -0
- package/dist/error.d.ts +14 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/gc/garbageCollection.cjs +865 -0
- package/dist/gc/garbageCollection.cjs.map +1 -0
- package/dist/gc/garbageCollection.d.ts +224 -0
- package/dist/gc/garbageCollection.d.ts.map +1 -0
- package/dist/gc/gcConfigs.cjs +160 -0
- package/dist/gc/gcConfigs.cjs.map +1 -0
- package/dist/gc/gcConfigs.d.ts +23 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -0
- package/dist/gc/gcDefinitions.cjs +96 -0
- package/dist/gc/gcDefinitions.cjs.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +458 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -0
- package/dist/gc/gcHelpers.cjs +235 -0
- package/dist/gc/gcHelpers.cjs.map +1 -0
- package/dist/gc/gcHelpers.d.ts +71 -0
- package/dist/gc/gcHelpers.d.ts.map +1 -0
- package/dist/gc/gcReferenceGraphAlgorithm.cjs +49 -0
- package/dist/gc/gcReferenceGraphAlgorithm.cjs.map +1 -0
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
- package/dist/{summarizerTypes.js → gc/gcSummaryDefinitions.cjs} +1 -6
- package/dist/gc/gcSummaryDefinitions.cjs.map +1 -0
- package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
- package/dist/gc/gcSummaryStateTracker.cjs +213 -0
- package/dist/gc/gcSummaryStateTracker.cjs.map +1 -0
- package/dist/gc/gcSummaryStateTracker.d.ts +94 -0
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/dist/gc/gcTelemetry.cjs +307 -0
- package/dist/gc/gcTelemetry.cjs.map +1 -0
- package/dist/gc/gcTelemetry.d.ts +99 -0
- package/dist/gc/gcTelemetry.d.ts.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.cjs +118 -0
- package/dist/gc/gcUnreferencedStateTracker.cjs.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts +40 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
- package/dist/gc/index.cjs +44 -0
- package/dist/gc/index.cjs.map +1 -0
- package/dist/gc/index.d.ts +13 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/index.cjs +47 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +19 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/messageTypes.cjs +37 -0
- package/dist/messageTypes.cjs.map +1 -0
- package/dist/messageTypes.d.ts +142 -0
- package/dist/messageTypes.d.ts.map +1 -0
- package/dist/metadata.cjs +7 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.ts +24 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/opLifecycle/batchManager.cjs +139 -0
- package/dist/opLifecycle/batchManager.cjs.map +1 -0
- package/dist/opLifecycle/batchManager.d.ts +48 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -0
- package/dist/opLifecycle/definitions.cjs +7 -0
- package/dist/opLifecycle/definitions.cjs.map +1 -0
- package/dist/opLifecycle/definitions.d.ts +83 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -0
- package/dist/opLifecycle/index.cjs +26 -0
- package/dist/opLifecycle/index.cjs.map +1 -0
- package/dist/opLifecycle/index.d.ts +13 -0
- package/dist/opLifecycle/index.d.ts.map +1 -0
- package/dist/opLifecycle/opCompressor.cjs +84 -0
- package/dist/opLifecycle/opCompressor.cjs.map +1 -0
- package/dist/opLifecycle/opCompressor.d.ts +18 -0
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -0
- package/dist/opLifecycle/opDecompressor.cjs +132 -0
- package/dist/opLifecycle/opDecompressor.cjs.map +1 -0
- package/dist/opLifecycle/opDecompressor.d.ts +25 -0
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -0
- package/dist/opLifecycle/opGroupingManager.cjs +95 -0
- package/dist/opLifecycle/opGroupingManager.cjs.map +1 -0
- package/dist/opLifecycle/opGroupingManager.d.ts +22 -0
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/dist/opLifecycle/opSplitter.cjs +202 -0
- package/dist/opLifecycle/opSplitter.cjs.map +1 -0
- package/dist/opLifecycle/opSplitter.d.ts +61 -0
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -0
- package/dist/opLifecycle/outbox.cjs +326 -0
- package/dist/opLifecycle/outbox.cjs.map +1 -0
- package/dist/opLifecycle/outbox.d.ts +104 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -0
- package/dist/opLifecycle/remoteMessageProcessor.cjs +136 -0
- package/dist/opLifecycle/remoteMessageProcessor.cjs.map +1 -0
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +47 -0
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
- package/dist/opProperties.cjs +17 -0
- package/dist/opProperties.cjs.map +1 -0
- package/dist/opProperties.d.ts +7 -0
- package/dist/opProperties.d.ts.map +1 -0
- package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
- package/dist/packageVersion.cjs.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/pendingStateManager.cjs +282 -0
- package/dist/pendingStateManager.cjs.map +1 -0
- package/dist/pendingStateManager.d.ts +32 -69
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/scheduleManager.cjs +258 -0
- package/dist/scheduleManager.cjs.map +1 -0
- package/dist/scheduleManager.d.ts +31 -0
- package/dist/scheduleManager.d.ts.map +1 -0
- package/dist/storageServiceWithAttachBlobs.cjs +32 -0
- package/dist/storageServiceWithAttachBlobs.cjs.map +1 -0
- package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/dist/summary/index.cjs +51 -0
- package/dist/summary/index.cjs.map +1 -0
- package/dist/summary/index.d.ts +17 -0
- package/dist/summary/index.d.ts.map +1 -0
- package/dist/{orderedClientElection.js → summary/orderedClientElection.cjs} +100 -84
- package/dist/summary/orderedClientElection.cjs.map +1 -0
- package/{lib → dist/summary}/orderedClientElection.d.ts +41 -18
- package/dist/summary/orderedClientElection.d.ts.map +1 -0
- package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.cjs} +12 -10
- package/dist/summary/runWhileConnectedCoordinator.cjs.map +1 -0
- package/{lib → dist/summary}/runWhileConnectedCoordinator.d.ts +8 -2
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/dist/summary/runningSummarizer.cjs +679 -0
- package/dist/summary/runningSummarizer.cjs.map +1 -0
- package/dist/summary/runningSummarizer.d.ts +128 -0
- package/dist/summary/runningSummarizer.d.ts.map +1 -0
- package/dist/summary/summarizer.cjs +263 -0
- package/dist/summary/summarizer.cjs.map +1 -0
- package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +18 -33
- package/dist/summary/summarizer.d.ts.map +1 -0
- package/dist/{summarizerClientElection.js → summary/summarizerClientElection.cjs} +15 -46
- package/dist/summary/summarizerClientElection.cjs.map +1 -0
- package/{lib → dist/summary}/summarizerClientElection.d.ts +4 -4
- package/dist/summary/summarizerClientElection.d.ts.map +1 -0
- package/dist/summary/summarizerHeuristics.cjs +156 -0
- package/dist/summary/summarizerHeuristics.cjs.map +1 -0
- package/{lib → dist/summary}/summarizerHeuristics.d.ts +28 -6
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
- package/dist/summary/summarizerNode/index.cjs +12 -0
- package/dist/summary/summarizerNode/index.cjs.map +1 -0
- package/dist/summary/summarizerNode/index.d.ts +8 -0
- package/dist/summary/summarizerNode/index.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.cjs +526 -0
- package/dist/summary/summarizerNode/summarizerNode.cjs.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts +167 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.cjs +130 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.cjs.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +121 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs +375 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +153 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
- package/dist/summary/summarizerTypes.cjs +7 -0
- package/dist/summary/summarizerTypes.cjs.map +1 -0
- package/{lib → dist/summary}/summarizerTypes.d.ts +233 -83
- package/dist/summary/summarizerTypes.d.ts.map +1 -0
- package/dist/{summaryCollection.js → summary/summaryCollection.cjs} +80 -49
- package/dist/summary/summaryCollection.cjs.map +1 -0
- package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +23 -5
- package/dist/summary/summaryCollection.d.ts.map +1 -0
- package/dist/{summaryFormat.js → summary/summaryFormat.cjs} +29 -26
- package/dist/summary/summaryFormat.cjs.map +1 -0
- package/{lib → dist/summary}/summaryFormat.d.ts +25 -30
- package/dist/summary/summaryFormat.d.ts.map +1 -0
- package/dist/{summaryGenerator.js → summary/summaryGenerator.cjs} +162 -74
- package/dist/summary/summaryGenerator.cjs.map +1 -0
- package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +53 -11
- package/dist/summary/summaryGenerator.d.ts.map +1 -0
- package/dist/{summaryManager.js → summary/summaryManager.cjs} +98 -55
- package/dist/summary/summaryManager.cjs.map +1 -0
- package/{lib → dist/summary}/summaryManager.d.ts +13 -11
- package/dist/summary/summaryManager.d.ts.map +1 -0
- package/dist/{throttler.js → throttler.cjs} +21 -21
- package/dist/throttler.cjs.map +1 -0
- package/dist/throttler.d.ts +2 -2
- package/dist/throttler.d.ts.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/lib/{batchTracker.d.ts → batchTracker.d.mts} +7 -6
- package/lib/batchTracker.d.mts.map +1 -0
- package/lib/{batchTracker.js → batchTracker.mjs} +9 -8
- package/lib/batchTracker.mjs.map +1 -0
- package/lib/blobManager.d.mts +196 -0
- package/lib/blobManager.d.mts.map +1 -0
- package/lib/blobManager.mjs +704 -0
- package/lib/blobManager.mjs.map +1 -0
- package/lib/{connectionTelemetry.d.ts → connectionTelemetry.d.mts} +3 -3
- package/lib/connectionTelemetry.d.mts.map +1 -0
- package/lib/connectionTelemetry.mjs +226 -0
- package/lib/connectionTelemetry.mjs.map +1 -0
- package/lib/container-runtime-alpha.d.mts +1690 -0
- package/lib/container-runtime-beta.d.mts +250 -0
- package/lib/container-runtime-public.d.mts +250 -0
- package/lib/container-runtime-untrimmed.d.mts +1805 -0
- package/lib/{containerHandleContext.d.ts → containerHandleContext.d.mts} +2 -2
- package/lib/containerHandleContext.d.mts.map +1 -0
- package/lib/{containerHandleContext.js → containerHandleContext.mjs} +4 -2
- package/lib/containerHandleContext.mjs.map +1 -0
- package/lib/containerRuntime.d.mts +813 -0
- package/lib/containerRuntime.d.mts.map +1 -0
- package/lib/containerRuntime.mjs +2530 -0
- package/lib/containerRuntime.mjs.map +1 -0
- package/lib/{dataStore.d.ts → dataStore.d.mts} +5 -5
- package/lib/dataStore.d.mts.map +1 -0
- package/lib/{dataStore.js → dataStore.mjs} +52 -43
- package/lib/dataStore.mjs.map +1 -0
- package/lib/{dataStoreContext.d.ts → dataStoreContext.d.mts} +75 -43
- package/lib/dataStoreContext.d.mts.map +1 -0
- package/lib/{dataStoreContext.js → dataStoreContext.mjs} +309 -213
- package/lib/dataStoreContext.mjs.map +1 -0
- package/lib/{dataStoreContexts.d.ts → dataStoreContexts.d.mts} +3 -3
- package/lib/dataStoreContexts.d.mts.map +1 -0
- package/lib/{dataStoreContexts.js → dataStoreContexts.mjs} +12 -8
- package/lib/dataStoreContexts.mjs.map +1 -0
- package/lib/{dataStoreRegistry.d.ts → dataStoreRegistry.d.mts} +4 -1
- package/lib/dataStoreRegistry.d.mts.map +1 -0
- package/lib/{dataStoreRegistry.js → dataStoreRegistry.mjs} +7 -6
- package/lib/dataStoreRegistry.mjs.map +1 -0
- package/lib/{dataStores.d.ts → dataStores.d.mts} +60 -27
- package/lib/dataStores.d.mts.map +1 -0
- package/lib/{dataStores.js → dataStores.mjs} +257 -105
- package/lib/dataStores.mjs.map +1 -0
- package/lib/deltaManagerProxyBase.d.mts +35 -0
- package/lib/deltaManagerProxyBase.d.mts.map +1 -0
- package/lib/deltaManagerProxyBase.mjs +73 -0
- package/lib/deltaManagerProxyBase.mjs.map +1 -0
- package/lib/deltaManagerSummarizerProxy.d.mts +19 -0
- package/lib/deltaManagerSummarizerProxy.d.mts.map +1 -0
- package/lib/deltaManagerSummarizerProxy.mjs +38 -0
- package/lib/deltaManagerSummarizerProxy.mjs.map +1 -0
- package/lib/{deltaScheduler.d.ts → deltaScheduler.d.mts} +9 -7
- package/lib/deltaScheduler.d.mts.map +1 -0
- package/lib/{deltaScheduler.js → deltaScheduler.mjs} +22 -15
- package/lib/deltaScheduler.mjs.map +1 -0
- package/lib/error.d.mts +14 -0
- package/lib/error.d.mts.map +1 -0
- package/lib/error.mjs +17 -0
- package/lib/error.mjs.map +1 -0
- package/lib/gc/garbageCollection.d.mts +224 -0
- package/lib/gc/garbageCollection.d.mts.map +1 -0
- package/lib/gc/garbageCollection.mjs +861 -0
- package/lib/gc/garbageCollection.mjs.map +1 -0
- package/lib/gc/gcConfigs.d.mts +23 -0
- package/lib/gc/gcConfigs.d.mts.map +1 -0
- package/lib/gc/gcConfigs.mjs +156 -0
- package/lib/gc/gcConfigs.mjs.map +1 -0
- package/lib/gc/gcDefinitions.d.mts +458 -0
- package/lib/gc/gcDefinitions.d.mts.map +1 -0
- package/lib/gc/gcDefinitions.mjs +93 -0
- package/lib/gc/gcDefinitions.mjs.map +1 -0
- package/lib/gc/gcHelpers.d.mts +71 -0
- package/lib/gc/gcHelpers.d.mts.map +1 -0
- package/lib/gc/gcHelpers.mjs +222 -0
- package/lib/gc/gcHelpers.mjs.map +1 -0
- package/lib/gc/gcReferenceGraphAlgorithm.d.mts +16 -0
- package/lib/gc/gcReferenceGraphAlgorithm.d.mts.map +1 -0
- package/lib/gc/gcReferenceGraphAlgorithm.mjs +45 -0
- package/lib/gc/gcReferenceGraphAlgorithm.mjs.map +1 -0
- package/lib/gc/gcSummaryDefinitions.d.mts +52 -0
- package/lib/gc/gcSummaryDefinitions.d.mts.map +1 -0
- package/lib/gc/gcSummaryDefinitions.mjs +6 -0
- package/lib/gc/gcSummaryDefinitions.mjs.map +1 -0
- package/lib/gc/gcSummaryStateTracker.d.mts +94 -0
- package/lib/gc/gcSummaryStateTracker.d.mts.map +1 -0
- package/lib/gc/gcSummaryStateTracker.mjs +209 -0
- package/lib/gc/gcSummaryStateTracker.mjs.map +1 -0
- package/lib/gc/gcTelemetry.d.mts +99 -0
- package/lib/gc/gcTelemetry.d.mts.map +1 -0
- package/lib/gc/gcTelemetry.mjs +302 -0
- package/lib/gc/gcTelemetry.mjs.map +1 -0
- package/lib/gc/gcUnreferencedStateTracker.d.mts +40 -0
- package/lib/gc/gcUnreferencedStateTracker.d.mts.map +1 -0
- package/lib/gc/gcUnreferencedStateTracker.mjs +114 -0
- package/lib/gc/gcUnreferencedStateTracker.mjs.map +1 -0
- package/lib/gc/index.d.mts +13 -0
- package/lib/gc/index.d.mts.map +1 -0
- package/lib/gc/index.mjs +12 -0
- package/lib/gc/index.mjs.map +1 -0
- package/lib/index.d.mts +25 -0
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +24 -0
- package/lib/index.mjs.map +1 -0
- package/lib/messageTypes.d.mts +142 -0
- package/lib/messageTypes.d.mts.map +1 -0
- package/lib/messageTypes.mjs +34 -0
- package/lib/messageTypes.mjs.map +1 -0
- package/lib/metadata.d.mts +24 -0
- package/lib/metadata.d.mts.map +1 -0
- package/lib/metadata.mjs +6 -0
- package/lib/metadata.mjs.map +1 -0
- package/lib/opLifecycle/batchManager.d.mts +48 -0
- package/lib/opLifecycle/batchManager.d.mts.map +1 -0
- package/lib/opLifecycle/batchManager.mjs +133 -0
- package/lib/opLifecycle/batchManager.mjs.map +1 -0
- package/lib/opLifecycle/definitions.d.mts +83 -0
- package/lib/opLifecycle/definitions.d.mts.map +1 -0
- package/lib/opLifecycle/definitions.mjs +6 -0
- package/lib/opLifecycle/definitions.mjs.map +1 -0
- package/lib/opLifecycle/index.d.mts +13 -0
- package/lib/opLifecycle/index.d.mts.map +1 -0
- package/lib/opLifecycle/index.mjs +12 -0
- package/lib/opLifecycle/index.mjs.map +1 -0
- package/lib/opLifecycle/opCompressor.d.mts +18 -0
- package/lib/opLifecycle/opCompressor.d.mts.map +1 -0
- package/lib/opLifecycle/opCompressor.mjs +80 -0
- package/lib/opLifecycle/opCompressor.mjs.map +1 -0
- package/lib/opLifecycle/opDecompressor.d.mts +25 -0
- package/lib/opLifecycle/opDecompressor.d.mts.map +1 -0
- package/lib/opLifecycle/opDecompressor.mjs +128 -0
- package/lib/opLifecycle/opDecompressor.mjs.map +1 -0
- package/lib/opLifecycle/opGroupingManager.d.mts +22 -0
- package/lib/opLifecycle/opGroupingManager.d.mts.map +1 -0
- package/lib/opLifecycle/opGroupingManager.mjs +91 -0
- package/lib/opLifecycle/opGroupingManager.mjs.map +1 -0
- package/lib/opLifecycle/opSplitter.d.mts +61 -0
- package/lib/opLifecycle/opSplitter.d.mts.map +1 -0
- package/lib/opLifecycle/opSplitter.mjs +197 -0
- package/lib/opLifecycle/opSplitter.mjs.map +1 -0
- package/lib/opLifecycle/outbox.d.mts +104 -0
- package/lib/opLifecycle/outbox.d.mts.map +1 -0
- package/lib/opLifecycle/outbox.mjs +321 -0
- package/lib/opLifecycle/outbox.mjs.map +1 -0
- package/lib/opLifecycle/remoteMessageProcessor.d.mts +47 -0
- package/lib/opLifecycle/remoteMessageProcessor.d.mts.map +1 -0
- package/lib/opLifecycle/remoteMessageProcessor.mjs +131 -0
- package/lib/opLifecycle/remoteMessageProcessor.mjs.map +1 -0
- package/lib/opProperties.d.mts +7 -0
- package/lib/opProperties.d.mts.map +1 -0
- package/lib/opProperties.mjs +13 -0
- package/lib/opProperties.mjs.map +1 -0
- package/lib/{packageVersion.d.ts → packageVersion.d.mts} +2 -2
- package/lib/packageVersion.d.mts.map +1 -0
- package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
- package/lib/packageVersion.mjs.map +1 -0
- package/lib/{pendingStateManager.d.ts → pendingStateManager.d.mts} +33 -70
- package/lib/pendingStateManager.d.mts.map +1 -0
- package/lib/pendingStateManager.mjs +275 -0
- package/lib/pendingStateManager.mjs.map +1 -0
- package/lib/scheduleManager.d.mts +27 -0
- package/lib/scheduleManager.d.mts.map +1 -0
- package/lib/scheduleManager.mjs +254 -0
- package/lib/scheduleManager.mjs.map +1 -0
- package/lib/storageServiceWithAttachBlobs.d.mts +17 -0
- package/lib/storageServiceWithAttachBlobs.d.mts.map +1 -0
- package/lib/storageServiceWithAttachBlobs.mjs +28 -0
- package/lib/storageServiceWithAttachBlobs.mjs.map +1 -0
- package/lib/summary/index.d.mts +17 -0
- package/lib/summary/index.d.mts.map +1 -0
- package/lib/summary/index.mjs +16 -0
- package/lib/summary/index.mjs.map +1 -0
- package/{dist/orderedClientElection.d.ts → lib/summary/orderedClientElection.d.mts} +42 -23
- package/lib/summary/orderedClientElection.d.mts.map +1 -0
- package/lib/{orderedClientElection.js → summary/orderedClientElection.mjs} +95 -79
- package/lib/summary/orderedClientElection.mjs.map +1 -0
- package/{dist/runWhileConnectedCoordinator.d.ts → lib/summary/runWhileConnectedCoordinator.d.mts} +10 -4
- package/lib/summary/runWhileConnectedCoordinator.d.mts.map +1 -0
- package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.mjs} +12 -10
- package/lib/summary/runWhileConnectedCoordinator.mjs.map +1 -0
- package/lib/summary/runningSummarizer.d.mts +128 -0
- package/lib/summary/runningSummarizer.d.mts.map +1 -0
- package/lib/summary/runningSummarizer.mjs +675 -0
- package/lib/summary/runningSummarizer.mjs.map +1 -0
- package/lib/{summarizer.d.ts → summary/summarizer.d.mts} +21 -36
- package/lib/summary/summarizer.d.mts.map +1 -0
- package/lib/summary/summarizer.mjs +257 -0
- package/lib/summary/summarizer.mjs.map +1 -0
- package/{dist/summarizerClientElection.d.ts → lib/summary/summarizerClientElection.d.mts} +7 -7
- package/lib/summary/summarizerClientElection.d.mts.map +1 -0
- package/lib/{summarizerClientElection.js → summary/summarizerClientElection.mjs} +14 -45
- package/lib/summary/summarizerClientElection.mjs.map +1 -0
- package/{dist/summarizerHeuristics.d.ts → lib/summary/summarizerHeuristics.d.mts} +30 -8
- package/lib/summary/summarizerHeuristics.d.mts.map +1 -0
- package/lib/summary/summarizerHeuristics.mjs +151 -0
- package/lib/summary/summarizerHeuristics.mjs.map +1 -0
- package/lib/summary/summarizerNode/index.d.mts +8 -0
- package/lib/summary/summarizerNode/index.d.mts.map +1 -0
- package/lib/summary/summarizerNode/index.mjs +7 -0
- package/lib/summary/summarizerNode/index.mjs.map +1 -0
- package/lib/summary/summarizerNode/summarizerNode.d.mts +167 -0
- package/lib/summary/summarizerNode/summarizerNode.d.mts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNode.mjs +521 -0
- package/lib/summary/summarizerNode/summarizerNode.mjs.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts +121 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.mjs +123 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts +153 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs +370 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +1 -0
- package/{dist/summarizerTypes.d.ts → lib/summary/summarizerTypes.d.mts} +235 -85
- package/lib/summary/summarizerTypes.d.mts.map +1 -0
- package/lib/summary/summarizerTypes.mjs +6 -0
- package/lib/summary/summarizerTypes.mjs.map +1 -0
- package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.mts} +24 -6
- package/lib/summary/summaryCollection.d.mts.map +1 -0
- package/lib/{summaryCollection.js → summary/summaryCollection.mjs} +76 -45
- package/lib/summary/summaryCollection.mjs.map +1 -0
- package/{dist/summaryFormat.d.ts → lib/summary/summaryFormat.d.mts} +26 -31
- package/lib/summary/summaryFormat.d.mts.map +1 -0
- package/lib/{summaryFormat.js → summary/summaryFormat.mjs} +30 -26
- package/lib/summary/summaryFormat.mjs.map +1 -0
- package/lib/summary/summaryGenerator.d.mts +127 -0
- package/lib/summary/summaryGenerator.d.mts.map +1 -0
- package/lib/{summaryGenerator.js → summary/summaryGenerator.mjs} +153 -67
- package/lib/summary/summaryGenerator.mjs.map +1 -0
- package/{dist/summaryManager.d.ts → lib/summary/summaryManager.d.mts} +16 -14
- package/lib/summary/summaryManager.d.mts.map +1 -0
- package/lib/{summaryManager.js → summary/summaryManager.mjs} +94 -51
- package/lib/summary/summaryManager.mjs.map +1 -0
- package/lib/{throttler.d.ts → throttler.d.mts} +3 -3
- package/lib/throttler.d.mts.map +1 -0
- package/lib/{throttler.js → throttler.mjs} +21 -21
- package/lib/throttler.mjs.map +1 -0
- package/package.json +199 -71
- package/prettier.config.cjs +8 -0
- package/src/batchTracker.ts +59 -54
- package/src/blobManager.ts +942 -294
- package/src/connectionTelemetry.ts +342 -252
- package/src/containerHandleContext.ts +27 -29
- package/src/containerRuntime.ts +3883 -3143
- package/src/dataStore.ts +170 -140
- package/src/dataStoreContext.ts +1166 -986
- package/src/dataStoreContexts.ts +176 -163
- package/src/dataStoreRegistry.ts +29 -21
- package/src/dataStores.ts +924 -678
- package/src/deltaManagerProxyBase.ts +111 -0
- package/src/deltaManagerSummarizerProxy.ts +49 -0
- package/src/deltaScheduler.ts +161 -156
- package/src/error.ts +21 -0
- package/src/gc/garbageCollection.md +106 -0
- package/src/gc/garbageCollection.ts +1157 -0
- package/src/gc/gcConfigs.ts +224 -0
- package/src/gc/gcDefinitions.ts +524 -0
- package/src/gc/gcHelpers.ts +284 -0
- package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
- package/src/gc/gcSummaryDefinitions.ts +54 -0
- package/src/gc/gcSummaryStateTracker.ts +299 -0
- package/src/gc/gcTelemetry.ts +433 -0
- package/src/gc/gcUnreferencedStateTracker.ts +153 -0
- package/src/gc/index.ts +60 -0
- package/src/index.ts +101 -74
- package/src/messageTypes.ts +238 -0
- package/src/metadata.ts +26 -0
- package/src/opLifecycle/README.md +321 -0
- package/src/opLifecycle/batchManager.ts +179 -0
- package/src/opLifecycle/definitions.ts +89 -0
- package/src/opLifecycle/index.ts +19 -0
- package/src/opLifecycle/opCompressor.ts +99 -0
- package/src/opLifecycle/opDecompressor.ts +190 -0
- package/src/opLifecycle/opGroupingManager.ts +133 -0
- package/src/opLifecycle/opSplitter.ts +279 -0
- package/src/opLifecycle/outbox.ts +474 -0
- package/src/opLifecycle/remoteMessageProcessor.ts +175 -0
- package/src/opProperties.ts +21 -0
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +396 -465
- package/src/scheduleManager.ts +358 -0
- package/src/storageServiceWithAttachBlobs.ts +38 -0
- package/src/summary/index.ts +109 -0
- package/src/summary/orderedClientElection.ts +571 -0
- package/src/summary/runWhileConnectedCoordinator.ts +117 -0
- package/src/summary/runningSummarizer.ts +920 -0
- package/src/summary/summarizer.ts +352 -0
- package/src/summary/summarizerClientElection.ts +140 -0
- package/src/summary/summarizerHeuristics.ts +227 -0
- package/src/summary/summarizerNode/index.ts +12 -0
- package/src/summary/summarizerNode/summarizerNode.ts +725 -0
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +206 -0
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +571 -0
- package/src/summary/summarizerTypes.ts +631 -0
- package/src/summary/summaryCollection.ts +474 -0
- package/src/summary/summaryFormat.ts +249 -0
- package/src/summary/summaryGenerator.ts +539 -0
- package/src/summary/summaryManager.ts +452 -0
- package/src/throttler.ts +131 -122
- package/tsc-multi.test.json +4 -0
- package/tsconfig.json +11 -13
- package/dist/batchTracker.js.map +0 -1
- package/dist/blobManager.js +0 -249
- package/dist/blobManager.js.map +0 -1
- package/dist/connectionTelemetry.js +0 -178
- package/dist/connectionTelemetry.js.map +0 -1
- package/dist/containerHandleContext.js.map +0 -1
- package/dist/containerRuntime.js +0 -2174
- package/dist/containerRuntime.js.map +0 -1
- package/dist/dataStore.js.map +0 -1
- package/dist/dataStoreContext.js.map +0 -1
- package/dist/dataStoreContexts.js.map +0 -1
- package/dist/dataStoreRegistry.js.map +0 -1
- package/dist/dataStores.js.map +0 -1
- package/dist/deltaScheduler.js.map +0 -1
- package/dist/garbageCollection.d.ts +0 -319
- package/dist/garbageCollection.d.ts.map +0 -1
- package/dist/garbageCollection.js +0 -993
- package/dist/garbageCollection.js.map +0 -1
- package/dist/index.js +0 -33
- package/dist/index.js.map +0 -1
- package/dist/opTelemetry.d.ts +0 -22
- package/dist/opTelemetry.d.ts.map +0 -1
- package/dist/opTelemetry.js +0 -60
- package/dist/opTelemetry.js.map +0 -1
- package/dist/orderedClientElection.d.ts.map +0 -1
- package/dist/orderedClientElection.js.map +0 -1
- package/dist/packageVersion.js.map +0 -1
- package/dist/pendingStateManager.js +0 -346
- package/dist/pendingStateManager.js.map +0 -1
- package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/dist/runWhileConnectedCoordinator.js.map +0 -1
- package/dist/runningSummarizer.d.ts +0 -93
- package/dist/runningSummarizer.d.ts.map +0 -1
- package/dist/runningSummarizer.js +0 -384
- package/dist/runningSummarizer.js.map +0 -1
- package/dist/serializedSnapshotStorage.d.ts +0 -58
- package/dist/serializedSnapshotStorage.d.ts.map +0 -1
- package/dist/serializedSnapshotStorage.js +0 -108
- package/dist/serializedSnapshotStorage.js.map +0 -1
- package/dist/summarizer.d.ts.map +0 -1
- package/dist/summarizer.js +0 -348
- package/dist/summarizer.js.map +0 -1
- package/dist/summarizerClientElection.d.ts.map +0 -1
- package/dist/summarizerClientElection.js.map +0 -1
- package/dist/summarizerHandle.d.ts +0 -12
- package/dist/summarizerHandle.d.ts.map +0 -1
- package/dist/summarizerHandle.js +0 -22
- package/dist/summarizerHandle.js.map +0 -1
- package/dist/summarizerHeuristics.d.ts.map +0 -1
- package/dist/summarizerHeuristics.js +0 -84
- package/dist/summarizerHeuristics.js.map +0 -1
- package/dist/summarizerTypes.d.ts.map +0 -1
- package/dist/summarizerTypes.js.map +0 -1
- package/dist/summaryCollection.d.ts.map +0 -1
- package/dist/summaryCollection.js.map +0 -1
- package/dist/summaryFormat.d.ts.map +0 -1
- package/dist/summaryFormat.js.map +0 -1
- package/dist/summaryGenerator.d.ts.map +0 -1
- package/dist/summaryGenerator.js.map +0 -1
- package/dist/summaryManager.d.ts.map +0 -1
- package/dist/summaryManager.js.map +0 -1
- package/dist/throttler.js.map +0 -1
- package/garbageCollection.md +0 -41
- package/lib/batchTracker.d.ts.map +0 -1
- package/lib/batchTracker.js.map +0 -1
- package/lib/blobManager.d.ts +0 -95
- package/lib/blobManager.d.ts.map +0 -1
- package/lib/blobManager.js +0 -244
- package/lib/blobManager.js.map +0 -1
- package/lib/connectionTelemetry.d.ts.map +0 -1
- package/lib/connectionTelemetry.js +0 -174
- package/lib/connectionTelemetry.js.map +0 -1
- package/lib/containerHandleContext.d.ts.map +0 -1
- package/lib/containerHandleContext.js.map +0 -1
- package/lib/containerRuntime.d.ts +0 -615
- package/lib/containerRuntime.d.ts.map +0 -1
- package/lib/containerRuntime.js +0 -2166
- package/lib/containerRuntime.js.map +0 -1
- package/lib/dataStore.d.ts.map +0 -1
- package/lib/dataStore.js.map +0 -1
- package/lib/dataStoreContext.d.ts.map +0 -1
- package/lib/dataStoreContext.js.map +0 -1
- package/lib/dataStoreContexts.d.ts.map +0 -1
- package/lib/dataStoreContexts.js.map +0 -1
- package/lib/dataStoreRegistry.d.ts.map +0 -1
- package/lib/dataStoreRegistry.js.map +0 -1
- package/lib/dataStores.d.ts.map +0 -1
- package/lib/dataStores.js.map +0 -1
- package/lib/deltaScheduler.d.ts.map +0 -1
- package/lib/deltaScheduler.js.map +0 -1
- package/lib/garbageCollection.d.ts +0 -319
- package/lib/garbageCollection.d.ts.map +0 -1
- package/lib/garbageCollection.js +0 -989
- package/lib/garbageCollection.js.map +0 -1
- package/lib/index.d.ts +0 -14
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -13
- package/lib/index.js.map +0 -1
- package/lib/opTelemetry.d.ts +0 -22
- package/lib/opTelemetry.d.ts.map +0 -1
- package/lib/opTelemetry.js +0 -56
- package/lib/opTelemetry.js.map +0 -1
- package/lib/orderedClientElection.d.ts.map +0 -1
- package/lib/orderedClientElection.js.map +0 -1
- package/lib/packageVersion.d.ts.map +0 -1
- package/lib/packageVersion.js.map +0 -1
- package/lib/pendingStateManager.d.ts.map +0 -1
- package/lib/pendingStateManager.js +0 -339
- package/lib/pendingStateManager.js.map +0 -1
- package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/lib/runWhileConnectedCoordinator.js.map +0 -1
- package/lib/runningSummarizer.d.ts +0 -93
- package/lib/runningSummarizer.d.ts.map +0 -1
- package/lib/runningSummarizer.js +0 -380
- package/lib/runningSummarizer.js.map +0 -1
- package/lib/serializedSnapshotStorage.d.ts +0 -58
- package/lib/serializedSnapshotStorage.d.ts.map +0 -1
- package/lib/serializedSnapshotStorage.js +0 -104
- package/lib/serializedSnapshotStorage.js.map +0 -1
- package/lib/summarizer.d.ts.map +0 -1
- package/lib/summarizer.js +0 -342
- package/lib/summarizer.js.map +0 -1
- package/lib/summarizerClientElection.d.ts.map +0 -1
- package/lib/summarizerClientElection.js.map +0 -1
- package/lib/summarizerHandle.d.ts +0 -12
- package/lib/summarizerHandle.d.ts.map +0 -1
- package/lib/summarizerHandle.js +0 -18
- package/lib/summarizerHandle.js.map +0 -1
- package/lib/summarizerHeuristics.d.ts.map +0 -1
- package/lib/summarizerHeuristics.js +0 -79
- package/lib/summarizerHeuristics.js.map +0 -1
- package/lib/summarizerTypes.d.ts.map +0 -1
- package/lib/summarizerTypes.js +0 -9
- package/lib/summarizerTypes.js.map +0 -1
- package/lib/summaryCollection.d.ts.map +0 -1
- package/lib/summaryCollection.js.map +0 -1
- package/lib/summaryFormat.d.ts.map +0 -1
- package/lib/summaryFormat.js.map +0 -1
- package/lib/summaryGenerator.d.ts +0 -85
- package/lib/summaryGenerator.d.ts.map +0 -1
- package/lib/summaryGenerator.js.map +0 -1
- package/lib/summaryManager.d.ts.map +0 -1
- package/lib/summaryManager.js.map +0 -1
- package/lib/throttler.d.ts.map +0 -1
- package/lib/throttler.js.map +0 -1
- package/src/garbageCollection.ts +0 -1434
- package/src/opTelemetry.ts +0 -71
- package/src/orderedClientElection.ts +0 -511
- package/src/runWhileConnectedCoordinator.ts +0 -106
- package/src/runningSummarizer.ts +0 -550
- package/src/serializedSnapshotStorage.ts +0 -146
- package/src/summarizer.ts +0 -438
- package/src/summarizerClientElection.ts +0 -161
- package/src/summarizerHandle.ts +0 -21
- package/src/summarizerHeuristics.ts +0 -108
- package/src/summarizerTypes.ts +0 -462
- package/src/summaryCollection.ts +0 -406
- package/src/summaryFormat.ts +0 -239
- package/src/summaryGenerator.ts +0 -427
- package/src/summaryManager.ts +0 -368
- package/tsconfig.esnext.json +0 -7
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Configs and feature gates for solving the 1MB limit.
|
|
2
|
+
|
|
3
|
+
## Table of contents
|
|
4
|
+
|
|
5
|
+
- [Introduction](#introduction)
|
|
6
|
+
- [How batching works](#how-batching-works)
|
|
7
|
+
- [Compression](#compression)
|
|
8
|
+
- [Grouped batching](#grouped-batching)
|
|
9
|
+
- [Risks](#risks)
|
|
10
|
+
- [Chunking for compression](#chunking-for-compression)
|
|
11
|
+
- [Disabling in case of emergency](#disabling-in-case-of-emergency)
|
|
12
|
+
- [Example configs](#example-configs)
|
|
13
|
+
- [Note about performance and latency](#note-about-performance-and-latency)
|
|
14
|
+
- [How it works](#how-it-works)
|
|
15
|
+
- [How grouped batching works](#how-grouped-batching-works)
|
|
16
|
+
|
|
17
|
+
## Introduction
|
|
18
|
+
|
|
19
|
+
There is a current limitation regarding the size of the payload a Fluid client can send and receive. [The limit is 1MB per payload](https://github.com/microsoft/FluidFramework/issues/9023) and it is currently enforced explicitly with the `BatchTooLarge` error which closes the container.
|
|
20
|
+
|
|
21
|
+
There are two features which can be used to work around this size limit, batch compression and compressed batch chunking. This document describes how to enable/disable them, along with a brief description of how they work. The features are enabled by default.
|
|
22
|
+
|
|
23
|
+
By default, the runtime is configured with a max batch size of `716800` bytes, which is lower than the 1MB limit. The reason for the lower value is to account for possible overhead from the op envelope and metadata.
|
|
24
|
+
|
|
25
|
+
### How batching works
|
|
26
|
+
|
|
27
|
+
Batching in the context of Fluid ops is a way in which the framework accumulates and applies ops. A batch is a group of ops accumulated within a single JS turn, which will be broadcasted in the same order to all the other connected clients and applied synchronously. Additional logic and validation ensure that batches are never interleaved, nested or interrupted and they are processed in isolation without interleaving of ops from other clients.
|
|
28
|
+
|
|
29
|
+
The way batches are formed is governed by the `FlushMode` setting of the `ContainerRuntimeOptions` and it is immutable for the entire lifetime of the runtime and subsequently the container.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
export enum FlushMode {
|
|
33
|
+
/**
|
|
34
|
+
* In Immediate flush mode the runtime will immediately send all operations to the driver layer.
|
|
35
|
+
*/
|
|
36
|
+
Immediate,
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
40
|
+
* batch at the end of the turn. The flush call on the runtime can be used to force send the current batch.
|
|
41
|
+
*/
|
|
42
|
+
TurnBased,
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
What this means is that `FlushMode.Immediate` will send each op in its own payload to the server, while `FlushMode.TurnBased` will accumulate all ops in a single JS turn and send them together in the same payload. Technically, `FlushMode.Immediate` can be simulated with `FlushMode.TurnBased` by interrupting the JS turn after producing only one op (for example by pausing the execution to wait on a promise). Therefore, for all intents and purposes, `FlushMode.Immediate` enables all batches to have only one op.
|
|
47
|
+
|
|
48
|
+
**By default, Fluid uses `FlushMode.TurnBased`** as:
|
|
49
|
+
|
|
50
|
+
- it is more efficient from an I/O perspective (batching ops overall decrease the number of payloads sent to the server)
|
|
51
|
+
- reduces concurrency related bugs, as it ensures that all ops generated within the same JS turn are also applied by all other clients within a single JS turn. Clients using the same pattern can safely assume ops will be applied exactly as they are observed locally. The alternative would be for ops to be both produced and applied with interruptions (which may involve processing input or rendering), invalidating the state based off which the changes were produced.
|
|
52
|
+
|
|
53
|
+
As `FlushMode.TurnBased` accumulates ops, it is the most vulnerable to run into the 1MB socket limit.
|
|
54
|
+
|
|
55
|
+
## Compression
|
|
56
|
+
|
|
57
|
+
**Compression targets payloads which exceed the max batch size and it is enabled by default.**. The `IContainerRuntimeOptions.compressionOptions` property, of type `ICompressionRuntimeOptions` is the configuration governing how compression works.
|
|
58
|
+
|
|
59
|
+
`ICompressionRuntimeOptions` has two properties:
|
|
60
|
+
|
|
61
|
+
- `minimumBatchSizeInBytes` – the minimum size of the batch for which compression should kick in. If the payload is too small, compression may not yield too many benefits. To target the original 1MB issue, a good value here would be to match the default maxBatchSizeInBytes (972800), however, experimentally, a good lower value could be at around 614400 bytes. Setting this value to `Number.POSITIVE_INFINITY` will disable compression.
|
|
62
|
+
- `compressionAlgorithm` – currently, only `lz4` is supported.
|
|
63
|
+
|
|
64
|
+
Compression is relevant for both `FlushMode.TurnBased` and `FlushMode.Immediate` as it only targets the contents of the ops and not the number of ops in a batch. Compression is opaque to the server and implementations of the Fluid protocol do not need to alter their behavior to support this client feature.
|
|
65
|
+
|
|
66
|
+
## Grouped batching
|
|
67
|
+
|
|
68
|
+
**Note: This feature is currently considered experimental and is not ready for production usage.**
|
|
69
|
+
|
|
70
|
+
The `IContainerRuntimeOptions.enableGroupedBatching` option has been added to the container runtime layer and is **off by default**. This option will group all batch messages under a new "grouped" message to be sent to the service. Upon receiving this new "grouped" message, the batch messages will be extracted and given the sequence number of the parent "grouped" message.
|
|
71
|
+
|
|
72
|
+
The purpose for enabling grouped batching on top of compression is that regular compression won't include the empty messages in the chunks. Thus, if we have batches with many messages (i.e. more than 4k), we will go over the batch size limit just on empty op envelopes alone.
|
|
73
|
+
|
|
74
|
+
See [below](#how-grouped-batching-works) for an example.
|
|
75
|
+
|
|
76
|
+
### Risks
|
|
77
|
+
|
|
78
|
+
This option is experimental and should not be enabled yet in production. This option should **ONLY** be enabled after observing that 99.9% of your application sessions contains these changes (runtime version "2.0.0-internal.4.1.0" or later). Containers created with this option may not open in future versions of the framework.
|
|
79
|
+
|
|
80
|
+
This option will change a couple of expectations around message structure and runtime layer expectations. Only enable this option after testing
|
|
81
|
+
and verifying that the following expectation changes won't have any effects:
|
|
82
|
+
|
|
83
|
+
- batch messages observed at the runtime layer will not match messages seen at the loader layer (i.e. grouped form at loader layer, ungrouped form at runtime layer)
|
|
84
|
+
- messages within the same batch will have the same sequence number
|
|
85
|
+
- client sequence numbers on batch messages can only be used to order messages with the same sequenceNumber
|
|
86
|
+
- requires all ops to be processed by runtime layer (version "2.0.0-internal.1.2.0" or later https://github.com/microsoft/FluidFramework/pull/11832)
|
|
87
|
+
|
|
88
|
+
Grouped batching may become problematic for batches which contain reentrant ops. This is the case when changes are made to a DDS inside a DDS 'onChanged' event handler. This means that the reentrant op will have a different reference sequence number than the rest of the ops in the batch, resulting in a different view of the state of the data model.
|
|
89
|
+
|
|
90
|
+
Therefore, when grouped batching is enabled, all batches with reentrant ops are rebased to the current reference sequence number and resubmitted to the data stores so that all ops are in agreement about the state of the data model and ensure eventual consistency.
|
|
91
|
+
|
|
92
|
+
### How to enable
|
|
93
|
+
|
|
94
|
+
**This feature is disabled by default, currently considered experimental and not ready for production usage.**
|
|
95
|
+
|
|
96
|
+
If all prerequisites in the previous section are met, enabling the feature can be done via the `IContainerRuntimeOptions` as following:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
const runtimeOptions: IContainerRuntimeOptions = {
|
|
100
|
+
(...)
|
|
101
|
+
enableGroupedBatching: true,
|
|
102
|
+
(...)
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
In case of emergency grouped batching can be disabled at runtime, using feature gates. If `"Fluid.ContainerRuntime.DisableGroupedBatching"` is set to `true`, it will disable grouped batching if enabled from `IContainerRuntimeOptions` in the code.
|
|
107
|
+
|
|
108
|
+
Grouped batching is only relevant for `FlushMode.TurnBased` as it only targets the number of ops in a batch. Grouped batching is opaque to the server and implementations of the Fluid protocol do not need to alter their behavior to support this client feature.
|
|
109
|
+
|
|
110
|
+
## Chunking for compression
|
|
111
|
+
|
|
112
|
+
**Op chunking for compression targets payloads which exceed the max batch size after compression.** So, only payloads which are already compressed. By default, the feature is enabled.
|
|
113
|
+
|
|
114
|
+
The `IContainerRuntimeOptions.chunkSizeInBytes` property is the only configuration for chunking and it represents the size of the chunked ops, when chunking is necessary. When chunking is performed, the large op is split into smaller ops (chunks). This config represents both the size of the chunks and the threshold for the feature to activate. The value enables a trade-off between large chunks / few ops and small chunks / many ops. A good value for this would be at around 204800. Setting this value to `Number.POSITIVE_INFINITY` will disable chunking.
|
|
115
|
+
|
|
116
|
+
This config would govern chunking compressed batches only. We will not be enabling chunking across all types of ops/batches but **only when compression is enabled and when the batch is compressed**, and its payload size is more than `IContainerRuntimeOptions.chunkSizeInBytes`.
|
|
117
|
+
|
|
118
|
+
Chunking is relevant for both `FlushMode.TurnBased` and `FlushMode.Immediate` as it only targets the contents of the ops and not the number of ops in a batch. Chunking is opaque to the server and implementations of the Fluid protocol do not need to alter their behavior to support this client feature.
|
|
119
|
+
|
|
120
|
+
## Disabling in case of emergency
|
|
121
|
+
|
|
122
|
+
If the features are enabled using the configs, they can be disabled at runtime via feature gates as following:
|
|
123
|
+
|
|
124
|
+
- `Fluid.ContainerRuntime.CompressionDisabled` - if set to true, will disable compression (this has a side effect of also disabling chunking, as chunking is invoked only for compressed payloads).
|
|
125
|
+
- `Fluid.ContainerRuntime.DisableGroupedBatching` - if set to true, will disable grouped batching.
|
|
126
|
+
- `Fluid.ContainerRuntime.CompressionChunkingDisabled` - if set to true, will disable chunking for compression.
|
|
127
|
+
|
|
128
|
+
## Example configs
|
|
129
|
+
|
|
130
|
+
By default, the runtime is configured with the following values related to compression and chunking:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
const runtimeOptions: IContainerRuntimeOptions = {
|
|
134
|
+
compressionOptions: {
|
|
135
|
+
minimumBatchSizeInBytes: 614400,
|
|
136
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
137
|
+
},
|
|
138
|
+
chunkSizeInBytes: 204800,
|
|
139
|
+
maxBatchSizeInBytes: 716800,
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
To enable grouped batching, use the following property:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
const runtimeOptions: IContainerRuntimeOptions = {
|
|
147
|
+
enableGroupedBatching: true,
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Note about performance and latency
|
|
152
|
+
|
|
153
|
+
In terms of performance and impact on latency, the results greatly depend on payload size, payload structure, network speed and CPU speed. Therefore, customers must perform the required measurements and adjust the settings according to their scenarios.
|
|
154
|
+
|
|
155
|
+
In general, compression offers a trade-off between higher compute costs, lower bandwidth consumption and lower storage requirements, while chunking slightly increases latency due to the overhead of splitting an op, sending the chunks and reconstructing them on each client. Grouped batching heavily decreases the number of ops observed by the server and slightly decreases the bandwidth requirements as it merges all the ops in a batch into a single op and also eliminates the op envelope overhead.
|
|
156
|
+
|
|
157
|
+
## How it works
|
|
158
|
+
|
|
159
|
+
Compression currently works as a runtime layer over the regular op sending/receiving pipeline.
|
|
160
|
+
|
|
161
|
+
If we have a batch with a size larger than the configured minimum required for compression (in the example let’s say it’s 850 bytes), as following:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
+-----------+-----------+-----------+-----------+
|
|
165
|
+
| Op 1 | Op 2 | Op 3 | Op 4 |
|
|
166
|
+
| SeqNum: 1 | SeqNum: 2 | SeqNum: 3 | SeqNum: 4 |
|
|
167
|
+
| Size: 100 | Size: 150 | Size: 200 | Size: 400 |
|
|
168
|
+
+-----------+-----------+-----------+-----------+
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The total size of the batch is 850 bytes. The client which needs to send the batch would compress the batch to a smaller size (200 bytes) and will send a new batch like the following:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
+--------------------+-----------+-----------+-----------+
|
|
175
|
+
| Op 1 | Op 2 | Op 3 | Op 4 |
|
|
176
|
+
| SeqNum: 1 | SeqNum: 2 | SeqNum: 3 | SeqNum: 4 |
|
|
177
|
+
| Size: 200 | Size: 0 | Size: 0 | Size: 0 |
|
|
178
|
+
| Compression: 'lz4' | | | |
|
|
179
|
+
+--------------------+-----------+-----------+-----------+
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The first op in the batch is the only one with content (which is opaque due to it being compressed), the rest of the ops serve only to reserve the sequence numbers so that the state machine which rebuilds the original batch on the receiving client can reconstruct the original batch.
|
|
183
|
+
|
|
184
|
+
When the batch is received by a client, it will detect the first op as being compressed, it will decompress it and store it in memory. For each empty op subsequently received, it will fetch the uncompressed content from memory and rebuild the original ops. The original ops are then processed by the runtime and applied accordingly.
|
|
185
|
+
So, compression virtualizes the batch.
|
|
186
|
+
|
|
187
|
+
After compression, the first op in the batch can exceed 1MB, therefore it would still be rejected. In this case, another layer of virtualization is added after compression (and before decompression, symmetrically on the receiving end).
|
|
188
|
+
|
|
189
|
+
The first op in the compressed batch can be chunked into smaller ops which can be sent outside the original batch. However, to conveniently maintain the batch semantics, the last chunk (the chunk which triggers rebuilding the original op) is the first op in the new batch.
|
|
190
|
+
|
|
191
|
+
To illustrate, let’s take the large batch below:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
+--------------------+-----------+-----------+-----------+
|
|
195
|
+
| Op 1 | Op 2 | Op 3 | Op 4 |
|
|
196
|
+
| SeqNum: 1 | SeqNum: 2 | SeqNum: 3 | SeqNum: 4 |
|
|
197
|
+
| Size: 900 | Size: 0 | Size: 0 | Size: 0 |
|
|
198
|
+
| Compression: 'lz4' | | | |
|
|
199
|
+
+--------------------+-----------+-----------+-----------+
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
This will produce the following batches:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
+-----------+
|
|
206
|
+
| Chunk 1/3 |
|
|
207
|
+
| SeqNum: 1 |
|
|
208
|
+
| Size: 300 |
|
|
209
|
+
+-----------+
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
+-----------+
|
|
215
|
+
| Chunk 2/3 |
|
|
216
|
+
| SeqNum: 2 |
|
|
217
|
+
| Size: 300 |
|
|
218
|
+
+-----------+
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
+-----------+-----------+-----------+-----------+
|
|
224
|
+
| Chunk 3/3 | Op 2 | Op 3 | Op 4 |
|
|
225
|
+
| SeqNum: 3 | SeqNum: 4 | SeqNum: 5 | SeqNum: 6 |
|
|
226
|
+
| Size: 300 | Size: 0 | Size: 0 | Size: 0 |
|
|
227
|
+
+-----------+-----------+-----------+-----------+
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The first 2 chunks are sent in their own batches, while the last chunk is the first op in the last batch which contains the ops reserving the required sequence numbers.
|
|
231
|
+
|
|
232
|
+
Notice that the sequence numbers don’t matter here, as all ops will be based off the same reference sequence number, so the sequence number will be recalculated for all, without additional work.
|
|
233
|
+
|
|
234
|
+
Additionally, as compression preserves the original uncompressed batch layout in terms of the number of ops by using empty ops to reserve the sequence numbers, this ensures that the clients will always receive the exact count of ops to rebuild the uncompressed batch sequentially.
|
|
235
|
+
|
|
236
|
+
On the receiving end, the client will accumulate chunks 1 and 2 and keep them in memory. When chunk 3 is received, the original large, decompressed op will be rebuilt, and the runtime will then process the batch as if it is a compressed batch.
|
|
237
|
+
|
|
238
|
+
## How grouped batching works
|
|
239
|
+
|
|
240
|
+
Given the following baseline batch:
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
+---------------+---------------+---------------+---------------+---------------+
|
|
244
|
+
| Op 1 | Op 2 | Op 3 | Op 4 | Op 5 |
|
|
245
|
+
| Contents: "a" | Contents: "b" | Contents: "c" | Contents: "d" | Contents: "e" |
|
|
246
|
+
+---------------+---------------+---------------+---------------+---------------+
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Grouped batch:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
+---------------------------------------------------------------------------------------------------------------------+
|
|
253
|
+
| Op 1 Contents: +----------------+---------------+---------------+---------------+---------------+ |
|
|
254
|
+
| Type: "groupedBatch" | Op 1 | Op 2 | Op 3 | Op 4 | Op 5 | |
|
|
255
|
+
| | Contents: "a" | Contents: "b" | Contents: "c" | Contents: "d" | Contents: "e" | |
|
|
256
|
+
| +----------------+---------------+---------------+---------------+---------------+ |
|
|
257
|
+
+---------------------------------------------------------------------------------------------------------------------+
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Compressed batch:
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
+-------------------------------------------------------------------------------------------------------------------------+
|
|
264
|
+
| Op 1 Contents: +------------------------------------------------------------------------------------+ |
|
|
265
|
+
| Compression: 'lz4' | Type: "groupedBatch" | |
|
|
266
|
+
| | +----------------+---------------+---------------+---------------+---------------+ | |
|
|
267
|
+
| | | Op 1 | Op 2 | Op 3 | Op 4 | Op 5 | | |
|
|
268
|
+
| | | Contents: "a" | Contents: "b" | Contents: "c" | Contents: "d" | Contents: "e" | | |
|
|
269
|
+
| | +----------------+---------------+---------------+---------------+---------------+ | |
|
|
270
|
+
| +------------------------------------------------------------------------------------+ |
|
|
271
|
+
+-------------------------------------------------------------------------------------------------------------------------+
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Can produce the following chunks:
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
+------------------------------------------------+
|
|
278
|
+
| Chunk 1/2 Contents: +---------------------+ |
|
|
279
|
+
| | +-----------------+ | |
|
|
280
|
+
| | | Contents: "abc" | | |
|
|
281
|
+
| | +-----------------+ | |
|
|
282
|
+
| +---------------------+ |
|
|
283
|
+
+------------------------------------------------+
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
+-----------------------------------------------+
|
|
288
|
+
| Chunk 2/2 Contents: +--------------------+ |
|
|
289
|
+
| | +----------------+ | |
|
|
290
|
+
| | | Contents: "de" | | |
|
|
291
|
+
| | +----------------+ | |
|
|
292
|
+
| +--------------------+ |
|
|
293
|
+
+-----------------------------------------------+
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
- Send to service
|
|
297
|
+
- Service acks ops sent
|
|
298
|
+
- Receive chunks from service
|
|
299
|
+
- Recompile to the compression step
|
|
300
|
+
|
|
301
|
+
Decompressed batch:
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
+---------------------------------------------------------------------------------------------------------------------+
|
|
305
|
+
| Op 1 Contents: +----------------+---------------+---------------+---------------+---------------+ |
|
|
306
|
+
| SeqNum: 2 | Op 1 | Op 2 | Op 3 | Op 4 | Op 5 | |
|
|
307
|
+
| Type: "groupedBatch" | Contents: "a" | Contents: "b" | Contents: "c" | Contents: "d" | Contents: "e" | |
|
|
308
|
+
| +----------------+---------------+---------------+---------------+---------------+ |
|
|
309
|
+
+---------------------------------------------------------------------------------------------------------------------+
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Ungrouped batch:
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
+-----------------+-----------------+-----------------+-----------------+-----------------+
|
|
316
|
+
| Op 1 | Op 2 | Op 3 | Op 4 | Op 5 |
|
|
317
|
+
| Contents: "a" | Contents: "b" | Contents: "c" | Contents: "d" | Contents: "e" |
|
|
318
|
+
| SeqNum: 2 | SeqNum: 2 | SeqNum: 2 | SeqNum: 2 | SeqNum: 2 |
|
|
319
|
+
| ClientSeqNum: 1 | ClientSeqNum: 2 | ClientSeqNum: 3 | ClientSeqNum: 4 | ClientSeqNum: 5 |
|
|
320
|
+
+-----------------+-----------------+-----------------+-----------------+-----------------+
|
|
321
|
+
```
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ICompressionRuntimeOptions } from "../containerRuntime";
|
|
7
|
+
import { BatchMessage, IBatch, IBatchCheckpoint } from "./definitions";
|
|
8
|
+
|
|
9
|
+
export interface IBatchManagerOptions {
|
|
10
|
+
readonly hardLimit: number;
|
|
11
|
+
readonly softLimit?: number;
|
|
12
|
+
readonly compressionOptions?: ICompressionRuntimeOptions;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface BatchSequenceNumbers {
|
|
16
|
+
referenceSequenceNumber?: number;
|
|
17
|
+
clientSequenceNumber?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Estimated size of the stringification overhead for an op accumulated
|
|
22
|
+
* from runtime to loader to the service.
|
|
23
|
+
*/
|
|
24
|
+
const opOverhead = 200;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Helper class that manages partial batch & rollback.
|
|
28
|
+
*/
|
|
29
|
+
export class BatchManager {
|
|
30
|
+
private pendingBatch: BatchMessage[] = [];
|
|
31
|
+
private batchContentSize = 0;
|
|
32
|
+
private hasReentrantOps = false;
|
|
33
|
+
|
|
34
|
+
public get length() {
|
|
35
|
+
return this.pendingBatch.length;
|
|
36
|
+
}
|
|
37
|
+
public get contentSizeInBytes() {
|
|
38
|
+
return this.batchContentSize;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public get sequenceNumbers(): BatchSequenceNumbers {
|
|
42
|
+
return {
|
|
43
|
+
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
44
|
+
clientSequenceNumber: this.clientSequenceNumber,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private get referenceSequenceNumber(): number | undefined {
|
|
49
|
+
return this.pendingBatch.length === 0
|
|
50
|
+
? undefined
|
|
51
|
+
: this.pendingBatch[this.pendingBatch.length - 1].referenceSequenceNumber;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private clientSequenceNumber: number | undefined;
|
|
55
|
+
|
|
56
|
+
constructor(public readonly options: IBatchManagerOptions) {}
|
|
57
|
+
|
|
58
|
+
public push(
|
|
59
|
+
message: BatchMessage,
|
|
60
|
+
reentrant: boolean,
|
|
61
|
+
currentClientSequenceNumber?: number,
|
|
62
|
+
): boolean {
|
|
63
|
+
const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
|
|
64
|
+
const opCount = this.pendingBatch.length;
|
|
65
|
+
this.hasReentrantOps = this.hasReentrantOps || reentrant;
|
|
66
|
+
|
|
67
|
+
// Attempt to estimate batch size, aka socket message size.
|
|
68
|
+
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
69
|
+
// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
|
|
70
|
+
// Not taking it into account, as compression work should help there - compressed payload will be
|
|
71
|
+
// initially stored as base64, and that requires only 2 extra escape characters.
|
|
72
|
+
const socketMessageSize = contentSize + opOverhead * opCount;
|
|
73
|
+
|
|
74
|
+
// If we were provided soft limit, check for exceeding it.
|
|
75
|
+
// But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)
|
|
76
|
+
// and start over. That's not an option if we have no ops.
|
|
77
|
+
// If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.
|
|
78
|
+
// Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.
|
|
79
|
+
if (
|
|
80
|
+
this.options.softLimit !== undefined &&
|
|
81
|
+
this.length > 0 &&
|
|
82
|
+
socketMessageSize >= this.options.softLimit
|
|
83
|
+
) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (socketMessageSize >= this.options.hardLimit) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (this.pendingBatch.length === 0) {
|
|
92
|
+
this.clientSequenceNumber = currentClientSequenceNumber;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.batchContentSize = contentSize;
|
|
96
|
+
this.pendingBatch.push(message);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public get empty() {
|
|
101
|
+
return this.pendingBatch.length === 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public popBatch(): IBatch {
|
|
105
|
+
const batch: IBatch = {
|
|
106
|
+
content: this.pendingBatch,
|
|
107
|
+
contentSizeInBytes: this.batchContentSize,
|
|
108
|
+
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
109
|
+
hasReentrantOps: this.hasReentrantOps,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
this.pendingBatch = [];
|
|
113
|
+
this.batchContentSize = 0;
|
|
114
|
+
this.clientSequenceNumber = undefined;
|
|
115
|
+
this.hasReentrantOps = false;
|
|
116
|
+
|
|
117
|
+
return addBatchMetadata(batch);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Capture the pending state at this point
|
|
122
|
+
*/
|
|
123
|
+
public checkpoint(): IBatchCheckpoint {
|
|
124
|
+
const startPoint = this.pendingBatch.length;
|
|
125
|
+
return {
|
|
126
|
+
rollback: (process: (message: BatchMessage) => void) => {
|
|
127
|
+
for (let i = this.pendingBatch.length; i > startPoint; ) {
|
|
128
|
+
i--;
|
|
129
|
+
const message = this.pendingBatch[i];
|
|
130
|
+
this.batchContentSize -= message.contents?.length ?? 0;
|
|
131
|
+
process(message);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
this.pendingBatch.length = startPoint;
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const addBatchMetadata = (batch: IBatch): IBatch => {
|
|
141
|
+
if (batch.content.length > 1) {
|
|
142
|
+
batch.content[0].metadata = {
|
|
143
|
+
...batch.content[0].metadata,
|
|
144
|
+
batch: true,
|
|
145
|
+
};
|
|
146
|
+
batch.content[batch.content.length - 1].metadata = {
|
|
147
|
+
...batch.content[batch.content.length - 1].metadata,
|
|
148
|
+
batch: false,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return batch;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Estimates the real size in bytes on the socket for a given batch. It assumes that
|
|
157
|
+
* the envelope size (and the size of an empty op) is 200 bytes, taking into account
|
|
158
|
+
* extra overhead from stringification.
|
|
159
|
+
*
|
|
160
|
+
* @param batch - the batch to inspect
|
|
161
|
+
* @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
|
|
162
|
+
*/
|
|
163
|
+
export const estimateSocketSize = (batch: IBatch): number => {
|
|
164
|
+
return batch.contentSizeInBytes + opOverhead * batch.content.length;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const sequenceNumbersMatch = (
|
|
168
|
+
seqNums: BatchSequenceNumbers,
|
|
169
|
+
otherSeqNums: BatchSequenceNumbers,
|
|
170
|
+
): boolean => {
|
|
171
|
+
return (
|
|
172
|
+
(seqNums.referenceSequenceNumber === undefined ||
|
|
173
|
+
otherSeqNums.referenceSequenceNumber === undefined ||
|
|
174
|
+
seqNums.referenceSequenceNumber === otherSeqNums.referenceSequenceNumber) &&
|
|
175
|
+
(seqNums.clientSequenceNumber === undefined ||
|
|
176
|
+
otherSeqNums.clientSequenceNumber === undefined ||
|
|
177
|
+
seqNums.clientSequenceNumber === otherSeqNums.clientSequenceNumber)
|
|
178
|
+
);
|
|
179
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IBatchMessage } from "@fluidframework/container-definitions";
|
|
7
|
+
import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
|
|
8
|
+
import { CompressionAlgorithms } from "../containerRuntime";
|
|
9
|
+
import { ContainerMessageType } from "../messageTypes";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Batch message type used internally by the runtime
|
|
13
|
+
*/
|
|
14
|
+
export type BatchMessage = IBatchMessage & {
|
|
15
|
+
localOpMetadata: unknown;
|
|
16
|
+
type: ContainerMessageType;
|
|
17
|
+
referenceSequenceNumber: number;
|
|
18
|
+
compression?: CompressionAlgorithms;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Batch interface used internally by the runtime.
|
|
23
|
+
*/
|
|
24
|
+
export interface IBatch {
|
|
25
|
+
/**
|
|
26
|
+
* Sum of the in-memory content sizes of all messages in the batch.
|
|
27
|
+
* If the batch is compressed, this number reflects the post-compression size.
|
|
28
|
+
*/
|
|
29
|
+
readonly contentSizeInBytes: number;
|
|
30
|
+
/**
|
|
31
|
+
* All the messages in the batch
|
|
32
|
+
*/
|
|
33
|
+
readonly content: BatchMessage[];
|
|
34
|
+
/**
|
|
35
|
+
* The reference sequence number for the batch
|
|
36
|
+
*/
|
|
37
|
+
readonly referenceSequenceNumber: number | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Wether or not the batch contains at least one op which was produced as the result
|
|
40
|
+
* of processing another op. This means that the batch must be rebased before
|
|
41
|
+
* submitted, to ensure that all ops have the same reference sequence numbers and a
|
|
42
|
+
* consistent view of the data model. This happens when the op is created within a
|
|
43
|
+
* 'changed' event handler of a DDS and will have a different reference sequence number
|
|
44
|
+
* than the rest of the ops in the batch, meaning that it has a different view of the
|
|
45
|
+
* state of the data model, therefore all ops must be resubmitted and rebased to the current
|
|
46
|
+
* reference sequence number to be in agreement about the data model state.
|
|
47
|
+
*/
|
|
48
|
+
readonly hasReentrantOps?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface IBatchCheckpoint {
|
|
52
|
+
rollback: (action: (message: BatchMessage) => void) => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export interface IChunkedOp {
|
|
59
|
+
chunkId: number;
|
|
60
|
+
totalChunks: number;
|
|
61
|
+
contents: string;
|
|
62
|
+
originalType: MessageType | ContainerMessageType;
|
|
63
|
+
originalMetadata?: Record<string, unknown>;
|
|
64
|
+
originalCompression?: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The state of remote message processing:
|
|
69
|
+
* `Processed` - the message can be considered processed
|
|
70
|
+
* `Skipped` - the message was ignored by the processor
|
|
71
|
+
* `Accepted` - the message was processed partially. Eventually, a message
|
|
72
|
+
* will make the processor return `Processed`.
|
|
73
|
+
*/
|
|
74
|
+
export type ProcessingState = "Processed" | "Skipped" | "Accepted";
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Return type for functions which process remote messages
|
|
78
|
+
*/
|
|
79
|
+
export interface IMessageProcessingResult {
|
|
80
|
+
/**
|
|
81
|
+
* A shallow copy of the input message if processing happened, or
|
|
82
|
+
* the original message otherwise
|
|
83
|
+
*/
|
|
84
|
+
readonly message: ISequencedDocumentMessage;
|
|
85
|
+
/**
|
|
86
|
+
* Processing result of the input message.
|
|
87
|
+
*/
|
|
88
|
+
readonly state: ProcessingState;
|
|
89
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { BatchManager, estimateSocketSize, BatchSequenceNumbers } from "./batchManager";
|
|
7
|
+
export {
|
|
8
|
+
BatchMessage,
|
|
9
|
+
IBatch,
|
|
10
|
+
IBatchCheckpoint,
|
|
11
|
+
IChunkedOp,
|
|
12
|
+
IMessageProcessingResult,
|
|
13
|
+
} from "./definitions";
|
|
14
|
+
export { Outbox, getLongStack } from "./outbox";
|
|
15
|
+
export { OpCompressor } from "./opCompressor";
|
|
16
|
+
export { OpDecompressor } from "./opDecompressor";
|
|
17
|
+
export { OpSplitter, splitOp } from "./opSplitter";
|
|
18
|
+
export { RemoteMessageProcessor, unpackRuntimeMessage } from "./remoteMessageProcessor";
|
|
19
|
+
export { OpGroupingManager } from "./opGroupingManager";
|