@fluidframework/container-runtime 2.0.0-dev.4.4.0.162574 → 2.0.0-dev.5.3.2.178189
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +69 -0
- package/dist/batchTracker.d.ts +4 -4
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -2
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +5 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +53 -24
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +2 -2
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +8 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +19 -7
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +98 -22
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +2 -2
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +3 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +5 -5
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +2 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +2 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStores.d.ts +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +2 -1
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaScheduler.d.ts +2 -2
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +2 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +4 -3
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +3 -4
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +5 -5
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/id-compressor/idCompressor.d.ts +2 -2
- package/dist/id-compressor/idCompressor.d.ts.map +1 -1
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/id-compressor/uuidUtilities.d.ts +0 -2
- package/dist/id-compressor/uuidUtilities.d.ts.map +1 -1
- package/dist/id-compressor/uuidUtilities.js +1 -3
- package/dist/id-compressor/uuidUtilities.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +18 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +7 -0
- package/dist/metadata.js.map +1 -0
- package/dist/opLifecycle/batchManager.d.ts +2 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +5 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +13 -2
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +2 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +3 -6
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +2 -2
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +14 -8
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +6 -11
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +2 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +5 -3
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +35 -4
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +135 -45
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +3 -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 +24 -15
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +67 -72
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +2 -2
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +8 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +2 -2
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +2 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +4 -3
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +3 -18
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +4 -3
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +5 -6
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -3
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +2 -3
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +3 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +2 -2
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/index.d.ts +1 -1
- package/dist/summary/summarizerNode/index.d.ts.map +1 -1
- package/dist/summary/summarizerNode/index.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +41 -14
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +91 -23
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +24 -4
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +23 -8
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +60 -23
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +16 -9
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +4 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +4 -0
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +1 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +2 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +14 -5
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +23 -9
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +4 -2
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/lib/batchTracker.d.ts +4 -4
- 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 +5 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +53 -24
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +2 -2
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +8 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +19 -7
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +101 -25
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +2 -2
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +3 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +5 -5
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +2 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +2 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStores.d.ts +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +2 -1
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaScheduler.d.ts +2 -2
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +2 -2
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +2 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +3 -4
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +5 -5
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +1 -1
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/id-compressor/idCompressor.d.ts +2 -2
- package/lib/id-compressor/idCompressor.d.ts.map +1 -1
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/id-compressor/uuidUtilities.d.ts +0 -2
- package/lib/id-compressor/uuidUtilities.d.ts.map +1 -1
- package/lib/id-compressor/uuidUtilities.js +1 -3
- package/lib/id-compressor/uuidUtilities.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/metadata.d.ts +18 -0
- package/lib/metadata.d.ts.map +1 -0
- package/lib/metadata.js +6 -0
- package/lib/metadata.js.map +1 -0
- package/lib/opLifecycle/batchManager.d.ts +2 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +5 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +13 -2
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +2 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +3 -6
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +2 -2
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +14 -8
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +6 -11
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +2 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +5 -3
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +35 -4
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +133 -44
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +3 -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 +24 -15
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +67 -72
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +2 -2
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +8 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +2 -2
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +4 -3
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +3 -18
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +4 -3
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +5 -6
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -3
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +2 -3
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +3 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +2 -2
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/index.d.ts +1 -1
- package/lib/summary/summarizerNode/index.d.ts.map +1 -1
- package/lib/summary/summarizerNode/index.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +41 -14
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +91 -23
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +24 -4
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +23 -8
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +59 -22
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +16 -9
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +4 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +4 -0
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +1 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +2 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +14 -5
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +21 -8
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +4 -2
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +25 -41
- package/src/batchTracker.ts +5 -6
- package/src/blobManager.ts +70 -29
- package/src/connectionTelemetry.ts +14 -6
- package/src/containerRuntime.ts +124 -38
- package/src/dataStore.ts +3 -4
- package/src/dataStoreContext.ts +12 -9
- package/src/dataStoreContexts.ts +6 -8
- package/src/dataStores.ts +8 -3
- package/src/deltaScheduler.ts +2 -3
- package/src/gc/garbageCollection.ts +7 -6
- package/src/gc/gcDefinitions.ts +3 -4
- package/src/gc/gcTelemetry.ts +9 -5
- package/src/id-compressor/idCompressor.ts +2 -2
- package/src/id-compressor/uuidUtilities.ts +1 -4
- package/src/index.ts +2 -0
- package/src/metadata.ts +19 -0
- package/src/opLifecycle/README.md +20 -0
- package/src/opLifecycle/batchManager.ts +9 -1
- package/src/opLifecycle/definitions.ts +13 -2
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opCompressor.ts +4 -8
- package/src/opLifecycle/opDecompressor.ts +43 -16
- package/src/opLifecycle/opGroupingManager.ts +19 -13
- package/src/opLifecycle/opSplitter.ts +7 -6
- package/src/opLifecycle/outbox.ts +172 -57
- package/src/opLifecycle/remoteMessageProcessor.ts +5 -1
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +113 -129
- package/src/scheduleManager.ts +18 -10
- package/src/summary/index.ts +3 -1
- package/src/summary/orderedClientElection.ts +7 -20
- package/src/summary/runningSummarizer.ts +11 -10
- package/src/summary/summarizer.ts +8 -8
- package/src/summary/summarizerClientElection.ts +3 -2
- package/src/summary/summarizerHeuristics.ts +2 -2
- package/src/summary/summarizerNode/index.ts +1 -0
- package/src/summary/summarizerNode/summarizerNode.ts +121 -38
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +27 -4
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +73 -27
- package/src/summary/summarizerTypes.ts +19 -14
- package/src/summary/summaryCollection.ts +10 -4
- package/src/summary/summaryFormat.ts +5 -1
- package/src/summary/summaryGenerator.ts +38 -11
- package/src/summary/summaryManager.ts +9 -9
package/src/gc/gcDefinitions.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
ITelemetryContext,
|
|
14
14
|
} from "@fluidframework/runtime-definitions";
|
|
15
15
|
import { ReadAndParseBlob } from "@fluidframework/runtime-utils";
|
|
16
|
-
import {
|
|
16
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
17
17
|
import {
|
|
18
18
|
IContainerRuntimeMetadata,
|
|
19
19
|
ICreateContainerMetadata,
|
|
@@ -211,7 +211,7 @@ export interface IGarbageCollector {
|
|
|
211
211
|
/** Run garbage collection and update the reference / used state of the system. */
|
|
212
212
|
collectGarbage(
|
|
213
213
|
options: {
|
|
214
|
-
logger?:
|
|
214
|
+
logger?: ITelemetryLoggerExt;
|
|
215
215
|
runSweep?: boolean;
|
|
216
216
|
fullGC?: boolean;
|
|
217
217
|
},
|
|
@@ -253,7 +253,7 @@ export interface IGarbageCollector {
|
|
|
253
253
|
export interface IGarbageCollectorCreateParams {
|
|
254
254
|
readonly runtime: IGarbageCollectionRuntime;
|
|
255
255
|
readonly gcOptions: IGCRuntimeOptions;
|
|
256
|
-
readonly baseLogger:
|
|
256
|
+
readonly baseLogger: ITelemetryLoggerExt;
|
|
257
257
|
readonly existing: boolean;
|
|
258
258
|
readonly metadata: IContainerRuntimeMetadata | undefined;
|
|
259
259
|
readonly createContainerMetadata: ICreateContainerMetadata;
|
|
@@ -263,7 +263,6 @@ export interface IGarbageCollectorCreateParams {
|
|
|
263
263
|
readonly getLastSummaryTimestampMs: () => number | undefined;
|
|
264
264
|
readonly readAndParseBlob: ReadAndParseBlob;
|
|
265
265
|
readonly activeConnection: () => boolean;
|
|
266
|
-
readonly getContainerDiagnosticId: () => string;
|
|
267
266
|
}
|
|
268
267
|
|
|
269
268
|
export interface IGCRuntimeOptions {
|
package/src/gc/gcTelemetry.ts
CHANGED
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ITelemetryGenericEvent
|
|
6
|
+
import { ITelemetryGenericEvent } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { IGarbageCollectionData } from "@fluidframework/runtime-definitions";
|
|
8
8
|
import { packagePathToTelemetryProperty } from "@fluidframework/runtime-utils";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
generateStack,
|
|
11
|
+
ITelemetryLoggerExt,
|
|
12
|
+
MonitoringContext,
|
|
13
|
+
} from "@fluidframework/telemetry-utils";
|
|
10
14
|
import { ICreateContainerMetadata } from "../summary";
|
|
11
15
|
import {
|
|
12
16
|
disableSweepLogKey,
|
|
@@ -243,7 +247,7 @@ export class GCTelemetryTracker {
|
|
|
243
247
|
currentGCData: IGarbageCollectionData,
|
|
244
248
|
previousGCData: IGarbageCollectionData,
|
|
245
249
|
explicitReferences: Map<string, string[]>,
|
|
246
|
-
logger:
|
|
250
|
+
logger: ITelemetryLoggerExt,
|
|
247
251
|
) {
|
|
248
252
|
for (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {
|
|
249
253
|
const previousRoutes = previousGCData.gcNodes[nodeId] ?? [];
|
|
@@ -284,7 +288,7 @@ export class GCTelemetryTracker {
|
|
|
284
288
|
* Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client
|
|
285
289
|
* so that the state of an unreferenced node is updated.
|
|
286
290
|
*/
|
|
287
|
-
public async logPendingEvents(logger:
|
|
291
|
+
public async logPendingEvents(logger: ITelemetryLoggerExt) {
|
|
288
292
|
// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at
|
|
289
293
|
// summary time they are then logged.
|
|
290
294
|
// Events generated:
|
|
@@ -333,7 +337,7 @@ export class GCTelemetryTracker {
|
|
|
333
337
|
* this will give us a view into how much deleted content a container has.
|
|
334
338
|
*/
|
|
335
339
|
public logSweepEvents(
|
|
336
|
-
logger:
|
|
340
|
+
logger: ITelemetryLoggerExt,
|
|
337
341
|
currentReferenceTimestampMs: number,
|
|
338
342
|
unreferencedNodesState: Map<string, UnreferencedStateTracker>,
|
|
339
343
|
completedGCRuns: number,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
9
9
|
import { assert } from "@fluidframework/common-utils";
|
|
10
10
|
import {
|
|
11
11
|
IIdCompressor,
|
|
@@ -311,7 +311,7 @@ export class IdCompressor implements IIdCompressorCore, IIdCompressor {
|
|
|
311
311
|
*/
|
|
312
312
|
public constructor(
|
|
313
313
|
public readonly localSessionId: SessionId,
|
|
314
|
-
private readonly logger?:
|
|
314
|
+
private readonly logger?: ITelemetryLoggerExt,
|
|
315
315
|
) {
|
|
316
316
|
this.localSession = this.createSession(localSessionId);
|
|
317
317
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert } from "@fluidframework/common-utils";
|
|
7
7
|
import { StableId, UuidString } from "@fluidframework/runtime-definitions";
|
|
8
|
-
import { v4
|
|
8
|
+
import { v4 } from "uuid";
|
|
9
9
|
|
|
10
10
|
const hexadecimalCharCodes = Array.from("09afAF").map((c) => c.charCodeAt(0)) as [
|
|
11
11
|
zero: number,
|
|
@@ -24,9 +24,6 @@ function isHexadecimalCharacter(charCode: number): boolean {
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** The null (lowest/all-zeros) UUID */
|
|
28
|
-
export const nilUuid = assertIsUuidString(NIL);
|
|
29
|
-
|
|
30
27
|
/**
|
|
31
28
|
* Asserts that the given string is a UUID
|
|
32
29
|
*/
|
package/src/index.ts
CHANGED
|
@@ -67,6 +67,8 @@ export {
|
|
|
67
67
|
OpActionEventListener,
|
|
68
68
|
OpActionEventName,
|
|
69
69
|
ICancellableSummarizerController,
|
|
70
|
+
SubmitSummaryFailureData,
|
|
71
|
+
SummaryStage,
|
|
70
72
|
} from "./summary";
|
|
71
73
|
export { IChunkedOp, unpackRuntimeMessage } from "./opLifecycle";
|
|
72
74
|
export { generateStableId, isStableId, assertIsStableId } from "./id-compressor";
|
package/src/metadata.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Batching makes assumptions about what might be on the metadata. This interface codifies those assumptions, but does not validate them.
|
|
8
|
+
*/
|
|
9
|
+
export interface IBatchMetadata {
|
|
10
|
+
batch?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Blob handling makes assumptions about what might be on the metadata. This interface codifies those assumptions, but does not validate them.
|
|
15
|
+
*/
|
|
16
|
+
export interface IBlobMetadata {
|
|
17
|
+
blobId?: string;
|
|
18
|
+
localId?: string;
|
|
19
|
+
}
|
|
@@ -51,6 +51,26 @@ and verifying that the following expectation changes won't have any effects:
|
|
|
51
51
|
- client sequence numbers on batch messages can only be used to order messages with the same sequenceNumber
|
|
52
52
|
- 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)
|
|
53
53
|
|
|
54
|
+
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.
|
|
55
|
+
|
|
56
|
+
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.
|
|
57
|
+
|
|
58
|
+
### How to enable
|
|
59
|
+
|
|
60
|
+
**This feature is disabled by default, currently considered experimental and not ready for production usage.**
|
|
61
|
+
|
|
62
|
+
If all prerequisites in the previous section are met, enabling the feature can be done via the `IContainerRuntimeOptions` as following:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
const runtimeOptions: IContainerRuntimeOptions = {
|
|
66
|
+
(...)
|
|
67
|
+
enableGroupedBatching: true,
|
|
68
|
+
(...)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
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.
|
|
73
|
+
|
|
54
74
|
## Chunking for compression
|
|
55
75
|
|
|
56
76
|
**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.
|
|
@@ -29,6 +29,7 @@ const opOverhead = 200;
|
|
|
29
29
|
export class BatchManager {
|
|
30
30
|
private pendingBatch: BatchMessage[] = [];
|
|
31
31
|
private batchContentSize = 0;
|
|
32
|
+
private hasReentrantOps = false;
|
|
32
33
|
|
|
33
34
|
public get length() {
|
|
34
35
|
return this.pendingBatch.length;
|
|
@@ -54,9 +55,14 @@ export class BatchManager {
|
|
|
54
55
|
|
|
55
56
|
constructor(public readonly options: IBatchManagerOptions) {}
|
|
56
57
|
|
|
57
|
-
public push(
|
|
58
|
+
public push(
|
|
59
|
+
message: BatchMessage,
|
|
60
|
+
reentrant: boolean,
|
|
61
|
+
currentClientSequenceNumber?: number,
|
|
62
|
+
): boolean {
|
|
58
63
|
const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
|
|
59
64
|
const opCount = this.pendingBatch.length;
|
|
65
|
+
this.hasReentrantOps = this.hasReentrantOps || reentrant;
|
|
60
66
|
|
|
61
67
|
// Attempt to estimate batch size, aka socket message size.
|
|
62
68
|
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
@@ -100,11 +106,13 @@ export class BatchManager {
|
|
|
100
106
|
content: this.pendingBatch,
|
|
101
107
|
contentSizeInBytes: this.batchContentSize,
|
|
102
108
|
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
109
|
+
hasReentrantOps: this.hasReentrantOps,
|
|
103
110
|
};
|
|
104
111
|
|
|
105
112
|
this.pendingBatch = [];
|
|
106
113
|
this.batchContentSize = 0;
|
|
107
114
|
this.clientSequenceNumber = undefined;
|
|
115
|
+
this.hasReentrantOps = false;
|
|
108
116
|
|
|
109
117
|
return addBatchMetadata(batch);
|
|
110
118
|
}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import { IBatchMessage } from "@fluidframework/container-definitions";
|
|
7
7
|
import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { CompressionAlgorithms, ContainerMessageType
|
|
8
|
+
import { CompressionAlgorithms, ContainerMessageType } from "..";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Batch message type used internally by the runtime
|
|
12
12
|
*/
|
|
13
13
|
export type BatchMessage = IBatchMessage & {
|
|
14
14
|
localOpMetadata: unknown;
|
|
15
|
-
|
|
15
|
+
type: ContainerMessageType;
|
|
16
16
|
referenceSequenceNumber: number;
|
|
17
17
|
compression?: CompressionAlgorithms;
|
|
18
18
|
};
|
|
@@ -34,6 +34,17 @@ export interface IBatch {
|
|
|
34
34
|
* The reference sequence number for the batch
|
|
35
35
|
*/
|
|
36
36
|
readonly referenceSequenceNumber: number | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Wether or not the batch contains at least one op which was produced as the result
|
|
39
|
+
* of processing another op. This means that the batch must be rebased before
|
|
40
|
+
* submitted, to ensure that all ops have the same reference sequence numbers and a
|
|
41
|
+
* consistent view of the data model. This happens when the op is created within a
|
|
42
|
+
* 'changed' event handler of a DDS and will have a different reference sequence number
|
|
43
|
+
* than the rest of the ops in the batch, meaning that it has a different view of the
|
|
44
|
+
* state of the data model, therefore all ops must be resubmitted and rebased to the current
|
|
45
|
+
* reference sequence number to be in agreement about the data model state.
|
|
46
|
+
*/
|
|
47
|
+
readonly hasReentrantOps?: boolean;
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
export interface IBatchCheckpoint {
|
package/src/opLifecycle/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ export {
|
|
|
11
11
|
IChunkedOp,
|
|
12
12
|
IMessageProcessingResult,
|
|
13
13
|
} from "./definitions";
|
|
14
|
-
export { Outbox } from "./outbox";
|
|
14
|
+
export { Outbox, getLongStack } from "./outbox";
|
|
15
15
|
export { OpCompressor } from "./opCompressor";
|
|
16
16
|
export { OpDecompressor } from "./opDecompressor";
|
|
17
17
|
export { OpSplitter, splitOp } from "./opSplitter";
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { ITelemetryLoggerExt, ChildLogger } from "@fluidframework/telemetry-utils";
|
|
7
7
|
import { assert, IsoBuffer } from "@fluidframework/common-utils";
|
|
8
8
|
import { UsageError } from "@fluidframework/container-utils";
|
|
9
|
-
import { ChildLogger } from "@fluidframework/telemetry-utils";
|
|
10
9
|
import { compress } from "lz4js";
|
|
11
10
|
import { CompressionAlgorithms } from "../containerRuntime";
|
|
12
11
|
import { estimateSocketSize } from "./batchManager";
|
|
@@ -20,7 +19,7 @@ import { IBatch, BatchMessage } from "./definitions";
|
|
|
20
19
|
export class OpCompressor {
|
|
21
20
|
private readonly logger;
|
|
22
21
|
|
|
23
|
-
constructor(logger:
|
|
22
|
+
constructor(logger: ITelemetryLoggerExt) {
|
|
24
23
|
this.logger = ChildLogger.create(logger, "OpCompressor");
|
|
25
24
|
}
|
|
26
25
|
|
|
@@ -47,10 +46,7 @@ export class OpCompressor {
|
|
|
47
46
|
// Add empty placeholder messages to reserve the sequence numbers
|
|
48
47
|
for (const message of batch.content.slice(1)) {
|
|
49
48
|
messages.push({
|
|
50
|
-
|
|
51
|
-
contents: undefined,
|
|
52
|
-
type: message.deserializedContent.type,
|
|
53
|
-
},
|
|
49
|
+
type: message.type,
|
|
54
50
|
localOpMetadata: message.localOpMetadata,
|
|
55
51
|
metadata: message.metadata,
|
|
56
52
|
referenceSequenceNumber: message.referenceSequenceNumber,
|
|
@@ -79,7 +75,7 @@ export class OpCompressor {
|
|
|
79
75
|
|
|
80
76
|
private serializeBatch(batch: IBatch): string {
|
|
81
77
|
try {
|
|
82
|
-
return
|
|
78
|
+
return `[${batch.content.map((message) => message.contents).join(",")}]`;
|
|
83
79
|
} catch (e: any) {
|
|
84
80
|
if (e.message === "Invalid string length") {
|
|
85
81
|
// This is how JSON.stringify signals that
|
|
@@ -6,11 +6,18 @@
|
|
|
6
6
|
import { decompress } from "lz4js";
|
|
7
7
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { assert, IsoBuffer, Uint8ArrayToString } from "@fluidframework/common-utils";
|
|
9
|
-
import { ChildLogger } from "@fluidframework/telemetry-utils";
|
|
10
|
-
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
9
|
+
import { ChildLogger, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
11
10
|
import { CompressionAlgorithms } from "../containerRuntime";
|
|
11
|
+
import { IBatchMetadata } from "../metadata";
|
|
12
12
|
import { IMessageProcessingResult } from "./definitions";
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Compression makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
|
|
16
|
+
*/
|
|
17
|
+
interface IPackedContentsContents {
|
|
18
|
+
packedContents: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* State machine that "unrolls" contents of compressed batches of ops after decompressing them.
|
|
16
23
|
* This class relies on some implicit contracts defined below:
|
|
@@ -25,7 +32,7 @@ export class OpDecompressor {
|
|
|
25
32
|
private processedCount = 0;
|
|
26
33
|
private readonly logger;
|
|
27
34
|
|
|
28
|
-
constructor(logger:
|
|
35
|
+
constructor(logger: ITelemetryLoggerExt) {
|
|
29
36
|
this.logger = ChildLogger.create(logger, "OpDecompressor");
|
|
30
37
|
}
|
|
31
38
|
|
|
@@ -35,7 +42,10 @@ export class OpDecompressor {
|
|
|
35
42
|
0x511 /* Only lz4 compression is supported */,
|
|
36
43
|
);
|
|
37
44
|
|
|
38
|
-
if (
|
|
45
|
+
if (
|
|
46
|
+
(message.metadata as IBatchMetadata | undefined)?.batch === true &&
|
|
47
|
+
this.isCompressed(message)
|
|
48
|
+
) {
|
|
39
49
|
// Beginning of a compressed batch
|
|
40
50
|
assert(this.activeBatch === false, 0x4b8 /* shouldn't have multiple active batches */);
|
|
41
51
|
if (message.compression) {
|
|
@@ -48,7 +58,10 @@ export class OpDecompressor {
|
|
|
48
58
|
|
|
49
59
|
this.activeBatch = true;
|
|
50
60
|
|
|
51
|
-
const contents = IsoBuffer.from(
|
|
61
|
+
const contents = IsoBuffer.from(
|
|
62
|
+
(message.contents as IPackedContentsContents).packedContents,
|
|
63
|
+
"base64",
|
|
64
|
+
);
|
|
52
65
|
const decompressedMessage = decompress(contents);
|
|
53
66
|
const intoString = Uint8ArrayToString(decompressedMessage);
|
|
54
67
|
const asObj = JSON.parse(intoString);
|
|
@@ -62,7 +75,7 @@ export class OpDecompressor {
|
|
|
62
75
|
|
|
63
76
|
if (
|
|
64
77
|
this.rootMessageContents !== undefined &&
|
|
65
|
-
message.metadata?.batch === undefined &&
|
|
78
|
+
(message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
|
|
66
79
|
this.activeBatch
|
|
67
80
|
) {
|
|
68
81
|
assert(message.contents === undefined, 0x512 /* Expecting empty message */);
|
|
@@ -74,7 +87,10 @@ export class OpDecompressor {
|
|
|
74
87
|
};
|
|
75
88
|
}
|
|
76
89
|
|
|
77
|
-
if (
|
|
90
|
+
if (
|
|
91
|
+
this.rootMessageContents !== undefined &&
|
|
92
|
+
(message.metadata as IBatchMetadata | undefined)?.batch === false
|
|
93
|
+
) {
|
|
78
94
|
// End of compressed batch
|
|
79
95
|
const returnMessage = newMessage(
|
|
80
96
|
message,
|
|
@@ -91,14 +107,20 @@ export class OpDecompressor {
|
|
|
91
107
|
};
|
|
92
108
|
}
|
|
93
109
|
|
|
94
|
-
if (
|
|
110
|
+
if (
|
|
111
|
+
(message.metadata as IBatchMetadata | undefined)?.batch === undefined &&
|
|
112
|
+
this.isCompressed(message)
|
|
113
|
+
) {
|
|
95
114
|
// Single compressed message
|
|
96
115
|
assert(
|
|
97
116
|
this.activeBatch === false,
|
|
98
117
|
0x4ba /* shouldn't receive compressed message in middle of a batch */,
|
|
99
118
|
);
|
|
100
119
|
|
|
101
|
-
const contents = IsoBuffer.from(
|
|
120
|
+
const contents = IsoBuffer.from(
|
|
121
|
+
(message.contents as IPackedContentsContents).packedContents,
|
|
122
|
+
"base64",
|
|
123
|
+
);
|
|
102
124
|
const decompressedMessage = decompress(contents);
|
|
103
125
|
const intoString = new TextDecoder().decode(decompressedMessage);
|
|
104
126
|
const asObj = JSON.parse(intoString);
|
|
@@ -136,16 +158,19 @@ export class OpDecompressor {
|
|
|
136
158
|
message.contents !== null &&
|
|
137
159
|
typeof message.contents === "object" &&
|
|
138
160
|
Object.keys(message.contents).length === 1 &&
|
|
139
|
-
message.contents
|
|
140
|
-
|
|
141
|
-
message.contents.packedContents.length > 0 &&
|
|
142
|
-
IsoBuffer.from(
|
|
143
|
-
message.contents.packedContents
|
|
161
|
+
typeof (message.contents as { packedContents?: unknown }).packedContents ===
|
|
162
|
+
"string" &&
|
|
163
|
+
(message.contents as IPackedContentsContents).packedContents.length > 0 &&
|
|
164
|
+
IsoBuffer.from(
|
|
165
|
+
(message.contents as IPackedContentsContents).packedContents,
|
|
166
|
+
"base64",
|
|
167
|
+
).toString("base64") ===
|
|
168
|
+
(message.contents as IPackedContentsContents).packedContents
|
|
144
169
|
) {
|
|
145
170
|
this.logger.sendTelemetryEvent({
|
|
146
171
|
eventName: "LegacyCompression",
|
|
147
172
|
type: message.type,
|
|
148
|
-
batch: message.metadata?.batch,
|
|
173
|
+
batch: (message.metadata as IBatchMetadata | undefined)?.batch,
|
|
149
174
|
});
|
|
150
175
|
return true;
|
|
151
176
|
}
|
|
@@ -165,5 +190,7 @@ const newMessage = (
|
|
|
165
190
|
...originalMessage,
|
|
166
191
|
contents,
|
|
167
192
|
compression: undefined,
|
|
168
|
-
|
|
193
|
+
// TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
195
|
+
metadata: { ...(originalMessage.metadata as any) },
|
|
169
196
|
});
|
|
@@ -5,9 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert } from "@fluidframework/common-utils";
|
|
7
7
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { ContainerMessageType
|
|
8
|
+
import { ContainerMessageType } from "..";
|
|
9
9
|
import { IBatch } from "./definitions";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Grouping makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
|
|
13
|
+
*/
|
|
14
|
+
interface IGroupedBatchMessageContents {
|
|
15
|
+
type: typeof OpGroupingManager.groupedBatchOp;
|
|
16
|
+
contents: IGroupedMessage[];
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
interface IGroupedMessage {
|
|
12
20
|
contents?: unknown;
|
|
13
21
|
metadata?: Record<string, unknown>;
|
|
@@ -15,7 +23,7 @@ interface IGroupedMessage {
|
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
export class OpGroupingManager {
|
|
18
|
-
static groupedBatchOp = "groupedBatch";
|
|
26
|
+
static readonly groupedBatchOp = "groupedBatch";
|
|
19
27
|
|
|
20
28
|
constructor(private readonly groupedBatchingEnabled: boolean) {}
|
|
21
29
|
|
|
@@ -25,10 +33,6 @@ export class OpGroupingManager {
|
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
for (const message of batch.content) {
|
|
28
|
-
// Blob attaches cannot be grouped (grouped batching would hide metadata)
|
|
29
|
-
if (message.deserializedContent.type === ContainerMessageType.BlobAttach) {
|
|
30
|
-
return batch;
|
|
31
|
-
}
|
|
32
36
|
if (message.metadata) {
|
|
33
37
|
const keys = Object.keys(message.metadata);
|
|
34
38
|
assert(keys.length < 2, 0x5dd /* cannot group ops with metadata */);
|
|
@@ -39,14 +43,14 @@ export class OpGroupingManager {
|
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
|
|
42
|
-
const
|
|
46
|
+
const serializedContent = JSON.stringify({
|
|
43
47
|
type: OpGroupingManager.groupedBatchOp,
|
|
44
48
|
contents: batch.content.map<IGroupedMessage>((message) => ({
|
|
45
49
|
contents: message.contents === undefined ? undefined : JSON.parse(message.contents),
|
|
46
50
|
metadata: message.metadata,
|
|
47
51
|
compression: message.compression,
|
|
48
52
|
})),
|
|
49
|
-
};
|
|
53
|
+
});
|
|
50
54
|
|
|
51
55
|
const groupedBatch: IBatch = {
|
|
52
56
|
...batch,
|
|
@@ -55,9 +59,8 @@ export class OpGroupingManager {
|
|
|
55
59
|
localOpMetadata: undefined,
|
|
56
60
|
metadata: undefined,
|
|
57
61
|
referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
contents: JSON.stringify(deserializedContent),
|
|
62
|
+
contents: serializedContent,
|
|
63
|
+
type: OpGroupingManager.groupedBatchOp as ContainerMessageType,
|
|
61
64
|
},
|
|
62
65
|
],
|
|
63
66
|
};
|
|
@@ -65,11 +68,14 @@ export class OpGroupingManager {
|
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
public ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {
|
|
68
|
-
if (
|
|
71
|
+
if (
|
|
72
|
+
(op.contents as { type?: unknown } | undefined)?.type !==
|
|
73
|
+
OpGroupingManager.groupedBatchOp
|
|
74
|
+
) {
|
|
69
75
|
return [op];
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
const messages = op.contents
|
|
78
|
+
const messages = (op.contents as IGroupedBatchMessageContents).contents;
|
|
73
79
|
let fakeCsn = 1;
|
|
74
80
|
return messages.map((subMessage) => ({
|
|
75
81
|
...op,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { ITelemetryLoggerExt, ChildLogger } from "@fluidframework/telemetry-utils";
|
|
7
7
|
import { assert } from "@fluidframework/common-utils";
|
|
8
8
|
import { IBatchMessage } from "@fluidframework/container-definitions";
|
|
9
9
|
import {
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
extractSafePropertiesFromMessage,
|
|
12
12
|
} from "@fluidframework/container-utils";
|
|
13
13
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
14
|
-
import { ChildLogger } from "@fluidframework/telemetry-utils";
|
|
15
14
|
import { ContainerMessageType, ContainerRuntimeMessage } from "../containerRuntime";
|
|
16
15
|
import { estimateSocketSize } from "./batchManager";
|
|
17
16
|
import { BatchMessage, IBatch, IChunkedOp, IMessageProcessingResult } from "./definitions";
|
|
@@ -31,7 +30,7 @@ export class OpSplitter {
|
|
|
31
30
|
| undefined,
|
|
32
31
|
public readonly chunkSizeInBytes: number,
|
|
33
32
|
private readonly maxBatchSizeInBytes: number,
|
|
34
|
-
logger:
|
|
33
|
+
logger: ITelemetryLoggerExt,
|
|
35
34
|
) {
|
|
36
35
|
this.chunkMap = new Map<string, string[]>(chunks);
|
|
37
36
|
this.logger = ChildLogger.create(logger, "OpSplitter");
|
|
@@ -53,7 +52,9 @@ export class OpSplitter {
|
|
|
53
52
|
};
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
|
|
55
|
+
// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
57
|
+
const clientId = message.clientId as string;
|
|
57
58
|
const chunkedContent = message.contents as IChunkedOp;
|
|
58
59
|
this.addChunk(clientId, chunkedContent, message);
|
|
59
60
|
|
|
@@ -214,7 +215,7 @@ const chunkToBatchMessage = (
|
|
|
214
215
|
};
|
|
215
216
|
return {
|
|
216
217
|
contents: JSON.stringify(payload),
|
|
217
|
-
|
|
218
|
+
type: payload.type,
|
|
218
219
|
metadata,
|
|
219
220
|
localOpMetadata: undefined,
|
|
220
221
|
referenceSequenceNumber,
|
|
@@ -251,7 +252,7 @@ export const splitOp = (
|
|
|
251
252
|
const chunk: IChunkedOp = {
|
|
252
253
|
chunkId,
|
|
253
254
|
contents: op.contents.substr(offset, chunkSizeInBytes),
|
|
254
|
-
originalType: op.
|
|
255
|
+
originalType: op.type,
|
|
255
256
|
totalChunks: chunkCount,
|
|
256
257
|
};
|
|
257
258
|
|