@fluidframework/container-runtime 2.0.0-dev.2.2.0.111723 → 2.0.0-dev.3.1.0.125672
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 +21 -10
- package/.mocharc.js +2 -2
- package/api-extractor.json +2 -2
- package/dist/batchTracker.d.ts +1 -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 +62 -28
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +256 -102
- 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 +110 -78
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +336 -331
- 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 +2 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +40 -23
- 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 +12 -9
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +69 -46
- 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 +57 -42
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +371 -239
- package/dist/garbageCollection.js.map +1 -1
- package/dist/garbageCollectionConstants.d.ts +23 -0
- package/dist/garbageCollectionConstants.d.ts.map +1 -0
- package/dist/garbageCollectionConstants.js +36 -0
- package/dist/garbageCollectionConstants.js.map +1 -0
- package/dist/garbageCollectionHelpers.d.ts +15 -0
- package/dist/garbageCollectionHelpers.d.ts.map +1 -0
- package/dist/garbageCollectionHelpers.js +27 -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 +15 -11
- package/dist/gcSweepReadyUsageDetection.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -6
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +42 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -0
- package/dist/opLifecycle/batchManager.js +124 -0
- package/dist/opLifecycle/batchManager.js.map +1 -0
- package/dist/opLifecycle/definitions.d.ts +64 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -0
- package/dist/opLifecycle/definitions.js +7 -0
- package/dist/opLifecycle/definitions.js.map +1 -0
- package/dist/opLifecycle/index.d.ts +12 -0
- package/dist/opLifecycle/index.d.ts.map +1 -0
- package/dist/opLifecycle/index.js +22 -0
- package/dist/opLifecycle/index.js.map +1 -0
- package/dist/{opCompressor.d.ts → opLifecycle/opCompressor.d.ts} +3 -3
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -0
- package/dist/opLifecycle/opCompressor.js +67 -0
- package/dist/opLifecycle/opCompressor.js.map +1 -0
- package/dist/{opDecompressor.d.ts → opLifecycle/opDecompressor.d.ts} +2 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -0
- package/dist/{opDecompressor.js → opLifecycle/opDecompressor.js} +37 -21
- package/dist/opLifecycle/opDecompressor.js.map +1 -0
- package/dist/opLifecycle/opSplitter.d.ts +49 -0
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -0
- package/dist/opLifecycle/opSplitter.js +173 -0
- package/dist/opLifecycle/opSplitter.js.map +1 -0
- package/dist/opLifecycle/outbox.d.ts +52 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -0
- package/dist/opLifecycle/outbox.js +164 -0
- package/dist/opLifecycle/outbox.js.map +1 -0
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +26 -0
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
- package/dist/opLifecycle/remoteMessageProcessor.js +96 -0
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -0
- 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 +4 -13
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +134 -161
- 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 -22
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/scheduleManager.d.ts +0 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +11 -21
- package/dist/scheduleManager.js.map +1 -1
- package/dist/serializedSnapshotStorage.d.ts.map +1 -1
- package/dist/serializedSnapshotStorage.js +3 -1
- package/dist/serializedSnapshotStorage.js.map +1 -1
- package/dist/summarizer.d.ts +2 -3
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +39 -18
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerClientElection.d.ts +1 -2
- package/dist/summarizerClientElection.d.ts.map +1 -1
- package/dist/summarizerClientElection.js +3 -30
- 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 +22 -25
- 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.map +1 -1
- package/dist/summaryFormat.js +18 -11
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryGenerator.d.ts.map +1 -1
- package/dist/summaryGenerator.js +32 -14
- 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 +1 -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 +62 -28
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +259 -105
- 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 +110 -78
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +340 -334
- 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 +2 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +41 -24
- 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 +12 -9
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +75 -52
- 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 +57 -42
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +364 -232
- package/lib/garbageCollection.js.map +1 -1
- package/lib/garbageCollectionConstants.d.ts +23 -0
- package/lib/garbageCollectionConstants.d.ts.map +1 -0
- package/lib/garbageCollectionConstants.js +33 -0
- package/lib/garbageCollectionConstants.js.map +1 -0
- package/lib/garbageCollectionHelpers.d.ts +15 -0
- package/lib/garbageCollectionHelpers.d.ts.map +1 -0
- package/lib/garbageCollectionHelpers.js +23 -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 +15 -11
- package/lib/gcSweepReadyUsageDetection.js.map +1 -1
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -3
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +42 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -0
- package/lib/opLifecycle/batchManager.js +120 -0
- package/lib/opLifecycle/batchManager.js.map +1 -0
- package/lib/opLifecycle/definitions.d.ts +64 -0
- package/lib/opLifecycle/definitions.d.ts.map +1 -0
- package/lib/opLifecycle/definitions.js +6 -0
- package/lib/opLifecycle/definitions.js.map +1 -0
- package/lib/opLifecycle/index.d.ts +12 -0
- package/lib/opLifecycle/index.d.ts.map +1 -0
- package/lib/opLifecycle/index.js +11 -0
- package/lib/opLifecycle/index.js.map +1 -0
- package/lib/{opCompressor.d.ts → opLifecycle/opCompressor.d.ts} +3 -3
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -0
- package/lib/opLifecycle/opCompressor.js +63 -0
- package/lib/opLifecycle/opCompressor.js.map +1 -0
- package/lib/{opDecompressor.d.ts → opLifecycle/opDecompressor.d.ts} +2 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -0
- package/lib/{opDecompressor.js → opLifecycle/opDecompressor.js} +37 -21
- package/lib/opLifecycle/opDecompressor.js.map +1 -0
- package/lib/opLifecycle/opSplitter.d.ts +49 -0
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -0
- package/lib/opLifecycle/opSplitter.js +168 -0
- package/lib/opLifecycle/opSplitter.js.map +1 -0
- package/lib/opLifecycle/outbox.d.ts +52 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -0
- package/lib/opLifecycle/outbox.js +160 -0
- package/lib/opLifecycle/outbox.js.map +1 -0
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +26 -0
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
- package/lib/opLifecycle/remoteMessageProcessor.js +91 -0
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -0
- 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 +4 -13
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +134 -161
- 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 -23
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/scheduleManager.d.ts +0 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +11 -21
- package/lib/scheduleManager.js.map +1 -1
- package/lib/serializedSnapshotStorage.d.ts.map +1 -1
- package/lib/serializedSnapshotStorage.js +3 -1
- package/lib/serializedSnapshotStorage.js.map +1 -1
- package/lib/summarizer.d.ts +2 -3
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +39 -18
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerClientElection.d.ts +1 -2
- package/lib/summarizerClientElection.d.ts.map +1 -1
- package/lib/summarizerClientElection.js +3 -30
- 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 +22 -25
- 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.map +1 -1
- package/lib/summaryFormat.js +20 -13
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryGenerator.d.ts.map +1 -1
- package/lib/summaryGenerator.js +32 -14
- 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 +28 -38
- package/prettier.config.cjs +1 -1
- package/src/batchTracker.ts +55 -50
- package/src/blobManager.ts +802 -541
- package/src/connectionTelemetry.ts +280 -249
- package/src/containerHandleContext.ts +27 -29
- package/src/containerRuntime.ts +3125 -2982
- package/src/dataStore.ts +172 -159
- package/src/dataStoreContext.ts +1049 -992
- package/src/dataStoreContexts.ts +178 -161
- package/src/dataStoreRegistry.ts +25 -20
- package/src/dataStores.ts +785 -711
- package/src/deltaScheduler.ts +158 -150
- package/src/garbageCollection.ts +1797 -1558
- package/src/garbageCollectionConstants.ts +38 -0
- package/src/garbageCollectionHelpers.ts +37 -0
- package/src/gcSweepReadyUsageDetection.ts +90 -84
- package/src/index.ts +68 -69
- package/src/opLifecycle/batchManager.ts +167 -0
- package/src/opLifecycle/definitions.ts +70 -0
- package/src/opLifecycle/index.ts +18 -0
- package/src/opLifecycle/opCompressor.ts +82 -0
- package/src/opLifecycle/opDecompressor.ts +124 -0
- package/src/opLifecycle/opSplitter.ts +238 -0
- package/src/opLifecycle/outbox.ts +228 -0
- package/src/opLifecycle/remoteMessageProcessor.ts +106 -0
- package/src/opProperties.ts +11 -9
- package/src/orderedClientElection.ts +489 -457
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +379 -381
- package/src/runWhileConnectedCoordinator.ts +78 -71
- package/src/runningSummarizer.ts +619 -582
- package/src/scheduleManager.ts +299 -280
- package/src/serializedSnapshotStorage.ts +116 -111
- package/src/summarizer.ts +417 -381
- package/src/summarizerClientElection.ts +107 -129
- package/src/summarizerHandle.ts +11 -9
- package/src/summarizerHeuristics.ts +183 -186
- package/src/summarizerTypes.ts +344 -333
- package/src/summaryCollection.ts +378 -349
- package/src/summaryFormat.ts +146 -127
- package/src/summaryGenerator.ts +464 -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/batchManager.d.ts +0 -42
- package/dist/batchManager.d.ts.map +0 -1
- package/dist/batchManager.js +0 -83
- package/dist/batchManager.js.map +0 -1
- package/dist/opCompressor.d.ts.map +0 -1
- package/dist/opCompressor.js +0 -50
- package/dist/opCompressor.js.map +0 -1
- package/dist/opDecompressor.d.ts.map +0 -1
- package/dist/opDecompressor.js.map +0 -1
- package/lib/batchManager.d.ts +0 -42
- package/lib/batchManager.d.ts.map +0 -1
- package/lib/batchManager.js +0 -79
- package/lib/batchManager.js.map +0 -1
- package/lib/opCompressor.d.ts.map +0 -1
- package/lib/opCompressor.js +0 -46
- package/lib/opCompressor.js.map +0 -1
- package/lib/opDecompressor.d.ts.map +0 -1
- package/lib/opDecompressor.js.map +0 -1
- package/src/batchManager.ts +0 -108
- package/src/opCompressor.ts +0 -59
- package/src/opDecompressor.ts +0 -82
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { GCVersion } from "./summaryFormat";
|
|
7
|
+
|
|
8
|
+
/** The stable version of garbage collection in production. */
|
|
9
|
+
export const stableGCVersion: GCVersion = 1;
|
|
10
|
+
/** The current version of garbage collection. */
|
|
11
|
+
export const currentGCVersion: GCVersion = 2;
|
|
12
|
+
|
|
13
|
+
// Feature gate key to turn GC on / off.
|
|
14
|
+
export const runGCKey = "Fluid.GarbageCollection.RunGC";
|
|
15
|
+
// Feature gate key to turn GC sweep on / off.
|
|
16
|
+
export const runSweepKey = "Fluid.GarbageCollection.RunSweep";
|
|
17
|
+
// Feature gate key to turn GC test mode on / off.
|
|
18
|
+
export const gcTestModeKey = "Fluid.GarbageCollection.GCTestMode";
|
|
19
|
+
// Feature gate key to expire a session after a set period of time.
|
|
20
|
+
export const runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
|
|
21
|
+
// Feature gate key to write the gc blob as a handle if the data is the same.
|
|
22
|
+
export const trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
|
|
23
|
+
// Feature gate key to turn GC sweep log off.
|
|
24
|
+
export const disableSweepLogKey = "Fluid.GarbageCollection.DisableSweepLog";
|
|
25
|
+
// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.
|
|
26
|
+
export const disableTombstoneKey = "Fluid.GarbageCollection.DisableTombstone";
|
|
27
|
+
// Feature gate to enable throwing an error when tombstone object is loaded (requested).
|
|
28
|
+
export const throwOnTombstoneLoadKey = "Fluid.GarbageCollection.ThrowOnTombstoneLoad";
|
|
29
|
+
// Feature gate to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops).
|
|
30
|
+
export const throwOnTombstoneUsageKey = "Fluid.GarbageCollection.ThrowOnTombstoneUsage";
|
|
31
|
+
// Feature gate to enable GC version upgrade.
|
|
32
|
+
export const gcVersionUpgradeToV2Key = "Fluid.GarbageCollection.GCVersionUpgradeToV2";
|
|
33
|
+
|
|
34
|
+
// One day in milliseconds.
|
|
35
|
+
export const oneDayMs = 1 * 24 * 60 * 60 * 1000;
|
|
36
|
+
|
|
37
|
+
export const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days
|
|
38
|
+
export const defaultSessionExpiryDurationMs = 30 * oneDayMs; // 30 days
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ITelemetryGenericEvent } from "@fluidframework/common-definitions";
|
|
7
|
+
import { packagePathToTelemetryProperty } from "@fluidframework/runtime-utils";
|
|
8
|
+
import { MonitoringContext } from "@fluidframework/telemetry-utils";
|
|
9
|
+
import {
|
|
10
|
+
disableTombstoneKey,
|
|
11
|
+
runSweepKey,
|
|
12
|
+
throwOnTombstoneLoadKey,
|
|
13
|
+
throwOnTombstoneUsageKey,
|
|
14
|
+
} from "./garbageCollectionConstants";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a
|
|
18
|
+
* tombstoned or deleted object is loaded.
|
|
19
|
+
*/
|
|
20
|
+
export function sendGCUnexpectedUsageEvent(
|
|
21
|
+
mc: MonitoringContext,
|
|
22
|
+
event: ITelemetryGenericEvent & { category: "error" | "generic"; isSummarizerClient: boolean },
|
|
23
|
+
packagePath: readonly string[] | undefined,
|
|
24
|
+
error?: unknown,
|
|
25
|
+
) {
|
|
26
|
+
event.pkg = packagePathToTelemetryProperty(packagePath);
|
|
27
|
+
event.tombstoneFlags = JSON.stringify({
|
|
28
|
+
DisableTombstone: mc.config.getBoolean(disableTombstoneKey),
|
|
29
|
+
ThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),
|
|
30
|
+
ThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),
|
|
31
|
+
});
|
|
32
|
+
event.sweepFlags = JSON.stringify({
|
|
33
|
+
EnableSweepFlag: mc.config.getBoolean(runSweepKey),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
mc.logger.sendTelemetryEvent(event, error);
|
|
37
|
+
}
|
|
@@ -6,41 +6,44 @@
|
|
|
6
6
|
import { ITelemetryProperties } from "@fluidframework/common-definitions";
|
|
7
7
|
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
IConfigProvider,
|
|
10
|
+
IFluidErrorBase,
|
|
11
|
+
LoggingError,
|
|
12
|
+
MonitoringContext,
|
|
13
13
|
} from "@fluidframework/telemetry-utils";
|
|
14
|
-
import { oneDayMs } from "./
|
|
14
|
+
import { oneDayMs } from "./garbageCollectionConstants";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Feature Gate Key -
|
|
18
18
|
* How many days between closing the container from this error (avoids locking user out of their file altogether)
|
|
19
19
|
*/
|
|
20
|
-
export const skipClosureForXDaysKey =
|
|
20
|
+
export const skipClosureForXDaysKey =
|
|
21
|
+
"Fluid.GarbageCollection.Dogfood.SweepReadyUsageDetection.SkipClosureForXDays";
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* LocalStorage key (NOT via feature gate / monitoring context)
|
|
24
25
|
* A map from docId to info about the last time we closed due to this error
|
|
25
26
|
*/
|
|
26
|
-
export const closuresMapLocalStorageKey =
|
|
27
|
+
export const closuresMapLocalStorageKey =
|
|
28
|
+
"Fluid.GarbageCollection.Dogfood.SweepReadyUsageDetection.Closures";
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* Feature gate key to enable closing the container if SweepReady objects are used.
|
|
30
32
|
* Value should contain keywords "interactiveClient" and/or "summarizer" to enable detection in each container type
|
|
31
33
|
*/
|
|
32
34
|
const sweepReadyUsageDetectionSetting = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
read(config: IConfigProvider) {
|
|
36
|
+
const sweepReadyUsageDetectionKey =
|
|
37
|
+
"Fluid.GarbageCollection.Dogfood.SweepReadyUsageDetection";
|
|
38
|
+
const value = config.getString(sweepReadyUsageDetectionKey);
|
|
39
|
+
if (value === undefined) {
|
|
40
|
+
return { interactiveClient: false, summarizer: false };
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
interactiveClient: value.includes("interactiveClient"),
|
|
44
|
+
summarizer: value.includes("summarizer"),
|
|
45
|
+
};
|
|
46
|
+
},
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
/**
|
|
@@ -52,8 +55,8 @@ const sweepReadyUsageDetectionSetting = {
|
|
|
52
55
|
* since only the Summarizer has the latest truth about unreferenced node tracking
|
|
53
56
|
*/
|
|
54
57
|
export class SweepReadyUsageError extends LoggingError implements IFluidErrorBase {
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
/** This errorType will be in temporary use (until Sweep is fully implemented) so don't add to any errorType type */
|
|
59
|
+
public errorType: string = "unreferencedObjectUsedAfterGarbageCollected";
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
/**
|
|
@@ -65,75 +68,78 @@ export class SweepReadyUsageError extends LoggingError implements IFluidErrorBas
|
|
|
65
68
|
* (via skipClosureForXDaysKey above. Uses localStorage and closuresMapLocalStorageKey to implement this behavior)
|
|
66
69
|
*/
|
|
67
70
|
export class SweepReadyUsageDetectionHandler {
|
|
68
|
-
|
|
71
|
+
private readonly localStorage: Pick<Storage, "getItem" | "setItem">;
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
constructor(
|
|
74
|
+
private readonly uniqueContainerKey: string,
|
|
75
|
+
private readonly mc: MonitoringContext,
|
|
76
|
+
private readonly closeFn: (error?: ICriticalContainerError) => void,
|
|
77
|
+
localStorageOverride?: Pick<Storage, "getItem" | "setItem">,
|
|
78
|
+
) {
|
|
79
|
+
const noopStorage = { getItem: () => null, setItem: () => {} };
|
|
80
|
+
// localStorage is not defined in Node environment, so fall back to noopStorage if needed.
|
|
81
|
+
this.localStorage = localStorageOverride ?? globalThis.localStorage ?? noopStorage;
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
if (this.localStorage === noopStorage) {
|
|
84
|
+
// This means the Skip Closure Period logic will not work.
|
|
85
|
+
this.mc.logger.sendTelemetryEvent({
|
|
86
|
+
eventName: "SweepReadyUsageDetectionHandlerNoopStorage",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
/**
|
|
92
|
+
* If SweepReady Usage Detection is enabled, close the interactive container.
|
|
93
|
+
* If the SkipClosureForXDays setting is set, don't close the container more than once in that period.
|
|
94
|
+
*
|
|
95
|
+
* Once Sweep is fully implemented, this will be removed since the objects will be gone
|
|
96
|
+
* and errors will arise elsewhere in the runtime
|
|
97
|
+
*/
|
|
98
|
+
public usageDetectedInInteractiveClient(errorProps: ITelemetryProperties) {
|
|
99
|
+
if (!sweepReadyUsageDetectionSetting.read(this.mc.config).interactiveClient) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
lastCloseTime = pastClosuresMap[this.uniqueContainerKey]?.lastCloseTime;
|
|
103
|
+
// Default stance is we close every time - this reflects the severity of SweepReady Object Usage.
|
|
104
|
+
// However, we may choose to "throttle" the closures by setting the SkipClosureForXDays setting,
|
|
105
|
+
// which will only allow the container to close once during that period, to avoid locking users out.
|
|
106
|
+
let shouldClose: boolean = true;
|
|
107
|
+
let pastClosuresMap: Record<string, { lastCloseTime: number } | undefined> = {};
|
|
108
|
+
let lastCloseTime: number | undefined;
|
|
109
|
+
const skipClosureForXDays = this.mc.config.getNumber(skipClosureForXDaysKey);
|
|
110
|
+
if (skipClosureForXDays !== undefined) {
|
|
111
|
+
// Read pastClosuresMap from localStorage then extract the lastCloseTime from the map
|
|
112
|
+
try {
|
|
113
|
+
const rawValue = this.localStorage.getItem(closuresMapLocalStorageKey);
|
|
114
|
+
const parsedValue = rawValue === null ? {} : JSON.parse(rawValue);
|
|
115
|
+
if (typeof parsedValue === "object") {
|
|
116
|
+
pastClosuresMap = parsedValue;
|
|
117
|
+
}
|
|
118
|
+
} catch (e) {}
|
|
119
|
+
lastCloseTime = pastClosuresMap[this.uniqueContainerKey]?.lastCloseTime;
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
// Don't close if we did already within the Skip Closure Period
|
|
122
|
+
if (
|
|
123
|
+
lastCloseTime !== undefined &&
|
|
124
|
+
Date.now() < lastCloseTime + skipClosureForXDays * oneDayMs
|
|
125
|
+
) {
|
|
126
|
+
shouldClose = false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
122
129
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.localStorage.setItem(closuresMapLocalStorageKey, JSON.stringify(pastClosuresMap));
|
|
130
|
+
const error = new SweepReadyUsageError("SweepReady object used in Non-Summarizer Client", {
|
|
131
|
+
errorDetails: JSON.stringify({ ...errorProps, lastCloseTime, skipClosureForXDays }),
|
|
132
|
+
});
|
|
133
|
+
if (shouldClose) {
|
|
134
|
+
// Update closures map in localStorage before closing
|
|
135
|
+
// Note there is a race condition between different tabs updating localStorage and overwriting
|
|
136
|
+
// each others' updates. If so, some tab will crash again. Just reload one at a time to get unstuck
|
|
137
|
+
pastClosuresMap[this.uniqueContainerKey] = { lastCloseTime: Date.now() };
|
|
138
|
+
this.localStorage.setItem(closuresMapLocalStorageKey, JSON.stringify(pastClosuresMap));
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
this.closeFn(error);
|
|
141
|
+
} else {
|
|
142
|
+
this.mc.logger.sendErrorEvent({ eventName: "SweepReadyObject_UsageAllowed" }, error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
139
145
|
}
|
package/src/index.ts
CHANGED
|
@@ -4,81 +4,80 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
export {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
7
|
+
ContainerMessageType,
|
|
8
|
+
ContainerRuntimeMessage,
|
|
9
|
+
IGCRuntimeOptions,
|
|
10
|
+
ISummaryRuntimeOptions,
|
|
11
|
+
ISummaryBaseConfiguration,
|
|
12
|
+
ISummaryConfigurationHeuristics,
|
|
13
|
+
ISummaryConfigurationDisableSummarizer,
|
|
14
|
+
ISummaryConfigurationDisableHeuristics,
|
|
15
|
+
IContainerRuntimeOptions,
|
|
16
|
+
IRootSummaryTreeWithStats,
|
|
17
|
+
isRuntimeMessage,
|
|
18
|
+
RuntimeMessage,
|
|
19
|
+
agentSchedulerId,
|
|
20
|
+
ContainerRuntime,
|
|
21
|
+
RuntimeHeaders,
|
|
22
|
+
AllowTombstoneRequestHeaderKey,
|
|
23
|
+
TombstoneResponseHeaderKey,
|
|
24
|
+
ISummaryConfiguration,
|
|
25
|
+
DefaultSummaryConfiguration,
|
|
26
|
+
ICompressionRuntimeOptions,
|
|
27
|
+
CompressionAlgorithms,
|
|
28
28
|
} from "./containerRuntime";
|
|
29
29
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
30
|
+
export { IGCStats } from "./garbageCollection";
|
|
30
31
|
export {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} from "./garbageCollection";
|
|
36
|
-
export {
|
|
37
|
-
IPendingFlush,
|
|
38
|
-
IPendingLocalState,
|
|
39
|
-
IPendingMessage,
|
|
40
|
-
IPendingState,
|
|
32
|
+
IPendingFlush,
|
|
33
|
+
IPendingLocalState,
|
|
34
|
+
IPendingMessage,
|
|
35
|
+
IPendingState,
|
|
41
36
|
} from "./pendingStateManager";
|
|
42
37
|
export { Summarizer } from "./summarizer";
|
|
43
38
|
export {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
39
|
+
EnqueueSummarizeResult,
|
|
40
|
+
IAckSummaryResult,
|
|
41
|
+
IBaseSummarizeResult,
|
|
42
|
+
IBroadcastSummaryResult,
|
|
43
|
+
ICancellationToken,
|
|
44
|
+
IConnectableRuntime,
|
|
45
|
+
IEnqueueSummarizeOptions,
|
|
46
|
+
IGenerateSummaryTreeResult,
|
|
47
|
+
IGeneratedSummaryStats,
|
|
48
|
+
INackSummaryResult,
|
|
49
|
+
IOnDemandSummarizeOptions,
|
|
50
|
+
IProvideSummarizer,
|
|
51
|
+
IRefreshSummaryAckOptions,
|
|
52
|
+
ISubmitSummaryOpResult,
|
|
53
|
+
ISubmitSummaryOptions,
|
|
54
|
+
ISummarizeOptions,
|
|
55
|
+
ISummarizeResults,
|
|
56
|
+
ISummarizer,
|
|
57
|
+
ISummarizerEvents,
|
|
58
|
+
ISummarizerInternalsProvider,
|
|
59
|
+
ISummarizerRuntime,
|
|
60
|
+
ISummarizingWarning,
|
|
61
|
+
ISummaryCancellationToken,
|
|
62
|
+
IUploadSummaryResult,
|
|
63
|
+
SubmitSummaryResult,
|
|
64
|
+
SummarizeResultPart,
|
|
65
|
+
SummarizerStopReason,
|
|
71
66
|
} from "./summarizerTypes";
|
|
72
67
|
export {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
68
|
+
IAckedSummary,
|
|
69
|
+
IClientSummaryWatcher,
|
|
70
|
+
ISummary,
|
|
71
|
+
ISummaryCollectionOpEvents,
|
|
72
|
+
ISummaryAckMessage,
|
|
73
|
+
ISummaryNackMessage,
|
|
74
|
+
ISummaryOpMessage,
|
|
75
|
+
OpActionEventListener,
|
|
76
|
+
OpActionEventName,
|
|
77
|
+
SummaryCollection,
|
|
83
78
|
} from "./summaryCollection";
|
|
84
|
-
export {
|
|
79
|
+
export {
|
|
80
|
+
ICancellableSummarizerController,
|
|
81
|
+
neverCancelledSummaryToken,
|
|
82
|
+
} from "./runWhileConnectedCoordinator";
|
|
83
|
+
export { IChunkedOp, unpackRuntimeMessage } from "./opLifecycle";
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
7
|
+
import { UsageError } from "@fluidframework/driver-utils";
|
|
8
|
+
import { ChildLogger } from "@fluidframework/telemetry-utils";
|
|
9
|
+
import { ICompressionRuntimeOptions } from "../containerRuntime";
|
|
10
|
+
import { BatchMessage, IBatch, IBatchCheckpoint } from "./definitions";
|
|
11
|
+
|
|
12
|
+
export interface IBatchManagerOptions {
|
|
13
|
+
readonly enableOpReentryCheck?: boolean;
|
|
14
|
+
readonly hardLimit: number;
|
|
15
|
+
readonly softLimit?: number;
|
|
16
|
+
readonly compressionOptions?: ICompressionRuntimeOptions;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Helper class that manages partial batch & rollback.
|
|
21
|
+
*/
|
|
22
|
+
export class BatchManager {
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private pendingBatch: BatchMessage[] = [];
|
|
25
|
+
private batchContentSize = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Track the number of ops which were detected to have a mismatched
|
|
28
|
+
* reference sequence number, in order to self-throttle the telemetry events.
|
|
29
|
+
*
|
|
30
|
+
* This should be removed as part of ADO:2322
|
|
31
|
+
*/
|
|
32
|
+
private readonly maxMismatchedOpsToReport = 5;
|
|
33
|
+
private mismatchedOpsReported = 0;
|
|
34
|
+
|
|
35
|
+
public get length() {
|
|
36
|
+
return this.pendingBatch.length;
|
|
37
|
+
}
|
|
38
|
+
public get contentSizeInBytes() {
|
|
39
|
+
return this.batchContentSize;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor(public readonly options: IBatchManagerOptions, logger: ITelemetryLogger) {
|
|
43
|
+
this.logger = ChildLogger.create(logger, "BatchManager");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public push(message: BatchMessage): boolean {
|
|
47
|
+
this.checkReferenceSequenceNumber(message);
|
|
48
|
+
|
|
49
|
+
const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
|
|
50
|
+
const opCount = this.pendingBatch.length;
|
|
51
|
+
|
|
52
|
+
// Attempt to estimate batch size, aka socket message size.
|
|
53
|
+
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
54
|
+
// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
|
|
55
|
+
// Not taking it into account, as compression work should help there - compressed payload will be
|
|
56
|
+
// initially stored as base64, and that requires only 2 extra escape characters.
|
|
57
|
+
const socketMessageSize = contentSize + 200 * opCount;
|
|
58
|
+
|
|
59
|
+
// If we were provided soft limit, check for exceeding it.
|
|
60
|
+
// But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)
|
|
61
|
+
// and start over. That's not an option if we have no ops.
|
|
62
|
+
// If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.
|
|
63
|
+
// Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.
|
|
64
|
+
if (
|
|
65
|
+
this.options.softLimit !== undefined &&
|
|
66
|
+
this.length > 0 &&
|
|
67
|
+
socketMessageSize >= this.options.softLimit
|
|
68
|
+
) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (socketMessageSize >= this.options.hardLimit) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.batchContentSize = contentSize;
|
|
77
|
+
this.pendingBatch.push(message);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public get empty() {
|
|
82
|
+
return this.pendingBatch.length === 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public popBatch(): IBatch {
|
|
86
|
+
const batch: IBatch = {
|
|
87
|
+
content: this.pendingBatch,
|
|
88
|
+
contentSizeInBytes: this.batchContentSize,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
this.pendingBatch = [];
|
|
92
|
+
this.batchContentSize = 0;
|
|
93
|
+
|
|
94
|
+
return addBatchMetadata(batch);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Capture the pending state at this point
|
|
99
|
+
*/
|
|
100
|
+
public checkpoint(): IBatchCheckpoint {
|
|
101
|
+
const startPoint = this.pendingBatch.length;
|
|
102
|
+
return {
|
|
103
|
+
rollback: (process: (message: BatchMessage) => void) => {
|
|
104
|
+
for (let i = this.pendingBatch.length; i > startPoint; ) {
|
|
105
|
+
i--;
|
|
106
|
+
const message = this.pendingBatch[i];
|
|
107
|
+
this.batchContentSize -= message.contents?.length ?? 0;
|
|
108
|
+
process(message);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this.pendingBatch.length = startPoint;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private checkReferenceSequenceNumber(message: BatchMessage) {
|
|
117
|
+
if (
|
|
118
|
+
this.pendingBatch.length === 0 ||
|
|
119
|
+
message.referenceSequenceNumber === this.pendingBatch[0].referenceSequenceNumber
|
|
120
|
+
) {
|
|
121
|
+
// The reference sequence numbers are stable
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const telemetryProperties = {
|
|
126
|
+
referenceSequenceNumber: this.pendingBatch[0].referenceSequenceNumber,
|
|
127
|
+
messageReferenceSequenceNumber: message.referenceSequenceNumber,
|
|
128
|
+
type: message.deserializedContent.type,
|
|
129
|
+
length: this.pendingBatch.length,
|
|
130
|
+
enableOpReentryCheck: this.options.enableOpReentryCheck === true,
|
|
131
|
+
};
|
|
132
|
+
const error = new UsageError("Submission of an out of order message");
|
|
133
|
+
const eventName = "ReferenceSequenceNumberMismatch";
|
|
134
|
+
|
|
135
|
+
if (this.options.enableOpReentryCheck === true) {
|
|
136
|
+
this.logger.sendErrorEvent({ eventName, ...telemetryProperties }, error);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {
|
|
141
|
+
this.logger.sendErrorEvent(
|
|
142
|
+
{
|
|
143
|
+
eventName,
|
|
144
|
+
...telemetryProperties,
|
|
145
|
+
ops: this.mismatchedOpsReported,
|
|
146
|
+
maxOps: this.maxMismatchedOpsToReport,
|
|
147
|
+
},
|
|
148
|
+
error,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const addBatchMetadata = (batch: IBatch): IBatch => {
|
|
155
|
+
if (batch.content.length > 1) {
|
|
156
|
+
batch.content[0].metadata = {
|
|
157
|
+
...batch.content[0].metadata,
|
|
158
|
+
batch: true,
|
|
159
|
+
};
|
|
160
|
+
batch.content[batch.content.length - 1].metadata = {
|
|
161
|
+
...batch.content[batch.content.length - 1].metadata,
|
|
162
|
+
batch: false,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return batch;
|
|
167
|
+
};
|