@fluidframework/container-runtime 2.0.0-internal.3.0.2 → 2.0.0-internal.3.2.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 +15 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +109 -37
- 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 +23 -11
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +225 -132
- 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 +27 -13
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +95 -56
- 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 +28 -4
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +122 -44
- 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 → gc/garbageCollection.d.ts} +27 -203
- package/dist/gc/garbageCollection.d.ts.map +1 -0
- package/dist/{garbageCollection.js → gc/garbageCollection.js} +210 -400
- package/dist/gc/garbageCollection.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +189 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -0
- package/dist/{garbageCollectionConstants.js → gc/gcDefinitions.js} +27 -2
- package/dist/gc/gcDefinitions.js.map +1 -0
- package/dist/gc/gcHelpers.d.ts +30 -0
- package/dist/gc/gcHelpers.d.ts.map +1 -0
- package/dist/gc/gcHelpers.js +65 -0
- package/dist/gc/gcHelpers.js.map +1 -0
- package/dist/gc/gcSummaryStateTracker.d.ts +86 -0
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/dist/gc/gcSummaryStateTracker.js +246 -0
- package/dist/gc/gcSummaryStateTracker.js.map +1 -0
- package/{lib → dist/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
- package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
- package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.js +94 -0
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
- package/dist/gc/index.d.ts +11 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +40 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -9
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +2 -13
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +19 -41
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +4 -0
- 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 +1 -0
- 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 +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +24 -13
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +19 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +78 -45
- 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/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +8 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +21 -13
- package/dist/pendingStateManager.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/summary/index.d.ts +17 -0
- package/dist/summary/index.d.ts.map +1 -0
- package/dist/summary/index.js +47 -0
- package/dist/summary/index.js.map +1 -0
- package/dist/summary/orderedClientElection.d.ts.map +1 -0
- package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
- package/dist/summary/orderedClientElection.js.map +1 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
- package/dist/summary/runningSummarizer.d.ts.map +1 -0
- package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -76
- package/dist/summary/runningSummarizer.js.map +1 -0
- package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
- package/dist/summary/summarizer.d.ts.map +1 -0
- package/dist/{summarizer.js → summary/summarizer.js} +31 -71
- package/dist/summary/summarizer.js.map +1 -0
- package/dist/summary/summarizerClientElection.d.ts.map +1 -0
- package/dist/summary/summarizerClientElection.js.map +1 -0
- package/dist/summary/summarizerHandle.d.ts.map +1 -0
- package/dist/summary/summarizerHandle.js.map +1 -0
- package/{lib → dist/summary}/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
- package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
- package/dist/summary/summarizerHeuristics.js.map +1 -0
- package/{lib → dist/summary}/summarizerTypes.d.ts +22 -22
- package/dist/summary/summarizerTypes.d.ts.map +1 -0
- package/dist/summary/summarizerTypes.js.map +1 -0
- package/dist/summary/summaryCollection.d.ts.map +1 -0
- package/dist/{summaryCollection.js → summary/summaryCollection.js} +18 -8
- package/dist/summary/summaryCollection.js.map +1 -0
- package/{lib → dist/summary}/summaryFormat.d.ts +1 -40
- package/dist/summary/summaryFormat.d.ts.map +1 -0
- package/dist/{summaryFormat.js → summary/summaryFormat.js} +19 -20
- package/dist/summary/summaryFormat.js.map +1 -0
- package/dist/summary/summaryGenerator.d.ts.map +1 -0
- package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
- package/dist/summary/summaryGenerator.js.map +1 -0
- package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -0
- package/dist/{summaryManager.js → summary/summaryManager.js} +21 -9
- package/dist/summary/summaryManager.js.map +1 -0
- 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/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 +15 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +109 -37
- 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 +23 -11
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +201 -108
- 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 +27 -13
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +84 -45
- 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 +28 -4
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +120 -42
- 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 → gc/garbageCollection.d.ts} +27 -203
- package/lib/gc/garbageCollection.d.ts.map +1 -0
- package/lib/{garbageCollection.js → gc/garbageCollection.js} +190 -379
- package/lib/gc/garbageCollection.js.map +1 -0
- package/lib/gc/gcDefinitions.d.ts +189 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -0
- package/lib/{garbageCollectionConstants.js → gc/gcDefinitions.js} +26 -1
- package/lib/gc/gcDefinitions.js.map +1 -0
- package/lib/gc/gcHelpers.d.ts +30 -0
- package/lib/gc/gcHelpers.d.ts.map +1 -0
- package/lib/gc/gcHelpers.js +58 -0
- package/lib/gc/gcHelpers.js.map +1 -0
- package/lib/gc/gcSummaryStateTracker.d.ts +86 -0
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/lib/gc/gcSummaryStateTracker.js +242 -0
- package/lib/gc/gcSummaryStateTracker.js.map +1 -0
- package/{dist → lib/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
- package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
- package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
- package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
- package/lib/gc/gcUnreferencedStateTracker.js +90 -0
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
- package/lib/gc/index.d.ts +11 -0
- package/lib/gc/index.d.ts.map +1 -0
- package/lib/gc/index.js +11 -0
- package/lib/gc/index.js.map +1 -0
- package/lib/index.d.ts +2 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -4
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +2 -13
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +19 -41
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +4 -0
- 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 +1 -0
- 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 +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +25 -14
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +19 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +79 -46
- 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/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +8 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +21 -13
- package/lib/pendingStateManager.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/summary/index.d.ts +17 -0
- package/lib/summary/index.d.ts.map +1 -0
- package/lib/summary/index.js +16 -0
- package/lib/summary/index.js.map +1 -0
- package/lib/summary/orderedClientElection.d.ts.map +1 -0
- package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
- package/lib/summary/orderedClientElection.js.map +1 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
- package/lib/summary/runningSummarizer.d.ts.map +1 -0
- package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +193 -78
- package/lib/summary/runningSummarizer.js.map +1 -0
- package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
- package/lib/summary/summarizer.d.ts.map +1 -0
- package/lib/{summarizer.js → summary/summarizer.js} +33 -73
- package/lib/summary/summarizer.js.map +1 -0
- package/lib/summary/summarizerClientElection.d.ts.map +1 -0
- package/lib/summary/summarizerClientElection.js.map +1 -0
- package/lib/summary/summarizerHandle.d.ts.map +1 -0
- package/lib/summary/summarizerHandle.js.map +1 -0
- package/{dist → lib/summary}/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
- package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
- package/lib/summary/summarizerHeuristics.js.map +1 -0
- package/{dist → lib/summary}/summarizerTypes.d.ts +22 -22
- package/lib/summary/summarizerTypes.d.ts.map +1 -0
- package/lib/summary/summarizerTypes.js.map +1 -0
- package/lib/summary/summaryCollection.d.ts.map +1 -0
- package/lib/{summaryCollection.js → summary/summaryCollection.js} +18 -8
- package/lib/summary/summaryCollection.js.map +1 -0
- package/{dist → lib/summary}/summaryFormat.d.ts +1 -40
- package/lib/summary/summaryFormat.d.ts.map +1 -0
- package/lib/{summaryFormat.js → summary/summaryFormat.js} +20 -20
- package/lib/summary/summaryFormat.js.map +1 -0
- package/lib/summary/summaryGenerator.d.ts.map +1 -0
- package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
- package/lib/summary/summaryGenerator.js.map +1 -0
- package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -0
- package/lib/{summaryManager.js → summary/summaryManager.js} +21 -9
- package/lib/summary/summaryManager.js.map +1 -0
- 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 +60 -51
- package/prettier.config.cjs +1 -1
- package/src/batchTracker.ts +54 -49
- package/src/blobManager.ts +825 -674
- package/src/connectionTelemetry.ts +280 -249
- package/src/containerHandleContext.ts +27 -29
- package/src/containerRuntime.ts +3249 -2978
- package/src/dataStore.ts +172 -159
- package/src/dataStoreContext.ts +1141 -1057
- package/src/dataStoreContexts.ts +178 -161
- package/src/dataStoreRegistry.ts +25 -20
- package/src/dataStores.ts +880 -731
- package/src/deltaScheduler.ts +158 -150
- package/{garbageCollection.md → src/gc/garbageCollection.md} +16 -3
- package/src/gc/garbageCollection.ts +1506 -0
- package/src/gc/gcDefinitions.ts +244 -0
- package/src/gc/gcHelpers.ts +86 -0
- package/src/gc/gcSummaryStateTracker.ts +339 -0
- package/src/gc/gcSweepReadyUsageDetection.ts +145 -0
- package/src/gc/gcUnreferencedStateTracker.ts +114 -0
- package/src/gc/index.ts +40 -0
- package/src/index.ts +67 -70
- package/src/opLifecycle/README.md +152 -0
- package/src/opLifecycle/batchManager.ts +101 -144
- package/src/opLifecycle/definitions.ts +33 -29
- package/src/opLifecycle/index.ts +5 -5
- package/src/opLifecycle/opCompressor.ts +55 -53
- package/src/opLifecycle/opDecompressor.ts +100 -81
- package/src/opLifecycle/opSplitter.ts +233 -188
- package/src/opLifecycle/outbox.ts +251 -195
- package/src/opLifecycle/remoteMessageProcessor.ts +62 -62
- package/src/opProperties.ts +11 -9
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +396 -338
- package/src/scheduleManager.ts +299 -269
- package/src/serializedSnapshotStorage.ts +126 -112
- package/src/summary/index.ts +99 -0
- package/src/summary/orderedClientElection.ts +564 -0
- package/src/summary/runWhileConnectedCoordinator.ts +113 -0
- package/src/summary/runningSummarizer.ts +788 -0
- package/src/summary/summarizer.ts +386 -0
- package/src/summary/summarizerClientElection.ts +139 -0
- package/src/{summarizerHandle.ts → summary/summarizerHandle.ts} +11 -9
- package/src/summary/summarizerHeuristics.ts +219 -0
- package/src/summary/summarizerTypes.ts +521 -0
- package/src/summary/summaryCollection.ts +450 -0
- package/src/summary/summaryFormat.ts +226 -0
- package/src/summary/summaryGenerator.ts +505 -0
- package/src/summary/summaryManager.ts +423 -0
- package/src/throttler.ts +131 -122
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
- package/dist/garbageCollection.d.ts.map +0 -1
- package/dist/garbageCollection.js.map +0 -1
- package/dist/garbageCollectionConstants.d.ts +0 -25
- package/dist/garbageCollectionConstants.d.ts.map +0 -1
- package/dist/garbageCollectionConstants.js.map +0 -1
- 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/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
- package/dist/gcSweepReadyUsageDetection.js.map +0 -1
- package/dist/orderedClientElection.d.ts.map +0 -1
- package/dist/orderedClientElection.js.map +0 -1
- package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/dist/runWhileConnectedCoordinator.js.map +0 -1
- package/dist/runningSummarizer.d.ts.map +0 -1
- package/dist/runningSummarizer.js.map +0 -1
- package/dist/summarizer.d.ts.map +0 -1
- package/dist/summarizer.js.map +0 -1
- package/dist/summarizerClientElection.d.ts.map +0 -1
- package/dist/summarizerClientElection.js.map +0 -1
- package/dist/summarizerHandle.d.ts.map +0 -1
- package/dist/summarizerHandle.js.map +0 -1
- package/dist/summarizerHeuristics.d.ts.map +0 -1
- package/dist/summarizerHeuristics.js.map +0 -1
- package/dist/summarizerTypes.d.ts.map +0 -1
- package/dist/summarizerTypes.js.map +0 -1
- package/dist/summaryCollection.d.ts.map +0 -1
- package/dist/summaryCollection.js.map +0 -1
- package/dist/summaryFormat.d.ts.map +0 -1
- package/dist/summaryFormat.js.map +0 -1
- package/dist/summaryGenerator.d.ts.map +0 -1
- package/dist/summaryGenerator.js.map +0 -1
- package/dist/summaryManager.d.ts.map +0 -1
- package/dist/summaryManager.js.map +0 -1
- package/lib/garbageCollection.d.ts.map +0 -1
- package/lib/garbageCollection.js.map +0 -1
- package/lib/garbageCollectionConstants.d.ts +0 -25
- package/lib/garbageCollectionConstants.d.ts.map +0 -1
- package/lib/garbageCollectionConstants.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/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
- package/lib/gcSweepReadyUsageDetection.js.map +0 -1
- package/lib/orderedClientElection.d.ts.map +0 -1
- package/lib/orderedClientElection.js.map +0 -1
- package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/lib/runWhileConnectedCoordinator.js.map +0 -1
- package/lib/runningSummarizer.d.ts.map +0 -1
- package/lib/runningSummarizer.js.map +0 -1
- package/lib/summarizer.d.ts.map +0 -1
- package/lib/summarizer.js.map +0 -1
- package/lib/summarizerClientElection.d.ts.map +0 -1
- package/lib/summarizerClientElection.js.map +0 -1
- package/lib/summarizerHandle.d.ts.map +0 -1
- package/lib/summarizerHandle.js.map +0 -1
- package/lib/summarizerHeuristics.d.ts.map +0 -1
- package/lib/summarizerHeuristics.js.map +0 -1
- package/lib/summarizerTypes.d.ts.map +0 -1
- package/lib/summarizerTypes.js.map +0 -1
- package/lib/summaryCollection.d.ts.map +0 -1
- package/lib/summaryCollection.js.map +0 -1
- package/lib/summaryFormat.d.ts.map +0 -1
- package/lib/summaryFormat.js.map +0 -1
- package/lib/summaryGenerator.d.ts.map +0 -1
- package/lib/summaryGenerator.js.map +0 -1
- package/lib/summaryManager.d.ts.map +0 -1
- package/lib/summaryManager.js.map +0 -1
- package/src/garbageCollection.ts +0 -1800
- package/src/garbageCollectionConstants.ts +0 -41
- package/src/garbageCollectionTombstoneUtils.ts +0 -28
- package/src/gcSweepReadyUsageDetection.ts +0 -139
- package/src/orderedClientElection.ts +0 -532
- package/src/runWhileConnectedCoordinator.ts +0 -106
- package/src/runningSummarizer.ts +0 -610
- package/src/summarizer.ts +0 -421
- package/src/summarizerClientElection.ts +0 -132
- package/src/summarizerHeuristics.ts +0 -222
- package/src/summarizerTypes.ts +0 -507
- package/src/summaryCollection.ts +0 -421
- package/src/summaryFormat.ts +0 -256
- package/src/summaryGenerator.ts +0 -450
- package/src/summaryManager.ts +0 -394
- /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
- /package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
- /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
- /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
- /package/dist/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
- /package/dist/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
- /package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
- /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
- /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
- /package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
- /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
- /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
- /package/lib/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
- /package/lib/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
- /package/lib/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
- /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
|
@@ -15,13 +15,15 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
15
15
|
};
|
|
16
16
|
import { assert, delay, Deferred, PromiseTimer } from "@fluidframework/common-utils";
|
|
17
17
|
import { UsageError } from "@fluidframework/container-utils";
|
|
18
|
+
import { DriverErrorType } from "@fluidframework/driver-definitions";
|
|
18
19
|
import { isRuntimeMessage } from "@fluidframework/driver-utils";
|
|
19
|
-
import { MessageType
|
|
20
|
-
import { ChildLogger } from "@fluidframework/telemetry-utils";
|
|
21
|
-
import { opSize } from "
|
|
20
|
+
import { MessageType } from "@fluidframework/protocol-definitions";
|
|
21
|
+
import { ChildLogger, isFluidError, loggerToMonitoringContext, } from "@fluidframework/telemetry-utils";
|
|
22
|
+
import { opSize } from "../opProperties";
|
|
22
23
|
import { SummarizeHeuristicRunner } from "./summarizerHeuristics";
|
|
23
24
|
import { raceTimer, SummarizeResultBuilder, SummaryGenerator, } from "./summaryGenerator";
|
|
24
25
|
const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
|
|
26
|
+
const defaultNumberSummarizationAttempts = 2; // only up to 2 attempts
|
|
25
27
|
/**
|
|
26
28
|
* An instance of RunningSummarizer manages the heuristics for summarizing.
|
|
27
29
|
* Until disposed, the instance of RunningSummarizer can assume that it is
|
|
@@ -30,10 +32,11 @@ const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
|
|
|
30
32
|
* This object is created and controlled by Summarizer object.
|
|
31
33
|
*/
|
|
32
34
|
export class RunningSummarizer {
|
|
33
|
-
constructor(baseLogger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
|
|
35
|
+
constructor(baseLogger, summaryWatcher, configuration, submitSummaryCallback, refreshLatestSummaryAckCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
|
|
34
36
|
this.summaryWatcher = summaryWatcher;
|
|
35
37
|
this.configuration = configuration;
|
|
36
38
|
this.submitSummaryCallback = submitSummaryCallback;
|
|
39
|
+
this.refreshLatestSummaryAckCallback = refreshLatestSummaryAckCallback;
|
|
37
40
|
this.heuristicData = heuristicData;
|
|
38
41
|
this.raiseSummarizingError = raiseSummarizingError;
|
|
39
42
|
this.summaryCollection = summaryCollection;
|
|
@@ -53,7 +56,7 @@ export class RunningSummarizer {
|
|
|
53
56
|
* @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct
|
|
54
57
|
*/
|
|
55
58
|
this.tryGetCorrelatedLogger = (summaryOpRefSeq) => this.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq
|
|
56
|
-
? this.logger
|
|
59
|
+
? this.mc.logger
|
|
57
60
|
: undefined;
|
|
58
61
|
/** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */
|
|
59
62
|
this.heuristicRunnerMicroTaskExists = false;
|
|
@@ -61,12 +64,12 @@ export class RunningSummarizer {
|
|
|
61
64
|
summarizeCount: () => this.summarizeCount,
|
|
62
65
|
summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,
|
|
63
66
|
};
|
|
64
|
-
this.
|
|
67
|
+
this.mc = loggerToMonitoringContext(ChildLogger.create(baseLogger, "Running", {
|
|
65
68
|
all: telemetryProps,
|
|
66
|
-
});
|
|
69
|
+
}));
|
|
67
70
|
if (configuration.state !== "disableHeuristics") {
|
|
68
71
|
assert(this.configuration.state === "enabled", 0x2ea /* "Configuration state should be enabled" */);
|
|
69
|
-
this.heuristicRunner = new SummarizeHeuristicRunner(heuristicData, this.configuration, (reason) => this.trySummarize(reason), this.logger);
|
|
72
|
+
this.heuristicRunner = new SummarizeHeuristicRunner(heuristicData, this.configuration, (reason) => this.trySummarize(reason), this.mc.logger);
|
|
70
73
|
}
|
|
71
74
|
assert(this.configuration.state !== "disabled", 0x2eb /* "Summary not supported with configuration disabled" */);
|
|
72
75
|
// Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime
|
|
@@ -78,7 +81,7 @@ export class RunningSummarizer {
|
|
|
78
81
|
// Note: summarizeCount (from ChildLogger definition) may be 0,
|
|
79
82
|
// since this code path is hit when RunningSummarizer first starts up,
|
|
80
83
|
// before this instance has kicked off a new summarize run.
|
|
81
|
-
this.logger.sendErrorEvent({
|
|
84
|
+
this.mc.logger.sendErrorEvent({
|
|
82
85
|
eventName: "SummaryAckWaitTimeout",
|
|
83
86
|
maxAckWaitTime,
|
|
84
87
|
referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,
|
|
@@ -89,7 +92,7 @@ export class RunningSummarizer {
|
|
|
89
92
|
// Set up pending ack timeout by op timestamp differences for previous summaries.
|
|
90
93
|
summaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {
|
|
91
94
|
if (this.pendingAckTimer.hasTimer) {
|
|
92
|
-
this.logger.sendTelemetryEvent({
|
|
95
|
+
this.mc.logger.sendTelemetryEvent({
|
|
93
96
|
eventName: "MissingSummaryAckFoundByOps",
|
|
94
97
|
referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,
|
|
95
98
|
summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,
|
|
@@ -97,23 +100,36 @@ export class RunningSummarizer {
|
|
|
97
100
|
this.pendingAckTimer.clear();
|
|
98
101
|
}
|
|
99
102
|
});
|
|
100
|
-
this.generator = new SummaryGenerator(this.pendingAckTimer, this.heuristicData, this.submitSummaryCallback, this.raiseSummarizingError, () => {
|
|
103
|
+
this.generator = new SummaryGenerator(this.pendingAckTimer, this.heuristicData, this.submitSummaryCallback, this.raiseSummarizingError, () => {
|
|
104
|
+
this.totalSuccessfulAttempts++;
|
|
105
|
+
}, this.summaryWatcher, this.mc.logger);
|
|
101
106
|
// Listen for ops
|
|
102
|
-
this.runtime.deltaManager.on("op", (op) => {
|
|
107
|
+
this.runtime.deltaManager.on("op", (op) => {
|
|
108
|
+
this.handleOp(op);
|
|
109
|
+
});
|
|
103
110
|
}
|
|
104
|
-
static async start(logger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
|
|
111
|
+
static async start(logger, summaryWatcher, configuration, submitSummaryCallback, refreshLatestSummaryAckCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
|
|
105
112
|
var _a, _b;
|
|
106
|
-
const summarizer = new RunningSummarizer(logger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime);
|
|
113
|
+
const summarizer = new RunningSummarizer(logger, summaryWatcher, configuration, submitSummaryCallback, refreshLatestSummaryAckCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime);
|
|
114
|
+
// Before doing any heuristics or proceeding with its refreshing, if there is a summary ack received while
|
|
115
|
+
// this summarizer catches up, let's refresh state before proceeding with the summarization.
|
|
116
|
+
const lastAckRefSeq = await summarizer.handleSummaryAck();
|
|
107
117
|
await summarizer.waitStart();
|
|
118
|
+
// Handle summary acks asynchronously
|
|
119
|
+
// Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions
|
|
120
|
+
summarizer.processIncomingSummaryAcks(lastAckRefSeq).catch((error) => {
|
|
121
|
+
logger.sendErrorEvent({ eventName: "HandleSummaryAckFatalError" }, error);
|
|
122
|
+
});
|
|
108
123
|
// Update heuristic counts
|
|
109
124
|
// By the time we get here, there are potentially ops missing from the heuristic summary counts
|
|
110
125
|
// Examples of where this could happen:
|
|
111
126
|
// 1. Op is processed during the time that we are initiating the RunningSummarizer instance but before we
|
|
112
127
|
// listen for the op events (will get missed by the handlers in the current workflow)
|
|
113
128
|
// 2. Op was sequenced after the last time we summarized (op sequence number > summarize ref sequence number)
|
|
114
|
-
const diff = runtime.deltaManager.lastSequenceNumber -
|
|
115
|
-
|
|
116
|
-
|
|
129
|
+
const diff = runtime.deltaManager.lastSequenceNumber -
|
|
130
|
+
(heuristicData.lastSuccessfulSummary.refSequenceNumber +
|
|
131
|
+
heuristicData.numNonRuntimeOps +
|
|
132
|
+
heuristicData.numRuntimeOps);
|
|
117
133
|
heuristicData.hasMissingOpData = diff > 0;
|
|
118
134
|
if (heuristicData.hasMissingOpData) {
|
|
119
135
|
// Split the diff 50-50 and increment the counts appropriately
|
|
@@ -127,10 +143,101 @@ export class RunningSummarizer {
|
|
|
127
143
|
(_b = summarizer.heuristicRunner) === null || _b === void 0 ? void 0 : _b.run();
|
|
128
144
|
return summarizer;
|
|
129
145
|
}
|
|
130
|
-
get disposed() {
|
|
146
|
+
get disposed() {
|
|
147
|
+
return this._disposed;
|
|
148
|
+
}
|
|
149
|
+
async handleSummaryAck() {
|
|
150
|
+
var _a, _b, _c, _d, _e;
|
|
151
|
+
const lastAck = this.summaryCollection.latestAck;
|
|
152
|
+
let refSequenceNumber = -1;
|
|
153
|
+
// In case we haven't received the lastestAck yet, just return.
|
|
154
|
+
if (lastAck !== undefined) {
|
|
155
|
+
refSequenceNumber = lastAck.summaryOp.referenceSequenceNumber;
|
|
156
|
+
const summaryLogger = (_a = this.tryGetCorrelatedLogger(refSequenceNumber)) !== null && _a !== void 0 ? _a : this.mc.logger;
|
|
157
|
+
try {
|
|
158
|
+
const summaryOpHandle = lastAck.summaryOp.contents.handle;
|
|
159
|
+
const summaryAckHandle = lastAck.summaryAck.contents.handle;
|
|
160
|
+
while (this.summarizingLock !== undefined) {
|
|
161
|
+
summaryLogger.sendTelemetryEvent({
|
|
162
|
+
eventName: "RefreshAttemptWithSummarizerRunning",
|
|
163
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
164
|
+
proposalHandle: summaryOpHandle,
|
|
165
|
+
ackHandle: summaryAckHandle,
|
|
166
|
+
});
|
|
167
|
+
await this.summarizingLock;
|
|
168
|
+
}
|
|
169
|
+
// Make sure we block any summarizer from being executed/enqueued while
|
|
170
|
+
// executing the refreshLatestSummaryAck.
|
|
171
|
+
// https://dev.azure.com/fluidframework/internal/_workitems/edit/779
|
|
172
|
+
await this.lockedSummaryAction(() => { }, async () => this.refreshLatestSummaryAckCallback({
|
|
173
|
+
proposalHandle: summaryOpHandle,
|
|
174
|
+
ackHandle: summaryAckHandle,
|
|
175
|
+
summaryRefSeq: refSequenceNumber,
|
|
176
|
+
summaryLogger,
|
|
177
|
+
}).catch(async (error) => {
|
|
178
|
+
// If the error is 404, so maybe the fetched version no longer exists on server. We just
|
|
179
|
+
// ignore this error in that case, as that means we will have another summaryAck for the
|
|
180
|
+
// latest version with which we will refresh the state. However in case of single commit
|
|
181
|
+
// summary, we might me missing a summary ack, so in that case we are still fine as the
|
|
182
|
+
// code in `submitSummary` function in container runtime, will refresh the latest state
|
|
183
|
+
// by calling `refreshLatestSummaryAckFromServer` and we will be fine.
|
|
184
|
+
if (isFluidError(error) &&
|
|
185
|
+
error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {
|
|
186
|
+
summaryLogger.sendTelemetryEvent({
|
|
187
|
+
eventName: "HandleSummaryAckErrorIgnored",
|
|
188
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
189
|
+
proposalHandle: summaryOpHandle,
|
|
190
|
+
ackHandle: summaryAckHandle,
|
|
191
|
+
}, error);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}), () => { });
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
summaryLogger.sendErrorEvent({
|
|
200
|
+
eventName: "HandleLastSummaryAckError",
|
|
201
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
202
|
+
handle: (_c = (_b = lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryOp) === null || _b === void 0 ? void 0 : _b.contents) === null || _c === void 0 ? void 0 : _c.handle,
|
|
203
|
+
ackHandle: (_e = (_d = lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck) === null || _d === void 0 ? void 0 : _d.contents) === null || _e === void 0 ? void 0 : _e.handle,
|
|
204
|
+
}, error);
|
|
205
|
+
}
|
|
206
|
+
refSequenceNumber++;
|
|
207
|
+
}
|
|
208
|
+
return refSequenceNumber;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Responsible for receiving and processing all the summaryAcks.
|
|
212
|
+
* In case there was a summary ack processed by the running summarizer before processIncomingSummaryAcks is called,
|
|
213
|
+
* it will wait for the summary ack that is newer than the one indicated by the lastAckRefSeq.
|
|
214
|
+
* @param lastAckRefSeq - Identifies the minimum reference sequence number the summarizer needs to wait for.
|
|
215
|
+
* In case of a negative number, the summarizer will wait for ANY summary ack that is greater than the deltaManager's initial sequence number,
|
|
216
|
+
* and, in case of a positive one, it will wait for a summary ack that is greater than this current reference sequence number.
|
|
217
|
+
*/
|
|
218
|
+
async processIncomingSummaryAcks(lastAckRefSeq) {
|
|
219
|
+
var _a;
|
|
220
|
+
let refSequenceNumber = lastAckRefSeq > 0 ? lastAckRefSeq : this.runtime.deltaManager.initialSequenceNumber;
|
|
221
|
+
while (!this.disposed) {
|
|
222
|
+
const summaryLogger = (_a = this.tryGetCorrelatedLogger(refSequenceNumber)) !== null && _a !== void 0 ? _a : this.mc.logger;
|
|
223
|
+
// Initialize ack with undefined if exception happens inside of waitSummaryAck on second iteration,
|
|
224
|
+
// we record undefined, not previous handles.
|
|
225
|
+
await this.summaryCollection.waitSummaryAck(refSequenceNumber);
|
|
226
|
+
summaryLogger.sendTelemetryEvent({
|
|
227
|
+
eventName: "processIncomingSummaryAcks",
|
|
228
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
229
|
+
lastAckRefSeq,
|
|
230
|
+
});
|
|
231
|
+
refSequenceNumber = await this.handleSummaryAck();
|
|
232
|
+
// A valid Summary Ack must have been processed.
|
|
233
|
+
assert(refSequenceNumber >= 0, 0x58f /* Invalid ref sequence number */);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
131
236
|
dispose() {
|
|
132
237
|
var _a;
|
|
133
|
-
this.runtime.deltaManager.off("op", (op) => {
|
|
238
|
+
this.runtime.deltaManager.off("op", (op) => {
|
|
239
|
+
this.handleOp(op);
|
|
240
|
+
});
|
|
134
241
|
this.summaryWatcher.dispose();
|
|
135
242
|
(_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
136
243
|
this.heuristicRunner = undefined;
|
|
@@ -150,15 +257,17 @@ export class RunningSummarizer {
|
|
|
150
257
|
}
|
|
151
258
|
this.heuristicData.totalOpsSize += opSize(op);
|
|
152
259
|
// Check for enqueued on-demand summaries; Intentionally do nothing otherwise
|
|
153
|
-
if (this.initialized
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
260
|
+
if (this.initialized &&
|
|
261
|
+
this.opCanTriggerSummary(op) &&
|
|
262
|
+
!this.tryRunEnqueuedSummary() &&
|
|
263
|
+
!this.heuristicRunnerMicroTaskExists) {
|
|
157
264
|
this.heuristicRunnerMicroTaskExists = true;
|
|
158
|
-
Promise.resolve()
|
|
265
|
+
Promise.resolve()
|
|
266
|
+
.then(() => {
|
|
159
267
|
var _a;
|
|
160
268
|
(_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
|
|
161
|
-
})
|
|
269
|
+
})
|
|
270
|
+
.finally(() => {
|
|
162
271
|
this.heuristicRunnerMicroTaskExists = false;
|
|
163
272
|
});
|
|
164
273
|
}
|
|
@@ -180,10 +289,11 @@ export class RunningSummarizer {
|
|
|
180
289
|
}
|
|
181
290
|
}
|
|
182
291
|
nonRuntimeOpCanTriggerSummary() {
|
|
183
|
-
const opsSinceLastAck = this.heuristicData.lastOpSequenceNumber -
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
292
|
+
const opsSinceLastAck = this.heuristicData.lastOpSequenceNumber -
|
|
293
|
+
this.heuristicData.lastSuccessfulSummary.refSequenceNumber;
|
|
294
|
+
return (this.configuration.state === "enabled" &&
|
|
295
|
+
(this.configuration.nonRuntimeHeuristicThreshold === undefined ||
|
|
296
|
+
this.configuration.nonRuntimeHeuristicThreshold <= opsSinceLastAck));
|
|
187
297
|
}
|
|
188
298
|
async waitStop(allowLastSummary) {
|
|
189
299
|
var _a;
|
|
@@ -226,52 +336,37 @@ export class RunningSummarizer {
|
|
|
226
336
|
}
|
|
227
337
|
this.initialized = true;
|
|
228
338
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
async lockedRefreshSummaryAckAction(action) {
|
|
242
|
-
assert(this.refreshSummaryAckLock === undefined, 0x396 /* Refresh Summary Ack - Caller is responsible for checking lock */);
|
|
243
|
-
const refreshSummaryAckLock = new Deferred();
|
|
244
|
-
this.refreshSummaryAckLock = refreshSummaryAckLock.promise;
|
|
245
|
-
return action().finally(() => {
|
|
246
|
-
refreshSummaryAckLock.resolve();
|
|
247
|
-
this.refreshSummaryAckLock = undefined;
|
|
248
|
-
});
|
|
339
|
+
beforeSummaryAction() {
|
|
340
|
+
this.summarizeCount++;
|
|
341
|
+
}
|
|
342
|
+
afterSummaryAction() {
|
|
343
|
+
var _a;
|
|
344
|
+
const retry = this.tryWhileSummarizing;
|
|
345
|
+
this.tryWhileSummarizing = false;
|
|
346
|
+
// After summarizing, we should check to see if we need to summarize again.
|
|
347
|
+
// Rerun the heuristics and check for enqueued summaries.
|
|
348
|
+
if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {
|
|
349
|
+
(_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
|
|
350
|
+
}
|
|
249
351
|
}
|
|
250
352
|
/**
|
|
251
353
|
* Runs single summary action that prevents any other concurrent actions.
|
|
252
354
|
* Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)
|
|
253
355
|
* before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.
|
|
356
|
+
* @param before - set of instructions to run before running the action.
|
|
254
357
|
* @param action - action to perform.
|
|
358
|
+
* @param after - set of instructions to run after running the action.
|
|
255
359
|
* @returns - result of action.
|
|
256
360
|
*/
|
|
257
|
-
async lockedSummaryAction(action) {
|
|
361
|
+
async lockedSummaryAction(before, action, after) {
|
|
258
362
|
assert(this.summarizingLock === undefined, 0x25b /* "Caller is responsible for checking lock" */);
|
|
259
363
|
const summarizingLock = new Deferred();
|
|
260
364
|
this.summarizingLock = summarizingLock.promise;
|
|
261
|
-
|
|
262
|
-
// Make sure the RefreshLatestSummaryAck is not being executed.
|
|
263
|
-
await this.refreshSummaryAckLock;
|
|
365
|
+
before();
|
|
264
366
|
return action().finally(() => {
|
|
265
|
-
var _a;
|
|
266
367
|
summarizingLock.resolve();
|
|
267
368
|
this.summarizingLock = undefined;
|
|
268
|
-
|
|
269
|
-
this.tryWhileSummarizing = false;
|
|
270
|
-
// After summarizing, we should check to see if we need to summarize again.
|
|
271
|
-
// Rerun the heuristics and check for enqueued summaries.
|
|
272
|
-
if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {
|
|
273
|
-
(_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
|
|
274
|
-
}
|
|
369
|
+
after();
|
|
275
370
|
});
|
|
276
371
|
}
|
|
277
372
|
/**
|
|
@@ -283,10 +378,14 @@ export class RunningSummarizer {
|
|
|
283
378
|
* @returns ISummarizeResult - result of running a summary.
|
|
284
379
|
*/
|
|
285
380
|
trySummarizeOnce(summarizeProps, options, cancellationToken = this.cancellationToken, resultsBuilder = new SummarizeResultBuilder()) {
|
|
286
|
-
this.lockedSummaryAction(
|
|
381
|
+
this.lockedSummaryAction(() => {
|
|
382
|
+
this.beforeSummaryAction();
|
|
383
|
+
}, async () => {
|
|
287
384
|
const summarizeResult = this.generator.summarize(summarizeProps, options, cancellationToken, resultsBuilder);
|
|
288
385
|
// ensure we wait till the end of the process
|
|
289
386
|
return summarizeResult.receivedSummaryAckOrNack;
|
|
387
|
+
}, () => {
|
|
388
|
+
this.afterSummaryAction();
|
|
290
389
|
}).catch((error) => {
|
|
291
390
|
// SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result
|
|
292
391
|
// on resultsBuilder
|
|
@@ -303,7 +402,10 @@ export class RunningSummarizer {
|
|
|
303
402
|
this.tryWhileSummarizing = true;
|
|
304
403
|
return;
|
|
305
404
|
}
|
|
306
|
-
this.lockedSummaryAction(
|
|
405
|
+
this.lockedSummaryAction(() => {
|
|
406
|
+
this.beforeSummaryAction();
|
|
407
|
+
}, async () => {
|
|
408
|
+
var _a;
|
|
307
409
|
const attempts = [
|
|
308
410
|
{ refreshLatestAck: false, fullTree: false },
|
|
309
411
|
{ refreshLatestAck: true, fullTree: false },
|
|
@@ -313,8 +415,20 @@ export class RunningSummarizer {
|
|
|
313
415
|
let overrideDelaySeconds;
|
|
314
416
|
let summaryAttempts = 0;
|
|
315
417
|
let summaryAttemptsPerPhase = 0;
|
|
418
|
+
// Reducing the default number of attempts to defaultNumberofSummarizationAttempts.
|
|
419
|
+
let totalAttempts = (_a = this.mc.config.getNumber("Fluid.Summarizer.Attempts")) !== null && _a !== void 0 ? _a : defaultNumberSummarizationAttempts;
|
|
420
|
+
if (totalAttempts > attempts.length) {
|
|
421
|
+
this.mc.logger.sendTelemetryEvent({
|
|
422
|
+
eventName: "InvalidSummarizerAttempts",
|
|
423
|
+
attempts: totalAttempts,
|
|
424
|
+
});
|
|
425
|
+
totalAttempts = defaultNumberSummarizationAttempts;
|
|
426
|
+
}
|
|
427
|
+
else if (totalAttempts < 1) {
|
|
428
|
+
throw new UsageError("Invalid number of attempts.");
|
|
429
|
+
}
|
|
316
430
|
let lastResult;
|
|
317
|
-
for (let summaryAttemptPhase = 0; summaryAttemptPhase <
|
|
431
|
+
for (let summaryAttemptPhase = 0; summaryAttemptPhase < totalAttempts;) {
|
|
318
432
|
if (this.cancellationToken.cancelled) {
|
|
319
433
|
return;
|
|
320
434
|
}
|
|
@@ -323,17 +437,10 @@ export class RunningSummarizer {
|
|
|
323
437
|
return;
|
|
324
438
|
}
|
|
325
439
|
summaryAttemptsPerPhase++;
|
|
326
|
-
const
|
|
327
|
-
const delaySeconds = overrideDelaySeconds !== null && overrideDelaySeconds !== void 0 ? overrideDelaySeconds : regularDelaySeconds;
|
|
440
|
+
const _b = attempts[summaryAttemptPhase], { delaySeconds: regularDelaySeconds = 0 } = _b, options = __rest(_b, ["delaySeconds"]);
|
|
328
441
|
const summarizeProps = Object.assign({ reason,
|
|
329
442
|
summaryAttempts,
|
|
330
443
|
summaryAttemptsPerPhase, summaryAttemptPhase: summaryAttemptPhase + 1 }, options);
|
|
331
|
-
if (delaySeconds > 0) {
|
|
332
|
-
this.logger.sendPerformanceEvent(Object.assign({ eventName: "SummarizeAttemptDelay", duration: delaySeconds, summaryNackDelay: overrideDelaySeconds !== undefined }, summarizeProps));
|
|
333
|
-
await delay(delaySeconds * 1000);
|
|
334
|
-
}
|
|
335
|
-
// Make sure the refresh Summary Ack is not being executed.
|
|
336
|
-
await this.refreshSummaryAckLock;
|
|
337
444
|
// Note: no need to account for cancellationToken.waitCancelled here, as
|
|
338
445
|
// this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.
|
|
339
446
|
const resultSummarize = this.generator.summarize(summarizeProps, options, cancellationToken);
|
|
@@ -349,16 +456,23 @@ export class RunningSummarizer {
|
|
|
349
456
|
summaryAttemptsPerPhase = 0;
|
|
350
457
|
}
|
|
351
458
|
lastResult = result;
|
|
459
|
+
const delaySeconds = overrideDelaySeconds !== null && overrideDelaySeconds !== void 0 ? overrideDelaySeconds : regularDelaySeconds;
|
|
460
|
+
if (delaySeconds > 0) {
|
|
461
|
+
this.mc.logger.sendPerformanceEvent(Object.assign({ eventName: "SummarizeAttemptDelay", duration: delaySeconds, summaryNackDelay: overrideDelaySeconds !== undefined }, summarizeProps));
|
|
462
|
+
await delay(delaySeconds * 1000);
|
|
463
|
+
}
|
|
352
464
|
}
|
|
353
465
|
// If all attempts failed, log error (with last attempt info) and close the summarizer container
|
|
354
|
-
this.logger.sendErrorEvent({
|
|
466
|
+
this.mc.logger.sendErrorEvent({
|
|
355
467
|
eventName: "FailToSummarize",
|
|
356
468
|
reason,
|
|
357
469
|
message: lastResult === null || lastResult === void 0 ? void 0 : lastResult.message,
|
|
358
470
|
}, lastResult === null || lastResult === void 0 ? void 0 : lastResult.error);
|
|
359
471
|
this.stopSummarizerCallback("failToSummarize");
|
|
472
|
+
}, () => {
|
|
473
|
+
this.afterSummaryAction();
|
|
360
474
|
}).catch((error) => {
|
|
361
|
-
this.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
|
|
475
|
+
this.mc.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
|
|
362
476
|
});
|
|
363
477
|
}
|
|
364
478
|
/** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */
|
|
@@ -399,16 +513,17 @@ export class RunningSummarizer {
|
|
|
399
513
|
};
|
|
400
514
|
const results = this.enqueuedSummary.resultsBuilder.build();
|
|
401
515
|
this.tryRunEnqueuedSummary();
|
|
402
|
-
return overridden
|
|
516
|
+
return overridden
|
|
517
|
+
? Object.assign(Object.assign({}, results), { alreadyEnqueued: true, overridden: true }) : results;
|
|
403
518
|
}
|
|
404
519
|
tryRunEnqueuedSummary() {
|
|
405
520
|
if (this.stopping) {
|
|
406
521
|
this.disposeEnqueuedSummary();
|
|
407
522
|
return false;
|
|
408
523
|
}
|
|
409
|
-
if (this.enqueuedSummary === undefined
|
|
410
|
-
|
|
411
|
-
|
|
524
|
+
if (this.enqueuedSummary === undefined ||
|
|
525
|
+
this.heuristicData.lastOpSequenceNumber < this.enqueuedSummary.afterSequenceNumber ||
|
|
526
|
+
this.summarizingLock !== undefined) {
|
|
412
527
|
// If no enqueued summary is ready or a summary is already in progress, take no action.
|
|
413
528
|
return false;
|
|
414
529
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runningSummarizer.js","sourceRoot":"","sources":["../../src/summary/runningSummarizer.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 { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay, Deferred, PromiseTimer } from \"@fluidframework/common-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { isRuntimeMessage } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tChildLogger,\n\tisFluidError,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport { ISummaryConfiguration } from \"../containerRuntime\";\nimport { opSize } from \"../opProperties\";\nimport { SummarizeHeuristicRunner } from \"./summarizerHeuristics\";\nimport {\n\tIEnqueueSummarizeOptions,\n\tISummarizeOptions,\n\tISummarizeHeuristicData,\n\tISummarizeHeuristicRunner,\n\tIOnDemandSummarizeOptions,\n\tEnqueueSummarizeResult,\n\tSummarizerStopReason,\n\tISubmitSummaryOptions,\n\tSubmitSummaryResult,\n\tISummaryCancellationToken,\n\tISummarizeResults,\n\tISummarizeTelemetryProperties,\n\tISummarizerRuntime,\n\tISummarizeRunnerTelemetry,\n\tIRefreshSummaryAckOptions,\n} from \"./summarizerTypes\";\nimport { IAckedSummary, IClientSummaryWatcher, SummaryCollection } from \"./summaryCollection\";\nimport {\n\traceTimer,\n\tSummarizeReason,\n\tSummarizeResultBuilder,\n\tSummaryGenerator,\n} from \"./summaryGenerator\";\n\nconst maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes\n\nconst defaultNumberSummarizationAttempts = 2; // only up to 2 attempts\n/**\n * An instance of RunningSummarizer manages the heuristics for summarizing.\n * Until disposed, the instance of RunningSummarizer can assume that it is\n * in a state of running, meaning it is connected and initialized. It keeps\n * track of summaries that it is generating as they are broadcast and acked/nacked.\n * This object is created and controlled by Summarizer object.\n */\nexport class RunningSummarizer implements IDisposable {\n\tpublic static async start(\n\t\tlogger: ITelemetryLogger,\n\t\tsummaryWatcher: IClientSummaryWatcher,\n\t\tconfiguration: ISummaryConfiguration,\n\t\tsubmitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n\t\trefreshLatestSummaryAckCallback: (options: IRefreshSummaryAckOptions) => Promise<void>,\n\t\theuristicData: ISummarizeHeuristicData,\n\t\traiseSummarizingError: (errorMessage: string) => void,\n\t\tsummaryCollection: SummaryCollection,\n\t\tcancellationToken: ISummaryCancellationToken,\n\t\tstopSummarizerCallback: (reason: SummarizerStopReason) => void,\n\t\truntime: ISummarizerRuntime,\n\t): Promise<RunningSummarizer> {\n\t\tconst summarizer = new RunningSummarizer(\n\t\t\tlogger,\n\t\t\tsummaryWatcher,\n\t\t\tconfiguration,\n\t\t\tsubmitSummaryCallback,\n\t\t\trefreshLatestSummaryAckCallback,\n\t\t\theuristicData,\n\t\t\traiseSummarizingError,\n\t\t\tsummaryCollection,\n\t\t\tcancellationToken,\n\t\t\tstopSummarizerCallback,\n\t\t\truntime,\n\t\t);\n\n\t\t// Before doing any heuristics or proceeding with its refreshing, if there is a summary ack received while\n\t\t// this summarizer catches up, let's refresh state before proceeding with the summarization.\n\t\tconst lastAckRefSeq = await summarizer.handleSummaryAck();\n\n\t\tawait summarizer.waitStart();\n\n\t\t// Handle summary acks asynchronously\n\t\t// Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions\n\t\tsummarizer.processIncomingSummaryAcks(lastAckRefSeq).catch((error) => {\n\t\t\tlogger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n\t\t});\n\n\t\t// Update heuristic counts\n\t\t// By the time we get here, there are potentially ops missing from the heuristic summary counts\n\t\t// Examples of where this could happen:\n\t\t// 1. Op is processed during the time that we are initiating the RunningSummarizer instance but before we\n\t\t// listen for the op events (will get missed by the handlers in the current workflow)\n\t\t// 2. Op was sequenced after the last time we summarized (op sequence number > summarize ref sequence number)\n\t\tconst diff =\n\t\t\truntime.deltaManager.lastSequenceNumber -\n\t\t\t(heuristicData.lastSuccessfulSummary.refSequenceNumber +\n\t\t\t\theuristicData.numNonRuntimeOps +\n\t\t\t\theuristicData.numRuntimeOps);\n\t\theuristicData.hasMissingOpData = diff > 0;\n\n\t\tif (heuristicData.hasMissingOpData) {\n\t\t\t// Split the diff 50-50 and increment the counts appropriately\n\t\t\theuristicData.numNonRuntimeOps += Math.ceil(diff / 2);\n\t\t\theuristicData.numRuntimeOps += Math.floor(diff / 2);\n\t\t}\n\n\t\t// Update last seq number (in case the handlers haven't processed anything yet)\n\t\theuristicData.lastOpSequenceNumber = runtime.deltaManager.lastSequenceNumber;\n\n\t\t// Start heuristics\n\t\tsummarizer.heuristicRunner?.start();\n\t\tsummarizer.heuristicRunner?.run();\n\n\t\treturn summarizer;\n\t}\n\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tprivate stopping = false;\n\tprivate _disposed = false;\n\tprivate summarizingLock: Promise<void> | undefined;\n\tprivate tryWhileSummarizing = false;\n\tprivate readonly pendingAckTimer: PromiseTimer;\n\tprivate heuristicRunner?: ISummarizeHeuristicRunner;\n\tprivate readonly generator: SummaryGenerator;\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate enqueuedSummary:\n\t\t| {\n\t\t\t\treason: SummarizeReason;\n\t\t\t\tafterSequenceNumber: number;\n\t\t\t\toptions: ISummarizeOptions;\n\t\t\t\treadonly resultsBuilder: SummarizeResultBuilder;\n\t\t }\n\t\t| undefined;\n\tprivate summarizeCount = 0;\n\tprivate totalSuccessfulAttempts = 0;\n\tprivate initialized = false;\n\n\tprivate constructor(\n\t\tbaseLogger: ITelemetryLogger,\n\t\tprivate readonly summaryWatcher: IClientSummaryWatcher,\n\t\tprivate readonly configuration: ISummaryConfiguration,\n\t\tprivate readonly submitSummaryCallback: (\n\t\t\toptions: ISubmitSummaryOptions,\n\t\t) => Promise<SubmitSummaryResult>,\n\t\tprivate readonly refreshLatestSummaryAckCallback: (\n\t\t\toptions: IRefreshSummaryAckOptions,\n\t\t) => Promise<void>,\n\t\tprivate readonly heuristicData: ISummarizeHeuristicData,\n\t\tprivate readonly raiseSummarizingError: (errorMessage: string) => void,\n\t\tprivate readonly summaryCollection: SummaryCollection,\n\t\tprivate readonly cancellationToken: ISummaryCancellationToken,\n\t\tprivate readonly stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n\t\tprivate readonly runtime: ISummarizerRuntime,\n\t) {\n\t\tconst telemetryProps: ISummarizeRunnerTelemetry = {\n\t\t\tsummarizeCount: () => this.summarizeCount,\n\t\t\tsummarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,\n\t\t};\n\n\t\tthis.mc = loggerToMonitoringContext(\n\t\t\tChildLogger.create(baseLogger, \"Running\", {\n\t\t\t\tall: telemetryProps,\n\t\t\t}),\n\t\t);\n\n\t\tif (configuration.state !== \"disableHeuristics\") {\n\t\t\tassert(\n\t\t\t\tthis.configuration.state === \"enabled\",\n\t\t\t\t0x2ea /* \"Configuration state should be enabled\" */,\n\t\t\t);\n\t\t\tthis.heuristicRunner = new SummarizeHeuristicRunner(\n\t\t\t\theuristicData,\n\t\t\t\tthis.configuration,\n\t\t\t\t(reason) => this.trySummarize(reason),\n\t\t\t\tthis.mc.logger,\n\t\t\t);\n\t\t}\n\n\t\tassert(\n\t\t\tthis.configuration.state !== \"disabled\",\n\t\t\t0x2eb /* \"Summary not supported with configuration disabled\" */,\n\t\t);\n\n\t\t// Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime\n\t\t// configuration.maxAckWaitTime is composed from defaults, server values, and runtime overrides\n\n\t\tconst maxAckWaitTime = Math.min(this.configuration.maxAckWaitTime, maxSummarizeAckWaitTime);\n\n\t\tthis.pendingAckTimer = new PromiseTimer(maxAckWaitTime, () => {\n\t\t\t// pre-0.58 error message: summaryAckWaitTimeout\n\t\t\tthis.raiseSummarizingError(\"Pending summary ack not received in time\");\n\t\t\t// Note: summarizeCount (from ChildLogger definition) may be 0,\n\t\t\t// since this code path is hit when RunningSummarizer first starts up,\n\t\t\t// before this instance has kicked off a new summarize run.\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"SummaryAckWaitTimeout\",\n\t\t\t\tmaxAckWaitTime,\n\t\t\t\treferenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n\t\t\t\tsummarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n\t\t\t\ttimePending: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n\t\t\t});\n\t\t});\n\t\t// Set up pending ack timeout by op timestamp differences for previous summaries.\n\t\tsummaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {\n\t\t\tif (this.pendingAckTimer.hasTimer) {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"MissingSummaryAckFoundByOps\",\n\t\t\t\t\treferenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n\t\t\t\t\tsummarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n\t\t\t\t});\n\t\t\t\tthis.pendingAckTimer.clear();\n\t\t\t}\n\t\t});\n\n\t\tthis.generator = new SummaryGenerator(\n\t\t\tthis.pendingAckTimer,\n\t\t\tthis.heuristicData,\n\t\t\tthis.submitSummaryCallback,\n\t\t\tthis.raiseSummarizingError,\n\t\t\t() => {\n\t\t\t\tthis.totalSuccessfulAttempts++;\n\t\t\t},\n\t\t\tthis.summaryWatcher,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// Listen for ops\n\t\tthis.runtime.deltaManager.on(\"op\", (op) => {\n\t\t\tthis.handleOp(op);\n\t\t});\n\t}\n\n\tprivate async handleSummaryAck(): Promise<number> {\n\t\tconst lastAck: IAckedSummary | undefined = this.summaryCollection.latestAck;\n\t\tlet refSequenceNumber = -1;\n\t\t// In case we haven't received the lastestAck yet, just return.\n\t\tif (lastAck !== undefined) {\n\t\t\trefSequenceNumber = lastAck.summaryOp.referenceSequenceNumber;\n\t\t\tconst summaryLogger = this.tryGetCorrelatedLogger(refSequenceNumber) ?? this.mc.logger;\n\t\t\ttry {\n\t\t\t\tconst summaryOpHandle = lastAck.summaryOp.contents.handle;\n\t\t\t\tconst summaryAckHandle = lastAck.summaryAck.contents.handle;\n\t\t\t\twhile (this.summarizingLock !== undefined) {\n\t\t\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"RefreshAttemptWithSummarizerRunning\",\n\t\t\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\t});\n\t\t\t\t\tawait this.summarizingLock;\n\t\t\t\t}\n\n\t\t\t\t// Make sure we block any summarizer from being executed/enqueued while\n\t\t\t\t// executing the refreshLatestSummaryAck.\n\t\t\t\t// https://dev.azure.com/fluidframework/internal/_workitems/edit/779\n\t\t\t\tawait this.lockedSummaryAction(\n\t\t\t\t\t() => {},\n\t\t\t\t\tasync () =>\n\t\t\t\t\t\tthis.refreshLatestSummaryAckCallback({\n\t\t\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\t\t\tsummaryRefSeq: refSequenceNumber,\n\t\t\t\t\t\t\tsummaryLogger,\n\t\t\t\t\t\t}).catch(async (error) => {\n\t\t\t\t\t\t\t// If the error is 404, so maybe the fetched version no longer exists on server. We just\n\t\t\t\t\t\t\t// ignore this error in that case, as that means we will have another summaryAck for the\n\t\t\t\t\t\t\t// latest version with which we will refresh the state. However in case of single commit\n\t\t\t\t\t\t\t// summary, we might me missing a summary ack, so in that case we are still fine as the\n\t\t\t\t\t\t\t// code in `submitSummary` function in container runtime, will refresh the latest state\n\t\t\t\t\t\t\t// by calling `refreshLatestSummaryAckFromServer` and we will be fine.\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tisFluidError(error) &&\n\t\t\t\t\t\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tsummaryLogger.sendTelemetryEvent(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\teventName: \"HandleSummaryAckErrorIgnored\",\n\t\t\t\t\t\t\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\t\t\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\t\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}),\n\t\t\t\t\t() => {},\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tsummaryLogger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"HandleLastSummaryAckError\",\n\t\t\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\t\t\thandle: lastAck?.summaryOp?.contents?.handle,\n\t\t\t\t\t\tackHandle: lastAck?.summaryAck?.contents?.handle,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\trefSequenceNumber++;\n\t\t}\n\t\treturn refSequenceNumber;\n\t}\n\n\t/**\n\t * Responsible for receiving and processing all the summaryAcks.\n\t * In case there was a summary ack processed by the running summarizer before processIncomingSummaryAcks is called,\n\t * it will wait for the summary ack that is newer than the one indicated by the lastAckRefSeq.\n\t * @param lastAckRefSeq - Identifies the minimum reference sequence number the summarizer needs to wait for.\n\t * In case of a negative number, the summarizer will wait for ANY summary ack that is greater than the deltaManager's initial sequence number,\n\t * and, in case of a positive one, it will wait for a summary ack that is greater than this current reference sequence number.\n\t */\n\tprivate async processIncomingSummaryAcks(lastAckRefSeq: number) {\n\t\tlet refSequenceNumber =\n\t\t\tlastAckRefSeq > 0 ? lastAckRefSeq : this.runtime.deltaManager.initialSequenceNumber;\n\t\twhile (!this.disposed) {\n\t\t\tconst summaryLogger = this.tryGetCorrelatedLogger(refSequenceNumber) ?? this.mc.logger;\n\n\t\t\t// Initialize ack with undefined if exception happens inside of waitSummaryAck on second iteration,\n\t\t\t// we record undefined, not previous handles.\n\t\t\tawait this.summaryCollection.waitSummaryAck(refSequenceNumber);\n\n\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"processIncomingSummaryAcks\",\n\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\tlastAckRefSeq,\n\t\t\t});\n\n\t\t\trefSequenceNumber = await this.handleSummaryAck();\n\t\t\t// A valid Summary Ack must have been processed.\n\t\t\tassert(refSequenceNumber >= 0, 0x58f /* Invalid ref sequence number */);\n\t\t}\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.runtime.deltaManager.off(\"op\", (op) => {\n\t\t\tthis.handleOp(op);\n\t\t});\n\t\tthis.summaryWatcher.dispose();\n\t\tthis.heuristicRunner?.dispose();\n\t\tthis.heuristicRunner = undefined;\n\t\tthis.generator.dispose();\n\t\tthis.pendingAckTimer.clear();\n\t\tthis.disposeEnqueuedSummary();\n\t\tthis._disposed = true;\n\t\tthis.stopping = true;\n\t}\n\n\t/**\n\t * RunningSummarizer's logger includes the sequenced index of the current summary on each event.\n\t * If some other Summarizer code wants that event on their logs they can get it here,\n\t * but only if they're logging about that same summary.\n\t * @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct\n\t */\n\tpublic tryGetCorrelatedLogger = (summaryOpRefSeq) =>\n\t\tthis.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq\n\t\t\t? this.mc.logger\n\t\t\t: undefined;\n\n\t/** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */\n\tprivate heuristicRunnerMicroTaskExists = false;\n\n\tpublic handleOp(op: ISequencedDocumentMessage) {\n\t\tthis.heuristicData.lastOpSequenceNumber = op.sequenceNumber;\n\n\t\tif (isRuntimeMessage(op)) {\n\t\t\tthis.heuristicData.numRuntimeOps++;\n\t\t} else {\n\t\t\tthis.heuristicData.numNonRuntimeOps++;\n\t\t}\n\n\t\tthis.heuristicData.totalOpsSize += opSize(op);\n\n\t\t// Check for enqueued on-demand summaries; Intentionally do nothing otherwise\n\t\tif (\n\t\t\tthis.initialized &&\n\t\t\tthis.opCanTriggerSummary(op) &&\n\t\t\t!this.tryRunEnqueuedSummary() &&\n\t\t\t!this.heuristicRunnerMicroTaskExists\n\t\t) {\n\t\t\tthis.heuristicRunnerMicroTaskExists = true;\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.heuristicRunner?.run();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.heuristicRunnerMicroTaskExists = false;\n\t\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Can the given op trigger a summary?\n\t * # Currently always prevents summaries for Summarize and SummaryAck/Nack ops\n\t * @param op - op to check\n\t * @returns true if this op can trigger a summary\n\t */\n\tprivate opCanTriggerSummary(op: ISequencedDocumentMessage): boolean {\n\t\tswitch (op.type) {\n\t\t\tcase MessageType.Summarize:\n\t\t\tcase MessageType.SummaryAck:\n\t\t\tcase MessageType.SummaryNack:\n\t\t\t\treturn false;\n\t\t\tdefault:\n\t\t\t\treturn isRuntimeMessage(op) || this.nonRuntimeOpCanTriggerSummary();\n\t\t}\n\t}\n\n\tprivate nonRuntimeOpCanTriggerSummary(): boolean {\n\t\tconst opsSinceLastAck =\n\t\t\tthis.heuristicData.lastOpSequenceNumber -\n\t\t\tthis.heuristicData.lastSuccessfulSummary.refSequenceNumber;\n\t\treturn (\n\t\t\tthis.configuration.state === \"enabled\" &&\n\t\t\t(this.configuration.nonRuntimeHeuristicThreshold === undefined ||\n\t\t\t\tthis.configuration.nonRuntimeHeuristicThreshold <= opsSinceLastAck)\n\t\t);\n\t}\n\n\tpublic async waitStop(allowLastSummary: boolean): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.stopping = true;\n\n\t\tthis.disposeEnqueuedSummary();\n\n\t\t// This will try to run lastSummary if needed.\n\t\tif (allowLastSummary && this.heuristicRunner?.shouldRunLastSummary()) {\n\t\t\tif (this.summarizingLock === undefined) {\n\t\t\t\tthis.trySummarizeOnce(\n\t\t\t\t\t// summarizeProps\n\t\t\t\t\t{ reason: \"lastSummary\" },\n\t\t\t\t\t// ISummarizeOptions, using defaults: { refreshLatestAck: false, fullTree: false }\n\t\t\t\t\t{},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Note that trySummarizeOnce() call above returns right away, without waiting.\n\t\t// So we need to wait for its completion, otherwise it would be destroyed right away.\n\t\t// That said, if summary lock was taken upfront, this wait might wait on multiple retries to\n\t\t// submit summary. We should reconsider this flow and make summarizer move to exit faster.\n\t\t// This resolves when the current pending summary gets an ack or fails.\n\t\tawait this.summarizingLock;\n\t}\n\n\tprivate async waitStart() {\n\t\t// Wait no longer than ack timeout for all pending\n\t\tconst waitStartResult = await raceTimer(\n\t\t\tthis.summaryWatcher.waitFlushed(),\n\t\t\tthis.pendingAckTimer.start(),\n\t\t);\n\t\tthis.pendingAckTimer.clear();\n\n\t\t// Remove pending ack wait timeout by op timestamp comparison, because\n\t\t// it has race conditions with summaries submitted by this same client.\n\t\tthis.summaryCollection.unsetPendingAckTimerTimeoutCallback();\n\n\t\tif (waitStartResult.result === \"done\" && waitStartResult.value !== undefined) {\n\t\t\tthis.heuristicData.updateWithLastSummaryAckInfo({\n\t\t\t\trefSequenceNumber: waitStartResult.value.summaryOp.referenceSequenceNumber,\n\t\t\t\t// This will be the Summarizer starting point so only use timestamps from client's machine.\n\t\t\t\tsummaryTime: Date.now(),\n\t\t\t\tsummarySequenceNumber: waitStartResult.value.summaryOp.sequenceNumber,\n\t\t\t});\n\t\t}\n\t\tthis.initialized = true;\n\t}\n\n\tprivate beforeSummaryAction() {\n\t\tthis.summarizeCount++;\n\t}\n\n\tprivate afterSummaryAction() {\n\t\tconst retry = this.tryWhileSummarizing;\n\t\tthis.tryWhileSummarizing = false;\n\n\t\t// After summarizing, we should check to see if we need to summarize again.\n\t\t// Rerun the heuristics and check for enqueued summaries.\n\t\tif (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {\n\t\t\tthis.heuristicRunner?.run();\n\t\t}\n\t}\n\n\t/**\n\t * Runs single summary action that prevents any other concurrent actions.\n\t * Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)\n\t * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.\n\t * @param before - set of instructions to run before running the action.\n\t * @param action - action to perform.\n\t * @param after - set of instructions to run after running the action.\n\t * @returns - result of action.\n\t */\n\tprivate async lockedSummaryAction<T>(\n\t\tbefore: () => void,\n\t\taction: () => Promise<T>,\n\t\tafter: () => void,\n\t) {\n\t\tassert(\n\t\t\tthis.summarizingLock === undefined,\n\t\t\t0x25b /* \"Caller is responsible for checking lock\" */,\n\t\t);\n\n\t\tconst summarizingLock = new Deferred<void>();\n\t\tthis.summarizingLock = summarizingLock.promise;\n\n\t\tbefore();\n\n\t\treturn action().finally(() => {\n\t\t\tsummarizingLock.resolve();\n\t\t\tthis.summarizingLock = undefined;\n\t\t\tafter();\n\t\t});\n\t}\n\n\t/**\n\t * Runs single summarize attempt\n\t * @param summarizeProps - props to log with each telemetry event associated with this attempt\n\t * @param options - summary options\n\t * @param cancellationToken - cancellation token to use to be able to cancel this summary, if needed\n\t * @param resultsBuilder - optional, result builder to use.\n\t * @returns ISummarizeResult - result of running a summary.\n\t */\n\tprivate trySummarizeOnce(\n\t\tsummarizeProps: ISummarizeTelemetryProperties,\n\t\toptions: ISummarizeOptions,\n\t\tcancellationToken = this.cancellationToken,\n\t\tresultsBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tthis.lockedSummaryAction(\n\t\t\t() => {\n\t\t\t\tthis.beforeSummaryAction();\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tconst summarizeResult = this.generator.summarize(\n\t\t\t\t\tsummarizeProps,\n\t\t\t\t\toptions,\n\t\t\t\t\tcancellationToken,\n\t\t\t\t\tresultsBuilder,\n\t\t\t\t);\n\t\t\t\t// ensure we wait till the end of the process\n\t\t\t\treturn summarizeResult.receivedSummaryAckOrNack;\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.afterSummaryAction();\n\t\t\t},\n\t\t).catch((error) => {\n\t\t\t// SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result\n\t\t\t// on resultsBuilder\n\t\t\t// We do not care about exceptions on receivedSummaryAckOrNack - caller should check results\n\t\t\t// and take a appropriate action.\n\t\t});\n\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** Heuristics summarize attempt. */\n\tprivate trySummarize(\n\t\treason: SummarizeReason,\n\t\tcancellationToken = this.cancellationToken,\n\t): void {\n\t\tif (this.summarizingLock !== undefined) {\n\t\t\t// lockedSummaryAction() will retry heuristic-based summary at the end of current attempt\n\t\t\t// if it's still needed\n\t\t\tthis.tryWhileSummarizing = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.lockedSummaryAction(\n\t\t\t() => {\n\t\t\t\tthis.beforeSummaryAction();\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tconst attempts: (ISummarizeOptions & { delaySeconds?: number })[] = [\n\t\t\t\t\t{ refreshLatestAck: false, fullTree: false },\n\t\t\t\t\t{ refreshLatestAck: true, fullTree: false },\n\t\t\t\t\t{ refreshLatestAck: true, fullTree: false, delaySeconds: 2 * 60 },\n\t\t\t\t\t{ refreshLatestAck: true, fullTree: true, delaySeconds: 10 * 60 },\n\t\t\t\t];\n\t\t\t\tlet overrideDelaySeconds: number | undefined;\n\t\t\t\tlet summaryAttempts = 0;\n\t\t\t\tlet summaryAttemptsPerPhase = 0;\n\t\t\t\t// Reducing the default number of attempts to defaultNumberofSummarizationAttempts.\n\t\t\t\tlet totalAttempts =\n\t\t\t\t\tthis.mc.config.getNumber(\"Fluid.Summarizer.Attempts\") ??\n\t\t\t\t\tdefaultNumberSummarizationAttempts;\n\n\t\t\t\tif (totalAttempts > attempts.length) {\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"InvalidSummarizerAttempts\",\n\t\t\t\t\t\tattempts: totalAttempts,\n\t\t\t\t\t});\n\t\t\t\t\ttotalAttempts = defaultNumberSummarizationAttempts;\n\t\t\t\t} else if (totalAttempts < 1) {\n\t\t\t\t\tthrow new UsageError(\"Invalid number of attempts.\");\n\t\t\t\t}\n\n\t\t\t\tlet lastResult: { message: string; error: any } | undefined;\n\n\t\t\t\tfor (let summaryAttemptPhase = 0; summaryAttemptPhase < totalAttempts; ) {\n\t\t\t\t\tif (this.cancellationToken.cancelled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We only want to attempt 1 summary when reason is \"lastSummary\"\n\t\t\t\t\tif (++summaryAttempts > 1 && reason === \"lastSummary\") {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tsummaryAttemptsPerPhase++;\n\n\t\t\t\t\tconst { delaySeconds: regularDelaySeconds = 0, ...options } =\n\t\t\t\t\t\tattempts[summaryAttemptPhase];\n\n\t\t\t\t\tconst summarizeProps: ISummarizeTelemetryProperties = {\n\t\t\t\t\t\treason,\n\t\t\t\t\t\tsummaryAttempts,\n\t\t\t\t\t\tsummaryAttemptsPerPhase,\n\t\t\t\t\t\tsummaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based\n\t\t\t\t\t\t...options,\n\t\t\t\t\t};\n\n\t\t\t\t\t// Note: no need to account for cancellationToken.waitCancelled here, as\n\t\t\t\t\t// this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.\n\t\t\t\t\tconst resultSummarize = this.generator.summarize(\n\t\t\t\t\t\tsummarizeProps,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t\tcancellationToken,\n\t\t\t\t\t);\n\t\t\t\t\tconst result = await resultSummarize.receivedSummaryAckOrNack;\n\n\t\t\t\t\tif (result.success) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Check for retryDelay that can come from summaryNack or upload summary flow.\n\t\t\t\t\t// Retry the same step only once per retryAfter response.\n\t\t\t\t\toverrideDelaySeconds = result.retryAfterSeconds;\n\t\t\t\t\tif (overrideDelaySeconds === undefined || summaryAttemptsPerPhase > 1) {\n\t\t\t\t\t\tsummaryAttemptPhase++;\n\t\t\t\t\t\tsummaryAttemptsPerPhase = 0;\n\t\t\t\t\t}\n\t\t\t\t\tlastResult = result;\n\n\t\t\t\t\tconst delaySeconds = overrideDelaySeconds ?? regularDelaySeconds;\n\n\t\t\t\t\tif (delaySeconds > 0) {\n\t\t\t\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\t\t\t\teventName: \"SummarizeAttemptDelay\",\n\t\t\t\t\t\t\tduration: delaySeconds,\n\t\t\t\t\t\t\tsummaryNackDelay: overrideDelaySeconds !== undefined,\n\t\t\t\t\t\t\t...summarizeProps,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tawait delay(delaySeconds * 1000);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If all attempts failed, log error (with last attempt info) and close the summarizer container\n\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"FailToSummarize\",\n\t\t\t\t\t\treason,\n\t\t\t\t\t\tmessage: lastResult?.message,\n\t\t\t\t\t},\n\t\t\t\t\tlastResult?.error,\n\t\t\t\t);\n\n\t\t\t\tthis.stopSummarizerCallback(\"failToSummarize\");\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.afterSummaryAction();\n\t\t\t},\n\t\t).catch((error) => {\n\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"UnexpectedSummarizeError\" }, error);\n\t\t});\n\t}\n\n\t/** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */\n\tpublic summarizeOnDemand(\n\t\tresultsBuilder: SummarizeResultBuilder = new SummarizeResultBuilder(),\n\t\t{ reason, ...options }: IOnDemandSummarizeOptions,\n\t): ISummarizeResults {\n\t\tif (this.stopping) {\n\t\t\tresultsBuilder.fail(\"RunningSummarizer stopped or disposed\", undefined);\n\t\t\treturn resultsBuilder.build();\n\t\t}\n\t\t// Check for concurrent summary attempts. If one is found,\n\t\t// return a promise that caller can await before trying again.\n\t\tif (this.summarizingLock !== undefined) {\n\t\t\t// The heuristics are blocking concurrent summarize attempts.\n\t\t\tthrow new UsageError(\"Attempted to run an already-running summarizer on demand\");\n\t\t}\n\n\t\tconst result = this.trySummarizeOnce(\n\t\t\t{ reason: `onDemand/${reason}` },\n\t\t\toptions,\n\t\t\tthis.cancellationToken,\n\t\t\tresultsBuilder,\n\t\t);\n\t\treturn result;\n\t}\n\n\t/** {@inheritdoc (ISummarizer:interface).enqueueSummarize} */\n\tpublic enqueueSummarize({\n\t\treason,\n\t\tafterSequenceNumber = 0,\n\t\toverride = false,\n\t\t...options\n\t}: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n\t\tconst onDemandReason = `enqueue;${reason}` as const;\n\t\tlet overridden = false;\n\t\tif (this.enqueuedSummary !== undefined) {\n\t\t\tif (!override) {\n\t\t\t\treturn { alreadyEnqueued: true };\n\t\t\t}\n\t\t\t// Override existing enqueued summarize attempt.\n\t\t\tthis.enqueuedSummary.resultsBuilder.fail(\n\t\t\t\t\"Aborted; overridden by another enqueue summarize attempt\",\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tthis.enqueuedSummary = undefined;\n\t\t\toverridden = true;\n\t\t}\n\t\tthis.enqueuedSummary = {\n\t\t\treason: onDemandReason,\n\t\t\tafterSequenceNumber,\n\t\t\toptions,\n\t\t\tresultsBuilder: new SummarizeResultBuilder(),\n\t\t};\n\t\tconst results = this.enqueuedSummary.resultsBuilder.build();\n\t\tthis.tryRunEnqueuedSummary();\n\t\treturn overridden\n\t\t\t? {\n\t\t\t\t\t...results,\n\t\t\t\t\talreadyEnqueued: true,\n\t\t\t\t\toverridden: true,\n\t\t\t }\n\t\t\t: results;\n\t}\n\n\tprivate tryRunEnqueuedSummary() {\n\t\tif (this.stopping) {\n\t\t\tthis.disposeEnqueuedSummary();\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\tthis.enqueuedSummary === undefined ||\n\t\t\tthis.heuristicData.lastOpSequenceNumber < this.enqueuedSummary.afterSequenceNumber ||\n\t\t\tthis.summarizingLock !== undefined\n\t\t) {\n\t\t\t// If no enqueued summary is ready or a summary is already in progress, take no action.\n\t\t\treturn false;\n\t\t}\n\t\tconst { reason, resultsBuilder, options } = this.enqueuedSummary;\n\t\t// Set to undefined first, so that subsequent enqueue attempt while summarize will occur later.\n\t\tthis.enqueuedSummary = undefined;\n\t\tthis.trySummarizeOnce(\n\t\t\t{ reason: `enqueuedSummary/${reason}` },\n\t\t\toptions,\n\t\t\tthis.cancellationToken,\n\t\t\tresultsBuilder,\n\t\t);\n\t\treturn true;\n\t}\n\n\tprivate disposeEnqueuedSummary() {\n\t\tif (this.enqueuedSummary !== undefined) {\n\t\t\tthis.enqueuedSummary.resultsBuilder.fail(\n\t\t\t\t\"RunningSummarizer stopped or disposed\",\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tthis.enqueuedSummary = undefined;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -7,11 +7,10 @@ import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
|
7
7
|
import { ILoader } from "@fluidframework/container-definitions";
|
|
8
8
|
import { IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils";
|
|
9
9
|
import { IFluidHandleContext, IFluidHandle } from "@fluidframework/core-interfaces";
|
|
10
|
-
import { ISummaryConfiguration } from "
|
|
10
|
+
import { ISummaryConfiguration } from "../containerRuntime";
|
|
11
11
|
import { ICancellableSummarizerController } from "./runWhileConnectedCoordinator";
|
|
12
12
|
import { SummaryCollection } from "./summaryCollection";
|
|
13
|
-
import { ISummarizer, ISummarizerInternalsProvider, ISummarizerRuntime, ISummarizingWarning, SummarizerStopReason } from "./summarizerTypes";
|
|
14
|
-
import { IConnectableRuntime } from ".";
|
|
13
|
+
import { IConnectableRuntime, ISummarizer, ISummarizerInternalsProvider, ISummarizerRuntime, ISummarizingWarning, SummarizerStopReason } from "./summarizerTypes";
|
|
15
14
|
export declare class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {
|
|
16
15
|
readonly logged: boolean;
|
|
17
16
|
readonly errorType = "summarizingError";
|
|
@@ -33,7 +32,7 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
33
32
|
private readonly configurationGetter;
|
|
34
33
|
/** Represents an object that can generate summary.
|
|
35
34
|
* In practical terms, it's same runtime (this.runtime) with clientType === "summarizer".
|
|
36
|
-
|
|
35
|
+
*/
|
|
37
36
|
private readonly internalsProvider;
|
|
38
37
|
readonly summaryCollection: SummaryCollection;
|
|
39
38
|
private readonly runCoordinatorCreateFn;
|
|
@@ -53,7 +52,7 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
53
52
|
runtime: ISummarizerRuntime, configurationGetter: () => ISummaryConfiguration,
|
|
54
53
|
/** Represents an object that can generate summary.
|
|
55
54
|
* In practical terms, it's same runtime (this.runtime) with clientType === "summarizer".
|
|
56
|
-
|
|
55
|
+
*/
|
|
57
56
|
internalsProvider: ISummarizerInternalsProvider, handleContext: IFluidHandleContext, summaryCollection: SummaryCollection, runCoordinatorCreateFn: (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>);
|
|
58
57
|
/**
|
|
59
58
|
* Creates a Summarizer and its underlying client.
|
|
@@ -100,6 +99,5 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
100
99
|
dispose(): void;
|
|
101
100
|
readonly summarizeOnDemand: ISummarizer["summarizeOnDemand"];
|
|
102
101
|
readonly enqueueSummarize: ISummarizer["enqueueSummarize"];
|
|
103
|
-
private handleSummaryAcks;
|
|
104
102
|
}
|
|
105
103
|
//# sourceMappingURL=summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/summary/summarizer.ts"],"names":[],"mappings":"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"}
|