@fluidframework/container-runtime 2.0.0-internal.3.0.1 → 2.0.0-internal.3.1.0
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 -19
- package/.mocharc.js +2 -2
- package/api-extractor.json +2 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +9 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +80 -33
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +11 -9
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +3 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +10 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +140 -72
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +11 -9
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +18 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +66 -15
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -3
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +3 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts +26 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +103 -18
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +8 -3
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/garbageCollection.d.ts +34 -14
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +188 -93
- package/dist/garbageCollection.js.map +1 -1
- package/dist/garbageCollectionConstants.d.ts +3 -0
- package/dist/garbageCollectionConstants.d.ts.map +1 -1
- package/dist/garbageCollectionConstants.js +6 -1
- package/dist/garbageCollectionConstants.js.map +1 -1
- package/dist/garbageCollectionHelpers.d.ts +26 -0
- package/dist/garbageCollectionHelpers.d.ts.map +1 -0
- package/dist/garbageCollectionHelpers.js +45 -0
- package/dist/garbageCollectionHelpers.js.map +1 -0
- package/dist/gcSweepReadyUsageDetection.d.ts +5 -5
- package/dist/gcSweepReadyUsageDetection.d.ts.map +1 -1
- package/dist/gcSweepReadyUsageDetection.js +14 -10
- package/dist/gcSweepReadyUsageDetection.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +5 -5
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +19 -12
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +5 -2
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +4 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +19 -17
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.d.ts.map +1 -1
- package/dist/opProperties.js +1 -3
- package/dist/opProperties.js.map +1 -1
- package/dist/orderedClientElection.d.ts.map +1 -1
- package/dist/orderedClientElection.js +10 -4
- package/dist/orderedClientElection.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 +7 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +7 -4
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/runningSummarizer.d.ts.map +1 -1
- package/dist/runningSummarizer.js +34 -21
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +3 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/serializedSnapshotStorage.d.ts +2 -2
- package/dist/serializedSnapshotStorage.d.ts.map +1 -1
- package/dist/serializedSnapshotStorage.js +5 -3
- package/dist/serializedSnapshotStorage.js.map +1 -1
- package/dist/summarizer.d.ts +2 -2
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +37 -17
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerClientElection.d.ts.map +1 -1
- package/dist/summarizerClientElection.js.map +1 -1
- package/dist/summarizerHandle.d.ts.map +1 -1
- package/dist/summarizerHandle.js.map +1 -1
- package/dist/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summarizerHeuristics.js +6 -9
- package/dist/summarizerHeuristics.js.map +1 -1
- package/dist/summarizerTypes.d.ts +21 -21
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryCollection.d.ts.map +1 -1
- package/dist/summaryCollection.js +18 -8
- package/dist/summaryCollection.js.map +1 -1
- package/dist/summaryFormat.d.ts +22 -0
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js +18 -10
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryGenerator.d.ts.map +1 -1
- package/dist/summaryGenerator.js +34 -15
- package/dist/summaryGenerator.js.map +1 -1
- package/dist/summaryManager.d.ts.map +1 -1
- package/dist/summaryManager.js +21 -9
- package/dist/summaryManager.js.map +1 -1
- package/dist/throttler.d.ts +2 -2
- package/dist/throttler.d.ts.map +1 -1
- package/dist/throttler.js +4 -4
- package/dist/throttler.js.map +1 -1
- package/garbageCollection.md +15 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +9 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +82 -35
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +11 -9
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +3 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +10 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +146 -78
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +11 -9
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +18 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +68 -17
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -3
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js +3 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts +26 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +109 -24
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +9 -4
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/garbageCollection.d.ts +34 -14
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +190 -95
- package/lib/garbageCollection.js.map +1 -1
- package/lib/garbageCollectionConstants.d.ts +3 -0
- package/lib/garbageCollectionConstants.d.ts.map +1 -1
- package/lib/garbageCollectionConstants.js +5 -0
- package/lib/garbageCollectionConstants.js.map +1 -1
- package/lib/garbageCollectionHelpers.d.ts +26 -0
- package/lib/garbageCollectionHelpers.d.ts.map +1 -0
- package/lib/garbageCollectionHelpers.js +40 -0
- package/lib/garbageCollectionHelpers.js.map +1 -0
- package/lib/gcSweepReadyUsageDetection.d.ts +5 -5
- package/lib/gcSweepReadyUsageDetection.d.ts.map +1 -1
- package/lib/gcSweepReadyUsageDetection.js +14 -10
- package/lib/gcSweepReadyUsageDetection.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +5 -5
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +19 -12
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +5 -2
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +5 -2
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +19 -17
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.d.ts.map +1 -1
- package/lib/opProperties.js +1 -3
- package/lib/opProperties.js.map +1 -1
- package/lib/orderedClientElection.d.ts.map +1 -1
- package/lib/orderedClientElection.js +10 -4
- package/lib/orderedClientElection.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 +7 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +7 -4
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/runningSummarizer.d.ts.map +1 -1
- package/lib/runningSummarizer.js +35 -22
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +3 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/serializedSnapshotStorage.d.ts +2 -2
- package/lib/serializedSnapshotStorage.d.ts.map +1 -1
- package/lib/serializedSnapshotStorage.js +5 -3
- package/lib/serializedSnapshotStorage.js.map +1 -1
- package/lib/summarizer.d.ts +2 -2
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +37 -17
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerClientElection.d.ts.map +1 -1
- package/lib/summarizerClientElection.js.map +1 -1
- package/lib/summarizerHandle.d.ts.map +1 -1
- package/lib/summarizerHandle.js.map +1 -1
- package/lib/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summarizerHeuristics.js +6 -9
- package/lib/summarizerHeuristics.js.map +1 -1
- package/lib/summarizerTypes.d.ts +21 -21
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryCollection.d.ts.map +1 -1
- package/lib/summaryCollection.js +18 -8
- package/lib/summaryCollection.js.map +1 -1
- package/lib/summaryFormat.d.ts +22 -0
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js +20 -12
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryGenerator.d.ts.map +1 -1
- package/lib/summaryGenerator.js +34 -15
- package/lib/summaryGenerator.js.map +1 -1
- package/lib/summaryManager.d.ts.map +1 -1
- package/lib/summaryManager.js +21 -9
- package/lib/summaryManager.js.map +1 -1
- package/lib/throttler.d.ts +2 -2
- package/lib/throttler.d.ts.map +1 -1
- package/lib/throttler.js +4 -4
- package/lib/throttler.js.map +1 -1
- package/package.json +121 -149
- package/prettier.config.cjs +1 -1
- package/src/batchTracker.ts +54 -49
- package/src/blobManager.ts +793 -672
- package/src/connectionTelemetry.ts +280 -249
- package/src/containerHandleContext.ts +27 -29
- package/src/containerRuntime.ts +3168 -2940
- package/src/dataStore.ts +172 -159
- package/src/dataStoreContext.ts +1098 -996
- package/src/dataStoreContexts.ts +178 -161
- package/src/dataStoreRegistry.ts +25 -20
- package/src/dataStores.ts +884 -728
- package/src/deltaScheduler.ts +158 -150
- package/src/garbageCollection.ts +1883 -1692
- package/src/garbageCollectionConstants.ts +6 -0
- package/src/garbageCollectionHelpers.ts +61 -0
- package/src/gcSweepReadyUsageDetection.ts +89 -83
- package/src/index.ts +67 -66
- package/src/opLifecycle/README.md +152 -0
- package/src/opLifecycle/batchManager.ts +145 -141
- package/src/opLifecycle/definitions.ts +29 -29
- package/src/opLifecycle/index.ts +5 -5
- package/src/opLifecycle/opCompressor.ts +54 -53
- package/src/opLifecycle/opDecompressor.ts +100 -81
- package/src/opLifecycle/opSplitter.ts +214 -188
- package/src/opLifecycle/outbox.ts +204 -194
- package/src/opLifecycle/remoteMessageProcessor.ts +62 -62
- package/src/opProperties.ts +11 -9
- package/src/orderedClientElection.ts +489 -457
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +384 -338
- package/src/runWhileConnectedCoordinator.ts +78 -71
- package/src/runningSummarizer.ts +619 -581
- package/src/scheduleManager.ts +299 -269
- package/src/serializedSnapshotStorage.ts +126 -112
- package/src/summarizer.ts +417 -381
- package/src/summarizerClientElection.ts +107 -100
- package/src/summarizerHandle.ts +11 -9
- package/src/summarizerHeuristics.ts +183 -186
- package/src/summarizerTypes.ts +344 -330
- package/src/summaryCollection.ts +378 -349
- package/src/summaryFormat.ts +170 -126
- package/src/summaryGenerator.ts +465 -406
- package/src/summaryManager.ts +377 -348
- package/src/throttler.ts +131 -122
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
- package/dist/garbageCollectionTombstoneUtils.d.ts +0 -14
- package/dist/garbageCollectionTombstoneUtils.d.ts.map +0 -1
- package/dist/garbageCollectionTombstoneUtils.js +0 -23
- package/dist/garbageCollectionTombstoneUtils.js.map +0 -1
- package/lib/garbageCollectionTombstoneUtils.d.ts +0 -14
- package/lib/garbageCollectionTombstoneUtils.d.ts.map +0 -1
- package/lib/garbageCollectionTombstoneUtils.js +0 -19
- package/lib/garbageCollectionTombstoneUtils.js.map +0 -1
- package/src/garbageCollectionTombstoneUtils.ts +0 -28
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"garbageCollectionConstants.d.ts","sourceRoot":"","sources":["../src/garbageCollectionConstants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,8DAA8D;AAC9D,eAAO,MAAM,eAAe,EAAE,SAAa,CAAC;AAC5C,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,EAAE,SAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"garbageCollectionConstants.d.ts","sourceRoot":"","sources":["../src/garbageCollectionConstants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,8DAA8D;AAC9D,eAAO,MAAM,eAAe,EAAE,SAAa,CAAC;AAC5C,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,EAAE,SAAa,CAAC;AAE7C,kJAAkJ;AAClJ,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAGvE,eAAO,MAAM,QAAQ,kCAAkC,CAAC;AAExD,eAAO,MAAM,WAAW,qCAAqC,CAAC;AAE9D,eAAO,MAAM,aAAa,uCAAuC,CAAC;AAElE,eAAO,MAAM,mBAAmB,6CAA6C,CAAC;AAE9E,eAAO,MAAM,eAAe,yCAAyC,CAAC;AAEtE,eAAO,MAAM,kBAAkB,4CAA4C,CAAC;AAE5E,eAAO,MAAM,mBAAmB,6CAA6C,CAAC;AAE9E,eAAO,MAAM,uBAAuB,iDAAiD,CAAC;AAEtF,eAAO,MAAM,wBAAwB,kDAAkD,CAAC;AAExF,eAAO,MAAM,uBAAuB,iDAAiD,CAAC;AAGtF,eAAO,MAAM,kBAAkB,iDAAiD,CAAC;AAGjF,eAAO,MAAM,QAAQ,QAA0B,CAAC;AAEhD,eAAO,MAAM,wBAAwB,QAAe,CAAC;AACrD,eAAO,MAAM,8BAA8B,QAAgB,CAAC"}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
export const stableGCVersion = 1;
|
|
7
7
|
/** The current version of garbage collection. */
|
|
8
8
|
export const currentGCVersion = 2;
|
|
9
|
+
/** This undocumented GC Option (on ContainerRuntime Options) allows an app to disable enforcing GC on old documents by incrementing this value */
|
|
10
|
+
export const gcTombstoneGenerationOptionName = "gcTombstoneGeneration";
|
|
9
11
|
// Feature gate key to turn GC on / off.
|
|
10
12
|
export const runGCKey = "Fluid.GarbageCollection.RunGC";
|
|
11
13
|
// Feature gate key to turn GC sweep on / off.
|
|
@@ -26,6 +28,9 @@ export const throwOnTombstoneLoadKey = "Fluid.GarbageCollection.ThrowOnTombstone
|
|
|
26
28
|
export const throwOnTombstoneUsageKey = "Fluid.GarbageCollection.ThrowOnTombstoneUsage";
|
|
27
29
|
// Feature gate to enable GC version upgrade.
|
|
28
30
|
export const gcVersionUpgradeToV2Key = "Fluid.GarbageCollection.GCVersionUpgradeToV2";
|
|
31
|
+
// Feature gate to enable GC sweep for datastores.
|
|
32
|
+
// TODO: Remove Test from the flag when we are confident to turn on sweep
|
|
33
|
+
export const sweepDatastoresKey = "Fluid.GarbageCollection.Test.SweepDataStores";
|
|
29
34
|
// One day in milliseconds.
|
|
30
35
|
export const oneDayMs = 1 * 24 * 60 * 60 * 1000;
|
|
31
36
|
export const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"garbageCollectionConstants.js","sourceRoot":"","sources":["../src/garbageCollectionConstants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,eAAe,GAAc,CAAC,CAAC;AAC5C,iDAAiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,CAAC;AAE7C,wCAAwC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAG,+BAA+B,CAAC;AACxD,8CAA8C;AAC9C,MAAM,CAAC,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAC9D,kDAAkD;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,oCAAoC,CAAC;AAClE,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAG,sCAAsC,CAAC;AACtE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,yCAAyC,CAAC;AAC5E,qHAAqH;AACrH,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,wFAAwF;AACxF,MAAM,CAAC,MAAM,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,0GAA0G;AAC1G,MAAM,CAAC,MAAM,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,6CAA6C;AAC7C,MAAM,CAAC,MAAM,uBAAuB,GAAG,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"garbageCollectionConstants.js","sourceRoot":"","sources":["../src/garbageCollectionConstants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,eAAe,GAAc,CAAC,CAAC;AAC5C,iDAAiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,CAAC;AAE7C,kJAAkJ;AAClJ,MAAM,CAAC,MAAM,+BAA+B,GAAG,uBAAuB,CAAC;AAEvE,wCAAwC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAG,+BAA+B,CAAC;AACxD,8CAA8C;AAC9C,MAAM,CAAC,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAC9D,kDAAkD;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,oCAAoC,CAAC;AAClE,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAG,sCAAsC,CAAC;AACtE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,yCAAyC,CAAC;AAC5E,qHAAqH;AACrH,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,wFAAwF;AACxF,MAAM,CAAC,MAAM,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,0GAA0G;AAC1G,MAAM,CAAC,MAAM,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,6CAA6C;AAC7C,MAAM,CAAC,MAAM,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,kDAAkD;AAClD,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,8CAA8C,CAAC;AAEjF,2BAA2B;AAC3B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,SAAS;AAC/D,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,UAAU","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { GCVersion } from \"./summaryFormat\";\n\n/** The stable version of garbage collection in production. */\nexport const stableGCVersion: GCVersion = 1;\n/** The current version of garbage collection. */\nexport const currentGCVersion: GCVersion = 2;\n\n/** This undocumented GC Option (on ContainerRuntime Options) allows an app to disable enforcing GC on old documents by incrementing this value */\nexport const gcTombstoneGenerationOptionName = \"gcTombstoneGeneration\";\n\n// Feature gate key to turn GC on / off.\nexport const runGCKey = \"Fluid.GarbageCollection.RunGC\";\n// Feature gate key to turn GC sweep on / off.\nexport const runSweepKey = \"Fluid.GarbageCollection.RunSweep\";\n// Feature gate key to turn GC test mode on / off.\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n// Feature gate key to expire a session after a set period of time.\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n// Feature gate key to write the gc blob as a handle if the data is the same.\nexport const trackGCStateKey = \"Fluid.GarbageCollection.TrackGCState\";\n// Feature gate key to turn GC sweep log off.\nexport const disableSweepLogKey = \"Fluid.GarbageCollection.DisableSweepLog\";\n// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n// Feature gate to enable throwing an error when tombstone object is loaded (requested).\nexport const throwOnTombstoneLoadKey = \"Fluid.GarbageCollection.ThrowOnTombstoneLoad\";\n// Feature gate to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops).\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n// Feature gate to enable GC version upgrade.\nexport const gcVersionUpgradeToV2Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV2\";\n// Feature gate to enable GC sweep for datastores.\n// TODO: Remove Test from the flag when we are confident to turn on sweep\nexport const sweepDatastoresKey = \"Fluid.GarbageCollection.Test.SweepDataStores\";\n\n// One day in milliseconds.\nexport const oneDayMs = 1 * 24 * 60 * 60 * 1000;\n\nexport const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days\nexport const defaultSessionExpiryDurationMs = 30 * oneDayMs; // 30 days\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { ITelemetryGenericEvent } from "@fluidframework/common-definitions";
|
|
6
|
+
import { MonitoringContext } from "@fluidframework/telemetry-utils";
|
|
7
|
+
/**
|
|
8
|
+
* Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a
|
|
9
|
+
* tombstoned or deleted object is loaded.
|
|
10
|
+
*/
|
|
11
|
+
export declare function sendGCUnexpectedUsageEvent(mc: MonitoringContext, event: ITelemetryGenericEvent & {
|
|
12
|
+
category: "error" | "generic";
|
|
13
|
+
gcTombstoneEnforcementAllowed: boolean | undefined;
|
|
14
|
+
}, packagePath: readonly string[] | undefined, error?: unknown): void;
|
|
15
|
+
/**
|
|
16
|
+
* In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants
|
|
17
|
+
* such that enforcing GC (Fail on Tombstone load/usage, GC Sweep) would cause legitimate data loss,
|
|
18
|
+
* the container author may increment the generation value for Tombstone such that containers created
|
|
19
|
+
* with a different value will not be subjected to GC enforcement.
|
|
20
|
+
* If no generation is provided at runtime, this defaults to return true to maintain expected default behavior
|
|
21
|
+
* @param persistedGeneration - The persisted feature support value
|
|
22
|
+
* @param currentGeneration - The current app-provided feature support value
|
|
23
|
+
* @returns true if GC Enforcement (Fail on Tombstone load/usage) should be allowed
|
|
24
|
+
*/
|
|
25
|
+
export declare function shouldAllowGcTombstoneEnforcement(persistedGeneration: number | undefined, currentGeneration: number | undefined): boolean;
|
|
26
|
+
//# sourceMappingURL=garbageCollectionHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"garbageCollectionHelpers.d.ts","sourceRoot":"","sources":["../src/garbageCollectionHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAQpE;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,sBAAsB,GAAG;IAC/B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,6BAA6B,EAAE,OAAO,GAAG,SAAS,CAAC;CACnD,EACD,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC1C,KAAK,CAAC,EAAE,OAAO,QAaf;AAED;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAChD,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,iBAAiB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAMT"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { packagePathToTelemetryProperty } from "@fluidframework/runtime-utils";
|
|
6
|
+
import { disableTombstoneKey, runSweepKey, throwOnTombstoneLoadKey, throwOnTombstoneUsageKey, } from "./garbageCollectionConstants";
|
|
7
|
+
/**
|
|
8
|
+
* Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a
|
|
9
|
+
* tombstoned or deleted object is loaded.
|
|
10
|
+
*/
|
|
11
|
+
export function sendGCUnexpectedUsageEvent(mc, event, packagePath, error) {
|
|
12
|
+
event.pkg = packagePathToTelemetryProperty(packagePath);
|
|
13
|
+
event.tombstoneFlags = JSON.stringify({
|
|
14
|
+
DisableTombstone: mc.config.getBoolean(disableTombstoneKey),
|
|
15
|
+
ThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),
|
|
16
|
+
ThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),
|
|
17
|
+
});
|
|
18
|
+
event.sweepFlags = JSON.stringify({
|
|
19
|
+
EnableSweepFlag: mc.config.getBoolean(runSweepKey),
|
|
20
|
+
});
|
|
21
|
+
mc.logger.sendTelemetryEvent(event, error);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants
|
|
25
|
+
* such that enforcing GC (Fail on Tombstone load/usage, GC Sweep) would cause legitimate data loss,
|
|
26
|
+
* the container author may increment the generation value for Tombstone such that containers created
|
|
27
|
+
* with a different value will not be subjected to GC enforcement.
|
|
28
|
+
* If no generation is provided at runtime, this defaults to return true to maintain expected default behavior
|
|
29
|
+
* @param persistedGeneration - The persisted feature support value
|
|
30
|
+
* @param currentGeneration - The current app-provided feature support value
|
|
31
|
+
* @returns true if GC Enforcement (Fail on Tombstone load/usage) should be allowed
|
|
32
|
+
*/
|
|
33
|
+
export function shouldAllowGcTombstoneEnforcement(persistedGeneration, currentGeneration) {
|
|
34
|
+
// If no Generation value is provided for this session, then we should default to letting Tombstone feature behave as intended.
|
|
35
|
+
if (currentGeneration === undefined) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return persistedGeneration === currentGeneration;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=garbageCollectionHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"garbageCollectionHelpers.js","sourceRoot":"","sources":["../src/garbageCollectionHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACxB,MAAM,8BAA8B,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACzC,EAAqB,EACrB,KAGC,EACD,WAA0C,EAC1C,KAAe;IAEf,KAAK,CAAC,GAAG,GAAG,8BAA8B,CAAC,WAAW,CAAC,CAAC;IACxD,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,gBAAgB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAC3D,qBAAqB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC;QACrE,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,uBAAuB,CAAC;KACnE,CAAC,CAAC;IACH,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,eAAe,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;KAClD,CAAC,CAAC;IAEH,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iCAAiC,CAChD,mBAAuC,EACvC,iBAAqC;IAErC,+HAA+H;IAC/H,IAAI,iBAAiB,KAAK,SAAS,EAAE;QACpC,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,mBAAmB,KAAK,iBAAiB,CAAC;AAClD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent } from \"@fluidframework/common-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport { MonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport {\n\tdisableTombstoneKey,\n\trunSweepKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n} from \"./garbageCollectionConstants\";\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = packagePathToTelemetryProperty(packagePath);\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n\n/**\n * In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants\n * such that enforcing GC (Fail on Tombstone load/usage, GC Sweep) would cause legitimate data loss,\n * the container author may increment the generation value for Tombstone such that containers created\n * with a different value will not be subjected to GC enforcement.\n * If no generation is provided at runtime, this defaults to return true to maintain expected default behavior\n * @param persistedGeneration - The persisted feature support value\n * @param currentGeneration - The current app-provided feature support value\n * @returns true if GC Enforcement (Fail on Tombstone load/usage) should be allowed\n */\nexport function shouldAllowGcTombstoneEnforcement(\n\tpersistedGeneration: number | undefined,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, then we should default to letting Tombstone feature behave as intended.\n\tif (currentGeneration === undefined) {\n\t\treturn true;\n\t}\n\treturn persistedGeneration === currentGeneration;\n}\n"]}
|
|
@@ -42,11 +42,11 @@ export declare class SweepReadyUsageDetectionHandler {
|
|
|
42
42
|
private readonly localStorage;
|
|
43
43
|
constructor(uniqueContainerKey: string, mc: MonitoringContext, closeFn: (error?: ICriticalContainerError) => void, localStorageOverride?: Pick<Storage, "getItem" | "setItem">);
|
|
44
44
|
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
* If SweepReady Usage Detection is enabled, close the interactive container.
|
|
46
|
+
* If the SkipClosureForXDays setting is set, don't close the container more than once in that period.
|
|
47
|
+
*
|
|
48
|
+
* Once Sweep is fully implemented, this will be removed since the objects will be gone
|
|
49
|
+
* and errors will arise elsewhere in the runtime
|
|
50
50
|
*/
|
|
51
51
|
usageDetectedInInteractiveClient(errorProps: ITelemetryProperties): void;
|
|
52
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcSweepReadyUsageDetection.d.ts","sourceRoot":"","sources":["../src/gcSweepReadyUsageDetection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,
|
|
1
|
+
{"version":3,"file":"gcSweepReadyUsageDetection.d.ts","sourceRoot":"","sources":["../src/gcSweepReadyUsageDetection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAEN,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,MAAM,iCAAiC,CAAC;AAGzC;;;GAGG;AACH,eAAO,MAAM,sBAAsB,iFAC4C,CAAC;AAEhF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,sEAC6B,CAAC;AAqBrE;;;;;;;GAOG;AACH,qBAAa,oBAAqB,SAAQ,YAAa,YAAW,eAAe;IAChF,oHAAoH;IAC7G,SAAS,EAAE,MAAM,CAAiD;CACzE;AAED;;;;;;;GAOG;AACH,qBAAa,+BAA+B;IAI1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IALzB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuC;gBAGlD,kBAAkB,EAAE,MAAM,EAC1B,EAAE,EAAE,iBAAiB,EACrB,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,uBAAuB,KAAK,IAAI,EACnE,oBAAoB,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IAc5D;;;;;;OAMG;IACI,gCAAgC,CAAC,UAAU,EAAE,oBAAoB;CA+CxE"}
|
|
@@ -65,15 +65,17 @@ export class SweepReadyUsageDetectionHandler {
|
|
|
65
65
|
this.localStorage = (_a = localStorageOverride !== null && localStorageOverride !== void 0 ? localStorageOverride : globalThis.localStorage) !== null && _a !== void 0 ? _a : noopStorage;
|
|
66
66
|
if (this.localStorage === noopStorage) {
|
|
67
67
|
// This means the Skip Closure Period logic will not work.
|
|
68
|
-
this.mc.logger.sendTelemetryEvent({
|
|
68
|
+
this.mc.logger.sendTelemetryEvent({
|
|
69
|
+
eventName: "SweepReadyUsageDetectionHandlerNoopStorage",
|
|
70
|
+
});
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
* If SweepReady Usage Detection is enabled, close the interactive container.
|
|
75
|
+
* If the SkipClosureForXDays setting is set, don't close the container more than once in that period.
|
|
76
|
+
*
|
|
77
|
+
* Once Sweep is fully implemented, this will be removed since the objects will be gone
|
|
78
|
+
* and errors will arise elsewhere in the runtime
|
|
77
79
|
*/
|
|
78
80
|
usageDetectedInInteractiveClient(errorProps) {
|
|
79
81
|
var _a;
|
|
@@ -96,15 +98,17 @@ export class SweepReadyUsageDetectionHandler {
|
|
|
96
98
|
pastClosuresMap = parsedValue;
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
}
|
|
101
|
+
catch (e) { }
|
|
101
102
|
lastCloseTime = (_a = pastClosuresMap[this.uniqueContainerKey]) === null || _a === void 0 ? void 0 : _a.lastCloseTime;
|
|
102
103
|
// Don't close if we did already within the Skip Closure Period
|
|
103
|
-
if (lastCloseTime !== undefined &&
|
|
104
|
+
if (lastCloseTime !== undefined &&
|
|
105
|
+
Date.now() < lastCloseTime + skipClosureForXDays * oneDayMs) {
|
|
104
106
|
shouldClose = false;
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
|
-
const error = new SweepReadyUsageError("SweepReady object used in Non-Summarizer Client", {
|
|
109
|
+
const error = new SweepReadyUsageError("SweepReady object used in Non-Summarizer Client", {
|
|
110
|
+
errorDetails: JSON.stringify(Object.assign(Object.assign({}, errorProps), { lastCloseTime, skipClosureForXDays })),
|
|
111
|
+
});
|
|
108
112
|
if (shouldClose) {
|
|
109
113
|
// Update closures map in localStorage before closing
|
|
110
114
|
// Note there is a race condition between different tabs updating localStorage and overwriting
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcSweepReadyUsageDetection.js","sourceRoot":"","sources":["../src/gcSweepReadyUsageDetection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,
|
|
1
|
+
{"version":3,"file":"gcSweepReadyUsageDetection.js","sourceRoot":"","sources":["../src/gcSweepReadyUsageDetection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryProperties } from \"@fluidframework/common-definitions\";\nimport { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport {\n\tIConfigProvider,\n\tIFluidErrorBase,\n\tLoggingError,\n\tMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport { oneDayMs } from \"./garbageCollectionConstants\";\n\n/**\n * Feature Gate Key -\n * How many days between closing the container from this error (avoids locking user out of their file altogether)\n */\nexport const skipClosureForXDaysKey =\n\t\"Fluid.GarbageCollection.Dogfood.SweepReadyUsageDetection.SkipClosureForXDays\";\n\n/**\n * LocalStorage key (NOT via feature gate / monitoring context)\n * A map from docId to info about the last time we closed due to this error\n */\nexport const closuresMapLocalStorageKey =\n\t\"Fluid.GarbageCollection.Dogfood.SweepReadyUsageDetection.Closures\";\n\n/**\n * Feature gate key to enable closing the container if SweepReady objects are used.\n * Value should contain keywords \"interactiveClient\" and/or \"summarizer\" to enable detection in each container type\n */\nconst sweepReadyUsageDetectionSetting = {\n\tread(config: IConfigProvider) {\n\t\tconst sweepReadyUsageDetectionKey =\n\t\t\t\"Fluid.GarbageCollection.Dogfood.SweepReadyUsageDetection\";\n\t\tconst value = config.getString(sweepReadyUsageDetectionKey);\n\t\tif (value === undefined) {\n\t\t\treturn { interactiveClient: false, summarizer: false };\n\t\t}\n\t\treturn {\n\t\t\tinteractiveClient: value.includes(\"interactiveClient\"),\n\t\t\tsummarizer: value.includes(\"summarizer\"),\n\t\t};\n\t},\n};\n\n/**\n * Error class raised when a SweepReady object is used, indicating a bug in how\n * references are managed in the container by the application, or a bug in how\n * GC tracks those references.\n *\n * There's a chance for false positives when this error is raised by an Interactive Container,\n * since only the Summarizer has the latest truth about unreferenced node tracking\n */\nexport class SweepReadyUsageError extends LoggingError implements IFluidErrorBase {\n\t/** This errorType will be in temporary use (until Sweep is fully implemented) so don't add to any errorType type */\n\tpublic errorType: string = \"unreferencedObjectUsedAfterGarbageCollected\";\n}\n\n/**\n * This class encapsulates the logic around what to do when a SweepReady object is used.\n * There are several tactics we plan to use in Dogfood environments to aid diagnosis of these cases:\n * - Closing the interactive container when either the interactive or summarizer client detects this kind of violation\n * (via sweepReadyUsageDetectionSetting above)\n * - Throttling the frequency of these crashes via a \"Skip Closure Period\" per container per device\n * (via skipClosureForXDaysKey above. Uses localStorage and closuresMapLocalStorageKey to implement this behavior)\n */\nexport class SweepReadyUsageDetectionHandler {\n\tprivate readonly localStorage: Pick<Storage, \"getItem\" | \"setItem\">;\n\n\tconstructor(\n\t\tprivate readonly uniqueContainerKey: string,\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly closeFn: (error?: ICriticalContainerError) => void,\n\t\tlocalStorageOverride?: Pick<Storage, \"getItem\" | \"setItem\">,\n\t) {\n\t\tconst noopStorage = { getItem: () => null, setItem: () => {} };\n\t\t// localStorage is not defined in Node environment, so fall back to noopStorage if needed.\n\t\tthis.localStorage = localStorageOverride ?? globalThis.localStorage ?? noopStorage;\n\n\t\tif (this.localStorage === noopStorage) {\n\t\t\t// This means the Skip Closure Period logic will not work.\n\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"SweepReadyUsageDetectionHandlerNoopStorage\",\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * If SweepReady Usage Detection is enabled, close the interactive container.\n\t * If the SkipClosureForXDays setting is set, don't close the container more than once in that period.\n\t *\n\t * Once Sweep is fully implemented, this will be removed since the objects will be gone\n\t * and errors will arise elsewhere in the runtime\n\t */\n\tpublic usageDetectedInInteractiveClient(errorProps: ITelemetryProperties) {\n\t\tif (!sweepReadyUsageDetectionSetting.read(this.mc.config).interactiveClient) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Default stance is we close every time - this reflects the severity of SweepReady Object Usage.\n\t\t// However, we may choose to \"throttle\" the closures by setting the SkipClosureForXDays setting,\n\t\t// which will only allow the container to close once during that period, to avoid locking users out.\n\t\tlet shouldClose: boolean = true;\n\t\tlet pastClosuresMap: Record<string, { lastCloseTime: number } | undefined> = {};\n\t\tlet lastCloseTime: number | undefined;\n\t\tconst skipClosureForXDays = this.mc.config.getNumber(skipClosureForXDaysKey);\n\t\tif (skipClosureForXDays !== undefined) {\n\t\t\t// Read pastClosuresMap from localStorage then extract the lastCloseTime from the map\n\t\t\ttry {\n\t\t\t\tconst rawValue = this.localStorage.getItem(closuresMapLocalStorageKey);\n\t\t\t\tconst parsedValue = rawValue === null ? {} : JSON.parse(rawValue);\n\t\t\t\tif (typeof parsedValue === \"object\") {\n\t\t\t\t\tpastClosuresMap = parsedValue;\n\t\t\t\t}\n\t\t\t} catch (e) {}\n\t\t\tlastCloseTime = pastClosuresMap[this.uniqueContainerKey]?.lastCloseTime;\n\n\t\t\t// Don't close if we did already within the Skip Closure Period\n\t\t\tif (\n\t\t\t\tlastCloseTime !== undefined &&\n\t\t\t\tDate.now() < lastCloseTime + skipClosureForXDays * oneDayMs\n\t\t\t) {\n\t\t\t\tshouldClose = false;\n\t\t\t}\n\t\t}\n\n\t\tconst error = new SweepReadyUsageError(\"SweepReady object used in Non-Summarizer Client\", {\n\t\t\terrorDetails: JSON.stringify({ ...errorProps, lastCloseTime, skipClosureForXDays }),\n\t\t});\n\t\tif (shouldClose) {\n\t\t\t// Update closures map in localStorage before closing\n\t\t\t// Note there is a race condition between different tabs updating localStorage and overwriting\n\t\t\t// each others' updates. If so, some tab will crash again. Just reload one at a time to get unstuck\n\t\t\tpastClosuresMap[this.uniqueContainerKey] = { lastCloseTime: Date.now() };\n\t\t\tthis.localStorage.setItem(closuresMapLocalStorageKey, JSON.stringify(pastClosuresMap));\n\n\t\t\tthis.closeFn(error);\n\t\t} else {\n\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"SweepReadyObject_UsageAllowed\" }, error);\n\t\t}\n\t}\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { ContainerMessageType, ContainerRuntimeMessage, IGCRuntimeOptions, ISummaryRuntimeOptions, ISummaryBaseConfiguration, ISummaryConfigurationHeuristics, ISummaryConfigurationDisableSummarizer, ISummaryConfigurationDisableHeuristics, IContainerRuntimeOptions, IRootSummaryTreeWithStats, isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, RuntimeHeaders, AllowTombstoneRequestHeaderKey, TombstoneResponseHeaderKey, ISummaryConfiguration, DefaultSummaryConfiguration, ICompressionRuntimeOptions, CompressionAlgorithms, } from "./containerRuntime";
|
|
6
6
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
7
|
-
export { IGCStats
|
|
7
|
+
export { IGCStats } from "./garbageCollection";
|
|
8
8
|
export { IPendingFlush, IPendingLocalState, IPendingMessage, IPendingState, } from "./pendingStateManager";
|
|
9
9
|
export { Summarizer } from "./summarizer";
|
|
10
10
|
export { EnqueueSummarizeResult, IAckSummaryResult, IBaseSummarizeResult, IBroadcastSummaryResult, ICancellationToken, IConnectableRuntime, IEnqueueSummarizeOptions, IGenerateSummaryTreeResult, IGeneratedSummaryStats, INackSummaryResult, IOnDemandSummarizeOptions, IProvideSummarizer, IRefreshSummaryAckOptions, ISubmitSummaryOpResult, ISubmitSummaryOptions, ISummarizeOptions, ISummarizeResults, ISummarizer, ISummarizerEvents, ISummarizerInternalsProvider, ISummarizerRuntime, ISummarizingWarning, ISummaryCancellationToken, IUploadSummaryResult, SubmitSummaryResult, SummarizeResultPart, SummarizerStopReason, } from "./summarizerTypes";
|
|
11
11
|
export { IAckedSummary, IClientSummaryWatcher, ISummary, ISummaryCollectionOpEvents, ISummaryAckMessage, ISummaryNackMessage, ISummaryOpMessage, OpActionEventListener, OpActionEventName, SummaryCollection, } from "./summaryCollection";
|
|
12
|
-
export { ICancellableSummarizerController, neverCancelledSummaryToken } from "./runWhileConnectedCoordinator";
|
|
12
|
+
export { ICancellableSummarizerController, neverCancelledSummaryToken, } from "./runWhileConnectedCoordinator";
|
|
13
13
|
export { IChunkedOp, unpackRuntimeMessage } from "./opLifecycle";
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,8BAA8B,EAC9B,0BAA0B,EAC1B,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EACN,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,aAAa,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACN,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,gCAAgC,EAChC,0BAA0B,GAC1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -7,6 +7,6 @@ export { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
|
7
7
|
export { Summarizer } from "./summarizer";
|
|
8
8
|
export { ISummarizer, } from "./summarizerTypes";
|
|
9
9
|
export { SummaryCollection, } from "./summaryCollection";
|
|
10
|
-
export { neverCancelledSummaryToken } from "./runWhileConnectedCoordinator";
|
|
10
|
+
export { neverCancelledSummaryToken, } from "./runWhileConnectedCoordinator";
|
|
11
11
|
export { unpackRuntimeMessage } from "./opLifecycle";
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,oBAAoB,EAUpB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,8BAA8B,EAC9B,0BAA0B,EAE1B,2BAA2B,EAE3B,qBAAqB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAQ7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAkBN,WAAW,GAUX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAUN,iBAAiB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,0BAA0B,GAC1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAc,oBAAoB,EAAE,MAAM,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tContainerMessageType,\n\tContainerRuntimeMessage,\n\tIGCRuntimeOptions,\n\tISummaryRuntimeOptions,\n\tISummaryBaseConfiguration,\n\tISummaryConfigurationHeuristics,\n\tISummaryConfigurationDisableSummarizer,\n\tISummaryConfigurationDisableHeuristics,\n\tIContainerRuntimeOptions,\n\tIRootSummaryTreeWithStats,\n\tisRuntimeMessage,\n\tRuntimeMessage,\n\tagentSchedulerId,\n\tContainerRuntime,\n\tRuntimeHeaders,\n\tAllowTombstoneRequestHeaderKey,\n\tTombstoneResponseHeaderKey,\n\tISummaryConfiguration,\n\tDefaultSummaryConfiguration,\n\tICompressionRuntimeOptions,\n\tCompressionAlgorithms,\n} from \"./containerRuntime\";\nexport { FluidDataStoreRegistry } from \"./dataStoreRegistry\";\nexport { IGCStats } from \"./garbageCollection\";\nexport {\n\tIPendingFlush,\n\tIPendingLocalState,\n\tIPendingMessage,\n\tIPendingState,\n} from \"./pendingStateManager\";\nexport { Summarizer } from \"./summarizer\";\nexport {\n\tEnqueueSummarizeResult,\n\tIAckSummaryResult,\n\tIBaseSummarizeResult,\n\tIBroadcastSummaryResult,\n\tICancellationToken,\n\tIConnectableRuntime,\n\tIEnqueueSummarizeOptions,\n\tIGenerateSummaryTreeResult,\n\tIGeneratedSummaryStats,\n\tINackSummaryResult,\n\tIOnDemandSummarizeOptions,\n\tIProvideSummarizer,\n\tIRefreshSummaryAckOptions,\n\tISubmitSummaryOpResult,\n\tISubmitSummaryOptions,\n\tISummarizeOptions,\n\tISummarizeResults,\n\tISummarizer,\n\tISummarizerEvents,\n\tISummarizerInternalsProvider,\n\tISummarizerRuntime,\n\tISummarizingWarning,\n\tISummaryCancellationToken,\n\tIUploadSummaryResult,\n\tSubmitSummaryResult,\n\tSummarizeResultPart,\n\tSummarizerStopReason,\n} from \"./summarizerTypes\";\nexport {\n\tIAckedSummary,\n\tIClientSummaryWatcher,\n\tISummary,\n\tISummaryCollectionOpEvents,\n\tISummaryAckMessage,\n\tISummaryNackMessage,\n\tISummaryOpMessage,\n\tOpActionEventListener,\n\tOpActionEventName,\n\tSummaryCollection,\n} from \"./summaryCollection\";\nexport {\n\tICancellableSummarizerController,\n\tneverCancelledSummaryToken,\n} from \"./runWhileConnectedCoordinator\";\nexport { IChunkedOp, unpackRuntimeMessage } from \"./opLifecycle\";\n"]}
|
|
@@ -20,11 +20,11 @@ export declare class BatchManager {
|
|
|
20
20
|
private pendingBatch;
|
|
21
21
|
private batchContentSize;
|
|
22
22
|
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
* Track the number of ops which were detected to have a mismatched
|
|
24
|
+
* reference sequence number, in order to self-throttle the telemetry events.
|
|
25
|
+
*
|
|
26
|
+
* This should be removed as part of ADO:2322
|
|
27
|
+
*/
|
|
28
28
|
private readonly maxMismatchedOpsToReport;
|
|
29
29
|
private mismatchedOpsReported;
|
|
30
30
|
get length(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchManager.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,oBAAoB;
|
|
1
|
+
{"version":3,"file":"batchManager.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;CACzD;AAED;;GAEG;AACH,qBAAa,YAAY;aAoBI,OAAO,EAAE,oBAAoB;IAnBzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,gBAAgB,CAAK;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAK;IAC9C,OAAO,CAAC,qBAAqB,CAAK;IAElC,IAAW,MAAM,WAEhB;IACD,IAAW,kBAAkB,WAE5B;gBAE2B,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,gBAAgB;IAI5E,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAmC3C,IAAW,KAAK,YAEf;IAEM,QAAQ,IAAI,MAAM;IAYzB;;OAEG;IACI,UAAU,IAAI,gBAAgB;IAgBrC,OAAO,CAAC,4BAA4B;CAoCpC"}
|
|
@@ -13,17 +13,21 @@ export class BatchManager {
|
|
|
13
13
|
this.pendingBatch = [];
|
|
14
14
|
this.batchContentSize = 0;
|
|
15
15
|
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
* Track the number of ops which were detected to have a mismatched
|
|
17
|
+
* reference sequence number, in order to self-throttle the telemetry events.
|
|
18
|
+
*
|
|
19
|
+
* This should be removed as part of ADO:2322
|
|
20
|
+
*/
|
|
21
21
|
this.maxMismatchedOpsToReport = 5;
|
|
22
22
|
this.mismatchedOpsReported = 0;
|
|
23
23
|
this.logger = ChildLogger.create(logger, "BatchManager");
|
|
24
24
|
}
|
|
25
|
-
get length() {
|
|
26
|
-
|
|
25
|
+
get length() {
|
|
26
|
+
return this.pendingBatch.length;
|
|
27
|
+
}
|
|
28
|
+
get contentSizeInBytes() {
|
|
29
|
+
return this.batchContentSize;
|
|
30
|
+
}
|
|
27
31
|
push(message) {
|
|
28
32
|
var _a, _b;
|
|
29
33
|
this.checkReferenceSequenceNumber(message);
|
|
@@ -40,9 +44,9 @@ export class BatchManager {
|
|
|
40
44
|
// and start over. That's not an option if we have no ops.
|
|
41
45
|
// If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.
|
|
42
46
|
// Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.
|
|
43
|
-
if (this.options.softLimit !== undefined
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (this.options.softLimit !== undefined &&
|
|
48
|
+
this.length > 0 &&
|
|
49
|
+
socketMessageSize >= this.options.softLimit) {
|
|
46
50
|
return false;
|
|
47
51
|
}
|
|
48
52
|
if (socketMessageSize >= this.options.hardLimit) {
|
|
@@ -52,7 +56,9 @@ export class BatchManager {
|
|
|
52
56
|
this.pendingBatch.push(message);
|
|
53
57
|
return true;
|
|
54
58
|
}
|
|
55
|
-
get empty() {
|
|
59
|
+
get empty() {
|
|
60
|
+
return this.pendingBatch.length === 0;
|
|
61
|
+
}
|
|
56
62
|
popBatch() {
|
|
57
63
|
const batch = {
|
|
58
64
|
content: this.pendingBatch,
|
|
@@ -81,7 +87,8 @@ export class BatchManager {
|
|
|
81
87
|
};
|
|
82
88
|
}
|
|
83
89
|
checkReferenceSequenceNumber(message) {
|
|
84
|
-
if (this.pendingBatch.length === 0 ||
|
|
90
|
+
if (this.pendingBatch.length === 0 ||
|
|
91
|
+
message.referenceSequenceNumber === this.pendingBatch[0].referenceSequenceNumber) {
|
|
85
92
|
// The reference sequence numbers are stable
|
|
86
93
|
return;
|
|
87
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAW9D;;GAEG;AACH,MAAM,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { ICompressionRuntimeOptions } from \"../containerRuntime\";\nimport { BatchMessage, IBatch, IBatchCheckpoint } from \"./definitions\";\n\nexport interface IBatchManagerOptions {\n\treadonly enableOpReentryCheck?: boolean;\n\treadonly hardLimit: number;\n\treadonly softLimit?: number;\n\treadonly compressionOptions?: ICompressionRuntimeOptions;\n}\n\n/**\n * Helper class that manages partial batch & rollback.\n */\nexport class BatchManager {\n\tprivate readonly logger;\n\tprivate pendingBatch: BatchMessage[] = [];\n\tprivate batchContentSize = 0;\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 5;\n\tprivate mismatchedOpsReported = 0;\n\n\tpublic get length() {\n\t\treturn this.pendingBatch.length;\n\t}\n\tpublic get contentSizeInBytes() {\n\t\treturn this.batchContentSize;\n\t}\n\n\tconstructor(public readonly options: IBatchManagerOptions, logger: ITelemetryLogger) {\n\t\tthis.logger = ChildLogger.create(logger, \"BatchManager\");\n\t}\n\n\tpublic push(message: BatchMessage): boolean {\n\t\tthis.checkReferenceSequenceNumber(message);\n\n\t\tconst contentSize = this.batchContentSize + (message.contents?.length ?? 0);\n\t\tconst opCount = this.pendingBatch.length;\n\n\t\t// Attempt to estimate batch size, aka socket message size.\n\t\t// Each op has pretty large envelope, estimating to be 200 bytes.\n\t\t// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.\n\t\t// Not taking it into account, as compression work should help there - compressed payload will be\n\t\t// initially stored as base64, and that requires only 2 extra escape characters.\n\t\tconst socketMessageSize = contentSize + 200 * opCount;\n\n\t\t// If we were provided soft limit, check for exceeding it.\n\t\t// But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)\n\t\t// and start over. That's not an option if we have no ops.\n\t\t// If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.\n\t\t// Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.\n\t\tif (\n\t\t\tthis.options.softLimit !== undefined &&\n\t\t\tthis.length > 0 &&\n\t\t\tsocketMessageSize >= this.options.softLimit\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (socketMessageSize >= this.options.hardLimit) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.batchContentSize = contentSize;\n\t\tthis.pendingBatch.push(message);\n\t\treturn true;\n\t}\n\n\tpublic get empty() {\n\t\treturn this.pendingBatch.length === 0;\n\t}\n\n\tpublic popBatch(): IBatch {\n\t\tconst batch: IBatch = {\n\t\t\tcontent: this.pendingBatch,\n\t\t\tcontentSizeInBytes: this.batchContentSize,\n\t\t};\n\n\t\tthis.pendingBatch = [];\n\t\tthis.batchContentSize = 0;\n\n\t\treturn addBatchMetadata(batch);\n\t}\n\n\t/**\n\t * Capture the pending state at this point\n\t */\n\tpublic checkpoint(): IBatchCheckpoint {\n\t\tconst startPoint = this.pendingBatch.length;\n\t\treturn {\n\t\t\trollback: (process: (message: BatchMessage) => void) => {\n\t\t\t\tfor (let i = this.pendingBatch.length; i > startPoint; ) {\n\t\t\t\t\ti--;\n\t\t\t\t\tconst message = this.pendingBatch[i];\n\t\t\t\t\tthis.batchContentSize -= message.contents?.length ?? 0;\n\t\t\t\t\tprocess(message);\n\t\t\t\t}\n\n\t\t\t\tthis.pendingBatch.length = startPoint;\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate checkReferenceSequenceNumber(message: BatchMessage) {\n\t\tif (\n\t\t\tthis.pendingBatch.length === 0 ||\n\t\t\tmessage.referenceSequenceNumber === this.pendingBatch[0].referenceSequenceNumber\n\t\t) {\n\t\t\t// The reference sequence numbers are stable\n\t\t\treturn;\n\t\t}\n\n\t\tconst telemetryProperties = {\n\t\t\treferenceSequenceNumber: this.pendingBatch[0].referenceSequenceNumber,\n\t\t\tmessageReferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\ttype: message.deserializedContent.type,\n\t\t\tlength: this.pendingBatch.length,\n\t\t\tenableOpReentryCheck: this.options.enableOpReentryCheck === true,\n\t\t};\n\t\tconst error = new UsageError(\"Submission of an out of order message\");\n\t\tconst eventName = \"ReferenceSequenceNumberMismatch\";\n\n\t\tif (this.options.enableOpReentryCheck === true) {\n\t\t\tthis.logger.sendErrorEvent({ eventName, ...telemetryProperties }, error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName,\n\t\t\t\t\t...telemetryProperties,\n\t\t\t\t\tops: this.mismatchedOpsReported,\n\t\t\t\t\tmaxOps: this.maxMismatchedOpsToReport,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t}\n}\n\nconst addBatchMetadata = (batch: IBatch): IBatch => {\n\tif (batch.content.length > 1) {\n\t\tbatch.content[0].metadata = {\n\t\t\t...batch.content[0].metadata,\n\t\t\tbatch: true,\n\t\t};\n\t\tbatch.content[batch.content.length - 1].metadata = {\n\t\t\t...batch.content[batch.content.length - 1].metadata,\n\t\t\tbatch: false,\n\t\t};\n\t}\n\n\treturn batch;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,IAAI,CAAC;AAE1F;;GAEG;AACH,oBAAY,YAAY,GAAG,aAAa,GAAG;
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,IAAI,CAAC;AAE1F;;GAEG;AACH,oBAAY,YAAY,GAAG,aAAa,GAAG;IAC1C,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,MAAM;IACtB;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,KAAK,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,WAAW,GAAG,oBAAoB,CAAC;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,oBAAY,eAAe,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;IAC5C;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;CAChC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IBatchMessage } from \"@fluidframework/container-definitions\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport { CompressionAlgorithms, ContainerMessageType, ContainerRuntimeMessage } from \"..\";\n\n/**\n * Batch message type used internally by the runtime\n */\nexport type BatchMessage = IBatchMessage & {\n
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IBatchMessage } from \"@fluidframework/container-definitions\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport { CompressionAlgorithms, ContainerMessageType, ContainerRuntimeMessage } from \"..\";\n\n/**\n * Batch message type used internally by the runtime\n */\nexport type BatchMessage = IBatchMessage & {\n\tlocalOpMetadata: unknown;\n\tdeserializedContent: ContainerRuntimeMessage;\n\treferenceSequenceNumber: number;\n\tcompression?: CompressionAlgorithms;\n};\n\n/**\n * Batch interface used internally by the runtime.\n */\nexport interface IBatch {\n\t/**\n\t * Sum of the in-memory content sizes of all messages in the batch.\n\t * If the batch is compressed, this number reflects the post-compression size.\n\t */\n\treadonly contentSizeInBytes: number;\n\t/**\n\t * All the messages in the batch\n\t */\n\treadonly content: BatchMessage[];\n}\n\nexport interface IBatchCheckpoint {\n\trollback: (action: (message: BatchMessage) => void) => void;\n}\n\nexport interface IChunkedOp {\n\tchunkId: number;\n\ttotalChunks: number;\n\tcontents: string;\n\toriginalType: MessageType | ContainerMessageType;\n\toriginalMetadata?: Record<string, unknown>;\n\toriginalCompression?: string;\n}\n\n/**\n * The state of remote message processing:\n * `Processed` - the message can be considered processed\n * `Skipped` - the message was ignored by the processor\n * `Accepted` - the message was processed partially. Eventually, a message\n * will make the processor return `Processed`.\n */\nexport type ProcessingState = \"Processed\" | \"Skipped\" | \"Accepted\";\n\n/**\n * Return type for functions which process remote messages\n */\nexport interface IMessageProcessingResult {\n\t/**\n\t * A shallow copy of the input message if processing happened, or\n\t * the original message otherwise\n\t */\n\treadonly message: ISequencedDocumentMessage;\n\t/**\n\t * Processing result of the input message.\n\t */\n\treadonly state: ProcessingState;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACN,YAAY,EACZ,MAAM,EACN,gBAAgB,EAChB,UAAU,EACV,wBAAwB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { BatchManager } from \"./batchManager\";\nexport {\n
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { BatchManager } from \"./batchManager\";\nexport {\n\tBatchMessage,\n\tIBatch,\n\tIBatchCheckpoint,\n\tIChunkedOp,\n\tIMessageProcessingResult,\n} from \"./definitions\";\nexport { Outbox } from \"./outbox\";\nexport { OpCompressor } from \"./opCompressor\";\nexport { OpDecompressor } from \"./opDecompressor\";\nexport { OpSplitter, splitOp } from \"./opSplitter\";\nexport { RemoteMessageProcessor, unpackRuntimeMessage } from \"./remoteMessageProcessor\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAMtE,OAAO,EAAE,MAAM,EAAgB,MAAM,eAAe,CAAC;AAErD;;;;GAIG;AACH,qBAAa,YAAY;
|
|
1
|
+
{"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAMtE,OAAO,EAAE,MAAM,EAAgB,MAAM,eAAe,CAAC;AAErD;;;;GAIG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAEZ,MAAM,EAAE,gBAAgB;IAI7B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAkC3C,OAAO,CAAC,cAAc;CAsBtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opCompressor.js","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D;;;;GAIG;AACH,MAAM,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"opCompressor.js","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAG5D;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAGxB,YAAY,MAAwB;QACnC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1D,CAAC;IAEM,aAAa,CAAC,KAAa;QACjC,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,gBAAgB,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9E,MAAM,kBAAkB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACtD,MAAM,iBAAiB,GAAG,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;QAE/C,IAAI,KAAK,CAAC,kBAAkB,GAAG,MAAM,EAAE;YACtC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;gBAChC,SAAS,EAAE,iBAAiB;gBAC5B,QAAQ;gBACR,qBAAqB,EAAE,KAAK,CAAC,kBAAkB;gBAC/C,oBAAoB,EAAE,iBAAiB,CAAC,MAAM;aAC9C,CAAC,CAAC;SACH;QAED,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,QAAQ,CAAC,IAAI,iCACT,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KACnB,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC,EAC/D,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EACnC,WAAW,EAAE,qBAAqB,CAAC,GAAG,IACrC,CAAC;QAEH,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YAC7C,QAAQ,CAAC,IAAI,iCAAM,OAAO,KAAE,QAAQ,EAAE,SAAS,IAAG,CAAC;SACnD;QAED,OAAO;YACN,kBAAkB,EAAE,iBAAiB,CAAC,MAAM;YAC5C,OAAO,EAAE,QAAQ;SACjB,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,KAAa;QACnC,IAAI;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC;SACnF;QAAC,OAAO,CAAM,EAAE;YAChB,IAAI,CAAC,CAAC,OAAO,KAAK,uBAAuB,EAAE;gBAC1C,0CAA0C;gBAC1C,wCAAwC;gBACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,mBAAmB,CAAC,CAAC;gBAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CACzB;oBACC,SAAS,EAAE,eAAe;oBAC1B,IAAI,EAAE,KAAK,CAAC,kBAAkB;oBAC9B,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;iBAC5B,EACD,KAAK,CACL,CAAC;gBACF,MAAM,KAAK,CAAC;aACZ;YAED,MAAM,CAAC,CAAC;SACR;IACF,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IsoBuffer } from \"@fluidframework/common-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { compress } from \"lz4js\";\nimport { CompressionAlgorithms } from \"../containerRuntime\";\nimport { IBatch, BatchMessage } from \"./definitions\";\n\n/**\n * Compresses batches of ops. It generates a single compressed op that contains\n * the contents of each op in the batch. It then submits empty ops for each original\n * op to reserve sequence numbers.\n */\nexport class OpCompressor {\n\tprivate readonly logger;\n\n\tconstructor(logger: ITelemetryLogger) {\n\t\tthis.logger = ChildLogger.create(logger, \"OpCompressor\");\n\t}\n\n\tpublic compressBatch(batch: IBatch): IBatch {\n\t\tconst compressionStart = Date.now();\n\t\tconst contentsAsBuffer = new TextEncoder().encode(this.serializeBatch(batch));\n\t\tconst compressedContents = compress(contentsAsBuffer);\n\t\tconst compressedContent = IsoBuffer.from(compressedContents).toString(\"base64\");\n\t\tconst duration = Date.now() - compressionStart;\n\n\t\tif (batch.contentSizeInBytes > 200000) {\n\t\t\tthis.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"CompressedBatch\",\n\t\t\t\tduration,\n\t\t\t\tsizeBeforeCompression: batch.contentSizeInBytes,\n\t\t\t\tsizeAfterCompression: compressedContent.length,\n\t\t\t});\n\t\t}\n\n\t\tconst messages: BatchMessage[] = [];\n\t\tmessages.push({\n\t\t\t...batch.content[0],\n\t\t\tcontents: JSON.stringify({ packedContents: compressedContent }),\n\t\t\tmetadata: batch.content[0].metadata,\n\t\t\tcompression: CompressionAlgorithms.lz4,\n\t\t});\n\n\t\tfor (const message of batch.content.slice(1)) {\n\t\t\tmessages.push({ ...message, contents: undefined });\n\t\t}\n\n\t\treturn {\n\t\t\tcontentSizeInBytes: compressedContent.length,\n\t\t\tcontent: messages,\n\t\t};\n\t}\n\n\tprivate serializeBatch(batch: IBatch): string {\n\t\ttry {\n\t\t\treturn JSON.stringify(batch.content.map((message) => message.deserializedContent));\n\t\t} catch (e: any) {\n\t\t\tif (e.message === \"Invalid string length\") {\n\t\t\t\t// This is how JSON.stringify signals that\n\t\t\t\t// the content size exceeds its capacity\n\t\t\t\tconst error = new UsageError(\"Payload too large\");\n\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"BatchTooLarge\",\n\t\t\t\t\t\tsize: batch.contentSizeInBytes,\n\t\t\t\t\t\tlength: batch.content.length,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opDecompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opDecompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAGjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;;;;;GAOG;AACH,qBAAa,cAAc;
|
|
1
|
+
{"version":3,"file":"opDecompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opDecompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAGjF,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD;;;;;;;GAOG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,cAAc,CAAK;IAEpB,cAAc,CAAC,OAAO,EAAE,yBAAyB,GAAG,wBAAwB;CAwFnF"}
|
|
@@ -39,7 +39,9 @@ export class OpDecompressor {
|
|
|
39
39
|
state: "Accepted",
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
if (this.rootMessageContents !== undefined &&
|
|
42
|
+
if (this.rootMessageContents !== undefined &&
|
|
43
|
+
((_b = message.metadata) === null || _b === void 0 ? void 0 : _b.batch) === undefined &&
|
|
44
|
+
this.activeBatch) {
|
|
43
45
|
assert(message.contents === undefined, 0x512 /* Expecting empty message */);
|
|
44
46
|
// Continuation of compressed batch
|
|
45
47
|
return {
|
|
@@ -58,7 +60,8 @@ export class OpDecompressor {
|
|
|
58
60
|
state: "Processed",
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
|
-
if (((_d = message.metadata) === null || _d === void 0 ? void 0 : _d.batch) === undefined &&
|
|
63
|
+
if (((_d = message.metadata) === null || _d === void 0 ? void 0 : _d.batch) === undefined &&
|
|
64
|
+
message.compression === CompressionAlgorithms.lz4) {
|
|
62
65
|
// Single compressed message
|
|
63
66
|
assert(this.activeBatch === false, 0x4ba /* shouldn't receive compressed message in middle of a batch */);
|
|
64
67
|
const contents = IsoBuffer.from(message.contents.packedContents, "base64");
|