@fluidframework/container-runtime 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.2.0.153917
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +69 -0
- package/dist/blobManager.d.ts +29 -24
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +162 -92
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +74 -76
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +328 -264
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +39 -13
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +112 -49
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +28 -4
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +107 -41
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/dist/deltaManagerSummarizerProxy.js +40 -0
- package/dist/deltaManagerSummarizerProxy.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +204 -0
- package/dist/gc/garbageCollection.d.ts.map +1 -0
- package/dist/{garbageCollection.js → gc/garbageCollection.js} +190 -554
- package/dist/gc/garbageCollection.js.map +1 -0
- package/dist/gc/gcConfigs.d.ts +22 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -0
- package/dist/gc/gcConfigs.js +143 -0
- package/dist/gc/gcConfigs.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +320 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -0
- package/dist/gc/gcDefinitions.js +81 -0
- package/dist/gc/gcDefinitions.js.map +1 -0
- package/dist/gc/gcHelpers.d.ts +86 -0
- package/dist/gc/gcHelpers.d.ts.map +1 -0
- package/dist/gc/gcHelpers.js +268 -0
- package/dist/gc/gcHelpers.js.map +1 -0
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
- package/dist/gc/gcReferenceGraphAlgorithm.js +49 -0
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -0
- package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
- package/dist/gc/gcSummaryDefinitions.js +7 -0
- package/dist/gc/gcSummaryDefinitions.js.map +1 -0
- package/dist/gc/gcSummaryStateTracker.d.ts +93 -0
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/dist/gc/gcSummaryStateTracker.js +239 -0
- package/dist/gc/gcSummaryStateTracker.js.map +1 -0
- package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +2 -2
- 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 +13 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +50 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/index.d.ts +3 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +11 -13
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +26 -38
- 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 +2 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +4 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +25 -10
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +4 -0
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +43 -4
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +14 -0
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/dist/opLifecycle/opGroupingManager.js +56 -0
- package/dist/opLifecycle/opGroupingManager.js.map +1 -0
- package/dist/opLifecycle/opSplitter.d.ts +16 -4
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +39 -15
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +21 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +90 -51
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -2
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +30 -20
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +3 -3
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +20 -21
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/dist/storageServiceWithAttachBlobs.js +32 -0
- package/dist/storageServiceWithAttachBlobs.js.map +1 -0
- package/dist/summary/index.d.ts +17 -0
- package/dist/summary/index.d.ts.map +1 -0
- package/dist/summary/index.js +48 -0
- package/dist/summary/index.js.map +1 -0
- package/dist/summary/orderedClientElection.d.ts.map +1 -0
- package/dist/summary/orderedClientElection.js.map +1 -0
- package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{lib → dist/summary}/runningSummarizer.d.ts +23 -20
- package/dist/summary/runningSummarizer.d.ts.map +1 -0
- package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -74
- package/dist/summary/runningSummarizer.js.map +1 -0
- package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
- package/dist/summary/summarizer.d.ts.map +1 -0
- package/dist/{summarizer.js → summary/summarizer.js} +10 -79
- 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/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +2 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
- package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -3
- package/dist/summary/summarizerHeuristics.js.map +1 -0
- package/dist/summary/summarizerNode/index.d.ts +8 -0
- package/dist/summary/summarizerNode/index.d.ts.map +1 -0
- package/dist/summary/summarizerNode/index.js +12 -0
- package/dist/summary/summarizerNode/index.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts +149 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.js +531 -0
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +132 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +148 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +424 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
- package/{lib → dist/summary}/summarizerTypes.d.ts +21 -19
- package/dist/summary/summarizerTypes.d.ts.map +1 -0
- package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -5
- package/dist/summary/summarizerTypes.js.map +1 -0
- package/dist/summary/summaryCollection.d.ts.map +1 -0
- package/dist/summary/summaryCollection.js.map +1 -0
- package/{lib → dist/summary}/summaryFormat.d.ts +3 -21
- package/dist/summary/summaryFormat.d.ts.map +1 -0
- package/dist/{summaryFormat.js → summary/summaryFormat.js} +1 -10
- package/dist/summary/summaryFormat.js.map +1 -0
- package/{lib → dist/summary}/summaryGenerator.d.ts +28 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -0
- package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +23 -20
- 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/summary/summaryManager.js.map +1 -0
- package/lib/blobManager.d.ts +29 -24
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +159 -89
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +74 -76
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +301 -237
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +39 -13
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +101 -38
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +28 -4
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +100 -34
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/lib/deltaManagerSummarizerProxy.js +36 -0
- package/lib/deltaManagerSummarizerProxy.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +204 -0
- package/lib/gc/garbageCollection.d.ts.map +1 -0
- package/lib/{garbageCollection.js → gc/garbageCollection.js} +172 -535
- package/lib/gc/garbageCollection.js.map +1 -0
- package/lib/gc/gcConfigs.d.ts +22 -0
- package/lib/gc/gcConfigs.d.ts.map +1 -0
- package/lib/gc/gcConfigs.js +139 -0
- package/lib/gc/gcConfigs.js.map +1 -0
- package/lib/gc/gcDefinitions.d.ts +320 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -0
- package/lib/gc/gcDefinitions.js +78 -0
- package/lib/gc/gcDefinitions.js.map +1 -0
- package/lib/gc/gcHelpers.d.ts +86 -0
- package/lib/gc/gcHelpers.d.ts.map +1 -0
- package/lib/gc/gcHelpers.js +254 -0
- package/lib/gc/gcHelpers.js.map +1 -0
- package/lib/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
- package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
- package/lib/gc/gcReferenceGraphAlgorithm.js +45 -0
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
- package/lib/gc/gcSummaryDefinitions.d.ts +52 -0
- package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
- package/lib/gc/gcSummaryDefinitions.js +6 -0
- package/lib/gc/gcSummaryDefinitions.js.map +1 -0
- package/lib/gc/gcSummaryStateTracker.d.ts +93 -0
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/lib/gc/gcSummaryStateTracker.js +235 -0
- package/lib/gc/gcSummaryStateTracker.js.map +1 -0
- package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +1 -1
- 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 +13 -0
- package/lib/gc/index.d.ts.map +1 -0
- package/lib/gc/index.js +12 -0
- package/lib/gc/index.js.map +1 -0
- package/lib/index.d.ts +3 -7
- 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 +11 -13
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +24 -37
- 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 +2 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +2 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +26 -11
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +4 -0
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +43 -4
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +14 -0
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/lib/opLifecycle/opGroupingManager.js +52 -0
- package/lib/opLifecycle/opGroupingManager.js.map +1 -0
- package/lib/opLifecycle/opSplitter.d.ts +16 -4
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +39 -15
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +21 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +92 -53
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -2
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +30 -20
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +3 -3
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +20 -21
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts +17 -0
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/lib/storageServiceWithAttachBlobs.js +28 -0
- package/lib/storageServiceWithAttachBlobs.js.map +1 -0
- 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/summary/orderedClientElection.js.map +1 -0
- package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{dist → lib/summary}/runningSummarizer.d.ts +23 -20
- package/lib/summary/runningSummarizer.d.ts.map +1 -0
- package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +192 -75
- package/lib/summary/runningSummarizer.js.map +1 -0
- package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
- package/lib/summary/summarizer.d.ts.map +1 -0
- package/lib/{summarizer.js → summary/summarizer.js} +12 -81
- 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/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +2 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
- package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -3
- package/lib/summary/summarizerHeuristics.js.map +1 -0
- package/lib/summary/summarizerNode/index.d.ts +8 -0
- package/lib/summary/summarizerNode/index.d.ts.map +1 -0
- package/lib/summary/summarizerNode/index.js +7 -0
- package/lib/summary/summarizerNode/index.js.map +1 -0
- package/lib/summary/summarizerNode/summarizerNode.d.ts +149 -0
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNode.js +526 -0
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +125 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +148 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +419 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
- package/{dist → lib/summary}/summarizerTypes.d.ts +21 -19
- package/lib/summary/summarizerTypes.d.ts.map +1 -0
- package/lib/summary/summarizerTypes.js +6 -0
- package/lib/summary/summarizerTypes.js.map +1 -0
- package/lib/summary/summaryCollection.d.ts.map +1 -0
- package/lib/summary/summaryCollection.js.map +1 -0
- package/{dist → lib/summary}/summaryFormat.d.ts +3 -21
- package/lib/summary/summaryFormat.d.ts.map +1 -0
- package/lib/{summaryFormat.js → summary/summaryFormat.js} +0 -8
- package/lib/summary/summaryFormat.js.map +1 -0
- package/{dist → lib/summary}/summaryGenerator.d.ts +28 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -0
- package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +21 -19
- 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/summary/summaryManager.js.map +1 -0
- package/package.json +66 -60
- package/src/blobManager.ts +196 -110
- package/src/containerRuntime.ts +491 -391
- package/src/dataStoreContext.ts +140 -49
- package/src/dataStores.ts +139 -41
- package/src/deltaManagerSummarizerProxy.ts +46 -0
- package/{garbageCollection.md → src/gc/garbageCollection.md} +2 -2
- package/src/{garbageCollection.ts → gc/garbageCollection.ts} +245 -890
- package/src/gc/gcConfigs.ts +193 -0
- package/src/gc/gcDefinitions.ts +387 -0
- package/src/gc/gcHelpers.ts +335 -0
- package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
- package/src/gc/gcSummaryDefinitions.ts +54 -0
- package/src/gc/gcSummaryStateTracker.ts +329 -0
- package/src/{gcSweepReadyUsageDetection.ts → gc/gcSweepReadyUsageDetection.ts} +1 -1
- package/src/gc/gcUnreferencedStateTracker.ts +114 -0
- package/src/gc/index.ts +65 -0
- package/src/index.ts +10 -22
- package/src/opLifecycle/README.md +263 -0
- package/src/opLifecycle/batchManager.ts +26 -55
- package/src/opLifecycle/definitions.ts +4 -0
- package/src/opLifecycle/index.ts +2 -1
- package/src/opLifecycle/opCompressor.ts +32 -12
- package/src/opLifecycle/opDecompressor.ts +50 -5
- package/src/opLifecycle/opGroupingManager.ts +78 -0
- package/src/opLifecycle/opSplitter.ts +56 -17
- package/src/opLifecycle/outbox.ts +126 -62
- package/src/opLifecycle/remoteMessageProcessor.ts +38 -22
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +34 -27
- package/src/storageServiceWithAttachBlobs.ts +38 -0
- package/src/summary/index.ts +105 -0
- package/src/{runWhileConnectedCoordinator.ts → summary/runWhileConnectedCoordinator.ts} +7 -7
- package/src/{runningSummarizer.ts → summary/runningSummarizer.ts} +318 -156
- package/src/{summarizer.ts → summary/summarizer.ts} +12 -105
- package/src/{summarizerHeuristics.ts → summary/summarizerHeuristics.ts} +13 -4
- package/src/summary/summarizerNode/index.ts +12 -0
- package/src/summary/summarizerNode/summarizerNode.ts +766 -0
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +214 -0
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +644 -0
- package/src/{summarizerTypes.ts → summary/summarizerTypes.ts} +28 -25
- package/src/{summaryFormat.ts → summary/summaryFormat.ts} +3 -29
- package/src/{summaryGenerator.ts → summary/summaryGenerator.ts} +34 -27
- package/src/{summaryManager.ts → summary/summaryManager.ts} +1 -1
- package/dist/garbageCollection.d.ts +0 -411
- package/dist/garbageCollection.d.ts.map +0 -1
- package/dist/garbageCollection.js.map +0 -1
- package/dist/garbageCollectionConstants.d.ts +0 -23
- package/dist/garbageCollectionConstants.d.ts.map +0 -1
- package/dist/garbageCollectionConstants.js +0 -36
- package/dist/garbageCollectionConstants.js.map +0 -1
- package/dist/garbageCollectionHelpers.d.ts +0 -15
- package/dist/garbageCollectionHelpers.d.ts.map +0 -1
- package/dist/garbageCollectionHelpers.js +0 -27
- package/dist/garbageCollectionHelpers.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/serializedSnapshotStorage.d.ts +0 -58
- package/dist/serializedSnapshotStorage.d.ts.map +0 -1
- package/dist/serializedSnapshotStorage.js +0 -110
- package/dist/serializedSnapshotStorage.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 +0 -12
- package/dist/summarizerHandle.d.ts.map +0 -1
- package/dist/summarizerHandle.js +0 -22
- package/dist/summarizerHandle.js.map +0 -1
- package/dist/summarizerHeuristics.d.ts.map +0 -1
- package/dist/summarizerHeuristics.js.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 +0 -411
- package/lib/garbageCollection.d.ts.map +0 -1
- package/lib/garbageCollection.js.map +0 -1
- package/lib/garbageCollectionConstants.d.ts +0 -23
- package/lib/garbageCollectionConstants.d.ts.map +0 -1
- package/lib/garbageCollectionConstants.js +0 -33
- package/lib/garbageCollectionConstants.js.map +0 -1
- package/lib/garbageCollectionHelpers.d.ts +0 -15
- package/lib/garbageCollectionHelpers.d.ts.map +0 -1
- package/lib/garbageCollectionHelpers.js +0 -23
- package/lib/garbageCollectionHelpers.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/serializedSnapshotStorage.d.ts +0 -58
- package/lib/serializedSnapshotStorage.d.ts.map +0 -1
- package/lib/serializedSnapshotStorage.js +0 -106
- package/lib/serializedSnapshotStorage.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 +0 -12
- package/lib/summarizerHandle.d.ts.map +0 -1
- package/lib/summarizerHandle.js +0 -18
- package/lib/summarizerHandle.js.map +0 -1
- package/lib/summarizerHeuristics.d.ts.map +0 -1
- package/lib/summarizerHeuristics.js.map +0 -1
- package/lib/summarizerTypes.d.ts.map +0 -1
- package/lib/summarizerTypes.js +0 -9
- package/lib/summarizerTypes.js.map +0 -1
- package/lib/summaryCollection.d.ts.map +0 -1
- package/lib/summaryCollection.js.map +0 -1
- package/lib/summaryFormat.d.ts.map +0 -1
- package/lib/summaryFormat.js.map +0 -1
- package/lib/summaryGenerator.d.ts.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/garbageCollectionConstants.ts +0 -38
- package/src/garbageCollectionHelpers.ts +0 -37
- package/src/serializedSnapshotStorage.ts +0 -151
- package/src/summarizerHandle.ts +0 -23
- /package/dist/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
- /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/dist/{orderedClientElection.js → summary/orderedClientElection.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/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/dist/{summaryCollection.js → summary/summaryCollection.js} +0 -0
- /package/dist/{summaryManager.js → summary/summaryManager.js} +0 -0
- /package/lib/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
- /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/lib/{orderedClientElection.js → summary/orderedClientElection.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/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/lib/{summaryCollection.js → summary/summaryCollection.js} +0 -0
- /package/lib/{summaryManager.js → summary/summaryManager.js} +0 -0
- /package/src/{orderedClientElection.ts → summary/orderedClientElection.ts} +0 -0
- /package/src/{summarizerClientElection.ts → summary/summarizerClientElection.ts} +0 -0
- /package/src/{summaryCollection.ts → summary/summaryCollection.ts} +0 -0
|
@@ -18,13 +18,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
exports.RunningSummarizer = void 0;
|
|
19
19
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
20
20
|
const container_utils_1 = require("@fluidframework/container-utils");
|
|
21
|
+
const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
21
22
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
22
23
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
23
24
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
24
|
-
const opProperties_1 = require("
|
|
25
|
+
const opProperties_1 = require("../opProperties");
|
|
25
26
|
const summarizerHeuristics_1 = require("./summarizerHeuristics");
|
|
26
27
|
const summaryGenerator_1 = require("./summaryGenerator");
|
|
27
28
|
const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
|
|
29
|
+
const defaultNumberSummarizationAttempts = 2; // only up to 2 attempts
|
|
30
|
+
const numberOfAttemptsOnRestartAsRecovery = 1; // Only summarize once
|
|
28
31
|
/**
|
|
29
32
|
* An instance of RunningSummarizer manages the heuristics for summarizing.
|
|
30
33
|
* Until disposed, the instance of RunningSummarizer can assume that it is
|
|
@@ -33,12 +36,13 @@ const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
|
|
|
33
36
|
* This object is created and controlled by Summarizer object.
|
|
34
37
|
*/
|
|
35
38
|
class RunningSummarizer {
|
|
36
|
-
constructor(baseLogger, summaryWatcher, configuration, submitSummaryCallback,
|
|
39
|
+
constructor(baseLogger, summaryWatcher, configuration, submitSummaryCallback, refreshLatestSummaryAckCallback, heuristicData, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
|
|
40
|
+
var _a, _b;
|
|
37
41
|
this.summaryWatcher = summaryWatcher;
|
|
38
42
|
this.configuration = configuration;
|
|
39
43
|
this.submitSummaryCallback = submitSummaryCallback;
|
|
44
|
+
this.refreshLatestSummaryAckCallback = refreshLatestSummaryAckCallback;
|
|
40
45
|
this.heuristicData = heuristicData;
|
|
41
|
-
this.raiseSummarizingError = raiseSummarizingError;
|
|
42
46
|
this.summaryCollection = summaryCollection;
|
|
43
47
|
this.cancellationToken = cancellationToken;
|
|
44
48
|
this.stopSummarizerCallback = stopSummarizerCallback;
|
|
@@ -56,7 +60,7 @@ class RunningSummarizer {
|
|
|
56
60
|
* @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct
|
|
57
61
|
*/
|
|
58
62
|
this.tryGetCorrelatedLogger = (summaryOpRefSeq) => this.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq
|
|
59
|
-
? this.logger
|
|
63
|
+
? this.mc.logger
|
|
60
64
|
: undefined;
|
|
61
65
|
/** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */
|
|
62
66
|
this.heuristicRunnerMicroTaskExists = false;
|
|
@@ -64,25 +68,27 @@ class RunningSummarizer {
|
|
|
64
68
|
summarizeCount: () => this.summarizeCount,
|
|
65
69
|
summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,
|
|
66
70
|
};
|
|
67
|
-
this.
|
|
71
|
+
this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(baseLogger, "Running", {
|
|
68
72
|
all: telemetryProps,
|
|
69
|
-
});
|
|
73
|
+
}));
|
|
74
|
+
this.shouldAbortOnSummaryFailure =
|
|
75
|
+
this.mc.config.getString("Fluid.ContainerRuntime.Test.SummarizationRecoveryMethod") ===
|
|
76
|
+
"restart";
|
|
70
77
|
if (configuration.state !== "disableHeuristics") {
|
|
71
78
|
(0, common_utils_1.assert)(this.configuration.state === "enabled", 0x2ea /* "Configuration state should be enabled" */);
|
|
72
|
-
this.heuristicRunner = new summarizerHeuristics_1.SummarizeHeuristicRunner(heuristicData, this.configuration, (reason) => this.trySummarize(reason), this.logger);
|
|
79
|
+
this.heuristicRunner = new summarizerHeuristics_1.SummarizeHeuristicRunner(heuristicData, this.configuration, (reason) => this.trySummarize(reason), this.mc.logger);
|
|
73
80
|
}
|
|
74
81
|
(0, common_utils_1.assert)(this.configuration.state !== "disabled", 0x2eb /* "Summary not supported with configuration disabled" */);
|
|
75
82
|
// Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime
|
|
76
83
|
// configuration.maxAckWaitTime is composed from defaults, server values, and runtime overrides
|
|
77
84
|
const maxAckWaitTime = Math.min(this.configuration.maxAckWaitTime, maxSummarizeAckWaitTime);
|
|
78
85
|
this.pendingAckTimer = new common_utils_1.PromiseTimer(maxAckWaitTime, () => {
|
|
79
|
-
// pre-0.58 error message: summaryAckWaitTimeout
|
|
80
|
-
this.raiseSummarizingError("Pending summary ack not received in time");
|
|
81
86
|
// Note: summarizeCount (from ChildLogger definition) may be 0,
|
|
82
87
|
// since this code path is hit when RunningSummarizer first starts up,
|
|
83
88
|
// before this instance has kicked off a new summarize run.
|
|
84
|
-
this.logger.sendErrorEvent({
|
|
89
|
+
this.mc.logger.sendErrorEvent({
|
|
85
90
|
eventName: "SummaryAckWaitTimeout",
|
|
91
|
+
message: "Pending summary ack not received in time",
|
|
86
92
|
maxAckWaitTime,
|
|
87
93
|
referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,
|
|
88
94
|
summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,
|
|
@@ -92,7 +98,7 @@ class RunningSummarizer {
|
|
|
92
98
|
// Set up pending ack timeout by op timestamp differences for previous summaries.
|
|
93
99
|
summaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {
|
|
94
100
|
if (this.pendingAckTimer.hasTimer) {
|
|
95
|
-
this.logger.sendTelemetryEvent({
|
|
101
|
+
this.mc.logger.sendTelemetryEvent({
|
|
96
102
|
eventName: "MissingSummaryAckFoundByOps",
|
|
97
103
|
referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,
|
|
98
104
|
summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,
|
|
@@ -100,18 +106,39 @@ class RunningSummarizer {
|
|
|
100
106
|
this.pendingAckTimer.clear();
|
|
101
107
|
}
|
|
102
108
|
});
|
|
103
|
-
this.generator = new summaryGenerator_1.SummaryGenerator(this.pendingAckTimer, this.heuristicData, this.submitSummaryCallback,
|
|
109
|
+
this.generator = new summaryGenerator_1.SummaryGenerator(this.pendingAckTimer, this.heuristicData, this.submitSummaryCallback, () => {
|
|
104
110
|
this.totalSuccessfulAttempts++;
|
|
105
|
-
}, this.summaryWatcher, this.logger);
|
|
106
|
-
// Listen for ops
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
}, this.summaryWatcher, this.mc.logger);
|
|
112
|
+
// Listen to deltaManager for non-runtime ops
|
|
113
|
+
this.deltaManagerListener = (op) => {
|
|
114
|
+
if (!(0, driver_utils_1.isRuntimeMessage)(op)) {
|
|
115
|
+
this.handleOp(op, false);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
// Listen to runtime for runtime ops
|
|
119
|
+
this.runtimeListener = (op, runtimeMessage) => {
|
|
120
|
+
if (runtimeMessage) {
|
|
121
|
+
this.handleOp(op, true);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Purpose of listening to deltaManager is for back-compat
|
|
125
|
+
// Can remove and only listen to runtime once loader version is past 2.0.0-internal.1.2.0 (https://github.com/microsoft/FluidFramework/pull/11832)
|
|
126
|
+
// Tracked by AB#3883
|
|
127
|
+
this.runtime.deltaManager.on("op", this.deltaManagerListener);
|
|
128
|
+
(_b = (_a = this.runtime).on) === null || _b === void 0 ? void 0 : _b.call(_a, "op", this.runtimeListener);
|
|
110
129
|
}
|
|
111
|
-
static async start(logger, summaryWatcher, configuration, submitSummaryCallback,
|
|
130
|
+
static async start(logger, summaryWatcher, configuration, submitSummaryCallback, refreshLatestSummaryAckCallback, heuristicData, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
|
|
112
131
|
var _a, _b;
|
|
113
|
-
const summarizer = new RunningSummarizer(logger, summaryWatcher, configuration, submitSummaryCallback,
|
|
132
|
+
const summarizer = new RunningSummarizer(logger, summaryWatcher, configuration, submitSummaryCallback, refreshLatestSummaryAckCallback, heuristicData, summaryCollection, cancellationToken, stopSummarizerCallback, runtime);
|
|
133
|
+
// Before doing any heuristics or proceeding with its refreshing, if there is a summary ack received while
|
|
134
|
+
// this summarizer catches up, let's refresh state before proceeding with the summarization.
|
|
135
|
+
const lastAckRefSeq = await summarizer.handleSummaryAck();
|
|
114
136
|
await summarizer.waitStart();
|
|
137
|
+
// Handle summary acks asynchronously
|
|
138
|
+
// Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions
|
|
139
|
+
summarizer.processIncomingSummaryAcks(lastAckRefSeq).catch((error) => {
|
|
140
|
+
logger.sendErrorEvent({ eventName: "HandleSummaryAckFatalError" }, error);
|
|
141
|
+
});
|
|
115
142
|
// Update heuristic counts
|
|
116
143
|
// By the time we get here, there are potentially ops missing from the heuristic summary counts
|
|
117
144
|
// Examples of where this could happen:
|
|
@@ -138,13 +165,87 @@ class RunningSummarizer {
|
|
|
138
165
|
get disposed() {
|
|
139
166
|
return this._disposed;
|
|
140
167
|
}
|
|
141
|
-
|
|
168
|
+
async handleSummaryAck() {
|
|
142
169
|
var _a;
|
|
143
|
-
this.
|
|
144
|
-
|
|
145
|
-
|
|
170
|
+
const lastAck = this.summaryCollection.latestAck;
|
|
171
|
+
let refSequenceNumber = -1;
|
|
172
|
+
// In case we haven't received the lastestAck yet, just return.
|
|
173
|
+
if (lastAck !== undefined) {
|
|
174
|
+
refSequenceNumber = lastAck.summaryOp.referenceSequenceNumber;
|
|
175
|
+
const summaryLogger = (_a = this.tryGetCorrelatedLogger(refSequenceNumber)) !== null && _a !== void 0 ? _a : this.mc.logger;
|
|
176
|
+
const summaryOpHandle = lastAck.summaryOp.contents.handle;
|
|
177
|
+
const summaryAckHandle = lastAck.summaryAck.contents.handle;
|
|
178
|
+
while (this.summarizingLock !== undefined) {
|
|
179
|
+
summaryLogger.sendTelemetryEvent({
|
|
180
|
+
eventName: "RefreshAttemptWithSummarizerRunning",
|
|
181
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
182
|
+
proposalHandle: summaryOpHandle,
|
|
183
|
+
ackHandle: summaryAckHandle,
|
|
184
|
+
});
|
|
185
|
+
await this.summarizingLock;
|
|
186
|
+
}
|
|
187
|
+
// Make sure we block any summarizer from being executed/enqueued while
|
|
188
|
+
// executing the refreshLatestSummaryAck.
|
|
189
|
+
// https://dev.azure.com/fluidframework/internal/_workitems/edit/779
|
|
190
|
+
await this.lockedSummaryAction(() => { }, async () => this.refreshLatestSummaryAckCallback({
|
|
191
|
+
proposalHandle: summaryOpHandle,
|
|
192
|
+
ackHandle: summaryAckHandle,
|
|
193
|
+
summaryRefSeq: refSequenceNumber,
|
|
194
|
+
summaryLogger,
|
|
195
|
+
}).catch(async (error) => {
|
|
196
|
+
// If the error is 404, so maybe the fetched version no longer exists on server. We just
|
|
197
|
+
// ignore this error in that case, as that means we will have another summaryAck for the
|
|
198
|
+
// latest version with which we will refresh the state. However in case of single commit
|
|
199
|
+
// summary, we might me missing a summary ack, so in that case we are still fine as the
|
|
200
|
+
// code in `submitSummary` function in container runtime, will refresh the latest state
|
|
201
|
+
// by calling `refreshLatestSummaryAckFromServer` and we will be fine.
|
|
202
|
+
const isIgnoredError = (0, telemetry_utils_1.isFluidError)(error) &&
|
|
203
|
+
error.errorType === driver_definitions_1.DriverErrorType.fileNotFoundOrAccessDeniedError;
|
|
204
|
+
summaryLogger.sendTelemetryEvent({
|
|
205
|
+
eventName: isIgnoredError
|
|
206
|
+
? "HandleSummaryAckErrorIgnored"
|
|
207
|
+
: "HandleLastSummaryAckError",
|
|
208
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
209
|
+
proposalHandle: summaryOpHandle,
|
|
210
|
+
ackHandle: summaryAckHandle,
|
|
211
|
+
}, error);
|
|
212
|
+
}), () => { });
|
|
213
|
+
refSequenceNumber++;
|
|
214
|
+
}
|
|
215
|
+
return refSequenceNumber;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Responsible for receiving and processing all the summaryAcks.
|
|
219
|
+
* In case there was a summary ack processed by the running summarizer before processIncomingSummaryAcks is called,
|
|
220
|
+
* it will wait for the summary ack that is newer than the one indicated by the lastAckRefSeq.
|
|
221
|
+
* @param lastAckRefSeq - Identifies the minimum reference sequence number the summarizer needs to wait for.
|
|
222
|
+
* In case of a negative number, the summarizer will wait for ANY summary ack that is greater than the deltaManager's initial sequence number,
|
|
223
|
+
* and, in case of a positive one, it will wait for a summary ack that is greater than this current reference sequence number.
|
|
224
|
+
*/
|
|
225
|
+
async processIncomingSummaryAcks(lastAckRefSeq) {
|
|
226
|
+
var _a;
|
|
227
|
+
let refSequenceNumber = lastAckRefSeq > 0 ? lastAckRefSeq : this.runtime.deltaManager.initialSequenceNumber;
|
|
228
|
+
while (!this.disposed) {
|
|
229
|
+
const summaryLogger = (_a = this.tryGetCorrelatedLogger(refSequenceNumber)) !== null && _a !== void 0 ? _a : this.mc.logger;
|
|
230
|
+
// Initialize ack with undefined if exception happens inside of waitSummaryAck on second iteration,
|
|
231
|
+
// we record undefined, not previous handles.
|
|
232
|
+
await this.summaryCollection.waitSummaryAck(refSequenceNumber);
|
|
233
|
+
summaryLogger.sendTelemetryEvent({
|
|
234
|
+
eventName: "processIncomingSummaryAcks",
|
|
235
|
+
referenceSequenceNumber: refSequenceNumber,
|
|
236
|
+
lastAckRefSeq,
|
|
237
|
+
});
|
|
238
|
+
refSequenceNumber = await this.handleSummaryAck();
|
|
239
|
+
// A valid Summary Ack must have been processed.
|
|
240
|
+
(0, common_utils_1.assert)(refSequenceNumber >= 0, 0x58f /* Invalid ref sequence number */);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
dispose() {
|
|
244
|
+
var _a, _b, _c;
|
|
245
|
+
this.runtime.deltaManager.off("op", this.deltaManagerListener);
|
|
246
|
+
(_b = (_a = this.runtime).off) === null || _b === void 0 ? void 0 : _b.call(_a, "op", this.runtimeListener);
|
|
146
247
|
this.summaryWatcher.dispose();
|
|
147
|
-
(
|
|
248
|
+
(_c = this.heuristicRunner) === null || _c === void 0 ? void 0 : _c.dispose();
|
|
148
249
|
this.heuristicRunner = undefined;
|
|
149
250
|
this.generator.dispose();
|
|
150
251
|
this.pendingAckTimer.clear();
|
|
@@ -152,9 +253,9 @@ class RunningSummarizer {
|
|
|
152
253
|
this._disposed = true;
|
|
153
254
|
this.stopping = true;
|
|
154
255
|
}
|
|
155
|
-
handleOp(op) {
|
|
256
|
+
handleOp(op, runtimeMessage) {
|
|
156
257
|
this.heuristicData.lastOpSequenceNumber = op.sequenceNumber;
|
|
157
|
-
if (
|
|
258
|
+
if (runtimeMessage) {
|
|
158
259
|
this.heuristicData.numRuntimeOps++;
|
|
159
260
|
}
|
|
160
261
|
else {
|
|
@@ -163,7 +264,7 @@ class RunningSummarizer {
|
|
|
163
264
|
this.heuristicData.totalOpsSize += (0, opProperties_1.opSize)(op);
|
|
164
265
|
// Check for enqueued on-demand summaries; Intentionally do nothing otherwise
|
|
165
266
|
if (this.initialized &&
|
|
166
|
-
this.opCanTriggerSummary(op) &&
|
|
267
|
+
this.opCanTriggerSummary(op, runtimeMessage) &&
|
|
167
268
|
!this.tryRunEnqueuedSummary() &&
|
|
168
269
|
!this.heuristicRunnerMicroTaskExists) {
|
|
169
270
|
this.heuristicRunnerMicroTaskExists = true;
|
|
@@ -183,14 +284,14 @@ class RunningSummarizer {
|
|
|
183
284
|
* @param op - op to check
|
|
184
285
|
* @returns true if this op can trigger a summary
|
|
185
286
|
*/
|
|
186
|
-
opCanTriggerSummary(op) {
|
|
287
|
+
opCanTriggerSummary(op, runtimeMessage) {
|
|
187
288
|
switch (op.type) {
|
|
188
289
|
case protocol_definitions_1.MessageType.Summarize:
|
|
189
290
|
case protocol_definitions_1.MessageType.SummaryAck:
|
|
190
291
|
case protocol_definitions_1.MessageType.SummaryNack:
|
|
191
292
|
return false;
|
|
192
293
|
default:
|
|
193
|
-
return
|
|
294
|
+
return runtimeMessage || this.nonRuntimeOpCanTriggerSummary();
|
|
194
295
|
}
|
|
195
296
|
}
|
|
196
297
|
nonRuntimeOpCanTriggerSummary() {
|
|
@@ -241,52 +342,37 @@ class RunningSummarizer {
|
|
|
241
342
|
}
|
|
242
343
|
this.initialized = true;
|
|
243
344
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
async lockedRefreshSummaryAckAction(action) {
|
|
257
|
-
(0, common_utils_1.assert)(this.refreshSummaryAckLock === undefined, 0x396 /* Refresh Summary Ack - Caller is responsible for checking lock */);
|
|
258
|
-
const refreshSummaryAckLock = new common_utils_1.Deferred();
|
|
259
|
-
this.refreshSummaryAckLock = refreshSummaryAckLock.promise;
|
|
260
|
-
return action().finally(() => {
|
|
261
|
-
refreshSummaryAckLock.resolve();
|
|
262
|
-
this.refreshSummaryAckLock = undefined;
|
|
263
|
-
});
|
|
345
|
+
beforeSummaryAction() {
|
|
346
|
+
this.summarizeCount++;
|
|
347
|
+
}
|
|
348
|
+
afterSummaryAction() {
|
|
349
|
+
var _a;
|
|
350
|
+
const retry = this.tryWhileSummarizing;
|
|
351
|
+
this.tryWhileSummarizing = false;
|
|
352
|
+
// After summarizing, we should check to see if we need to summarize again.
|
|
353
|
+
// Rerun the heuristics and check for enqueued summaries.
|
|
354
|
+
if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {
|
|
355
|
+
(_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
|
|
356
|
+
}
|
|
264
357
|
}
|
|
265
358
|
/**
|
|
266
359
|
* Runs single summary action that prevents any other concurrent actions.
|
|
267
360
|
* Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)
|
|
268
361
|
* before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.
|
|
362
|
+
* @param before - set of instructions to run before running the action.
|
|
269
363
|
* @param action - action to perform.
|
|
364
|
+
* @param after - set of instructions to run after running the action.
|
|
270
365
|
* @returns - result of action.
|
|
271
366
|
*/
|
|
272
|
-
async lockedSummaryAction(action) {
|
|
367
|
+
async lockedSummaryAction(before, action, after) {
|
|
273
368
|
(0, common_utils_1.assert)(this.summarizingLock === undefined, 0x25b /* "Caller is responsible for checking lock" */);
|
|
274
369
|
const summarizingLock = new common_utils_1.Deferred();
|
|
275
370
|
this.summarizingLock = summarizingLock.promise;
|
|
276
|
-
|
|
277
|
-
// Make sure the RefreshLatestSummaryAck is not being executed.
|
|
278
|
-
await this.refreshSummaryAckLock;
|
|
371
|
+
before();
|
|
279
372
|
return action().finally(() => {
|
|
280
|
-
var _a;
|
|
281
373
|
summarizingLock.resolve();
|
|
282
374
|
this.summarizingLock = undefined;
|
|
283
|
-
|
|
284
|
-
this.tryWhileSummarizing = false;
|
|
285
|
-
// After summarizing, we should check to see if we need to summarize again.
|
|
286
|
-
// Rerun the heuristics and check for enqueued summaries.
|
|
287
|
-
if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {
|
|
288
|
-
(_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
|
|
289
|
-
}
|
|
375
|
+
after();
|
|
290
376
|
});
|
|
291
377
|
}
|
|
292
378
|
/**
|
|
@@ -298,10 +384,14 @@ class RunningSummarizer {
|
|
|
298
384
|
* @returns ISummarizeResult - result of running a summary.
|
|
299
385
|
*/
|
|
300
386
|
trySummarizeOnce(summarizeProps, options, cancellationToken = this.cancellationToken, resultsBuilder = new summaryGenerator_1.SummarizeResultBuilder()) {
|
|
301
|
-
this.lockedSummaryAction(
|
|
387
|
+
this.lockedSummaryAction(() => {
|
|
388
|
+
this.beforeSummaryAction();
|
|
389
|
+
}, async () => {
|
|
302
390
|
const summarizeResult = this.generator.summarize(summarizeProps, options, cancellationToken, resultsBuilder);
|
|
303
391
|
// ensure we wait till the end of the process
|
|
304
392
|
return summarizeResult.receivedSummaryAckOrNack;
|
|
393
|
+
}, () => {
|
|
394
|
+
this.afterSummaryAction();
|
|
305
395
|
}).catch((error) => {
|
|
306
396
|
// SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result
|
|
307
397
|
// on resultsBuilder
|
|
@@ -318,7 +408,10 @@ class RunningSummarizer {
|
|
|
318
408
|
this.tryWhileSummarizing = true;
|
|
319
409
|
return;
|
|
320
410
|
}
|
|
321
|
-
this.lockedSummaryAction(
|
|
411
|
+
this.lockedSummaryAction(() => {
|
|
412
|
+
this.beforeSummaryAction();
|
|
413
|
+
}, async () => {
|
|
414
|
+
var _a;
|
|
322
415
|
const attempts = [
|
|
323
416
|
{ refreshLatestAck: false, fullTree: false },
|
|
324
417
|
{ refreshLatestAck: true, fullTree: false },
|
|
@@ -328,8 +421,22 @@ class RunningSummarizer {
|
|
|
328
421
|
let overrideDelaySeconds;
|
|
329
422
|
let summaryAttempts = 0;
|
|
330
423
|
let summaryAttemptsPerPhase = 0;
|
|
424
|
+
// Reducing the default number of attempts to defaultNumberofSummarizationAttempts.
|
|
425
|
+
let totalAttempts = this.shouldAbortOnSummaryFailure
|
|
426
|
+
? numberOfAttemptsOnRestartAsRecovery
|
|
427
|
+
: (_a = this.mc.config.getNumber("Fluid.Summarizer.Attempts")) !== null && _a !== void 0 ? _a : defaultNumberSummarizationAttempts;
|
|
428
|
+
if (totalAttempts > attempts.length) {
|
|
429
|
+
this.mc.logger.sendTelemetryEvent({
|
|
430
|
+
eventName: "InvalidSummarizerAttempts",
|
|
431
|
+
attempts: totalAttempts,
|
|
432
|
+
});
|
|
433
|
+
totalAttempts = defaultNumberSummarizationAttempts;
|
|
434
|
+
}
|
|
435
|
+
else if (totalAttempts < 1) {
|
|
436
|
+
throw new container_utils_1.UsageError("Invalid number of attempts.");
|
|
437
|
+
}
|
|
331
438
|
let lastResult;
|
|
332
|
-
for (let summaryAttemptPhase = 0; summaryAttemptPhase <
|
|
439
|
+
for (let summaryAttemptPhase = 0; summaryAttemptPhase < totalAttempts;) {
|
|
333
440
|
if (this.cancellationToken.cancelled) {
|
|
334
441
|
return;
|
|
335
442
|
}
|
|
@@ -338,17 +445,10 @@ class RunningSummarizer {
|
|
|
338
445
|
return;
|
|
339
446
|
}
|
|
340
447
|
summaryAttemptsPerPhase++;
|
|
341
|
-
const
|
|
342
|
-
const delaySeconds = overrideDelaySeconds !== null && overrideDelaySeconds !== void 0 ? overrideDelaySeconds : regularDelaySeconds;
|
|
448
|
+
const _b = attempts[summaryAttemptPhase], { delaySeconds: regularDelaySeconds = 0 } = _b, options = __rest(_b, ["delaySeconds"]);
|
|
343
449
|
const summarizeProps = Object.assign({ reason,
|
|
344
450
|
summaryAttempts,
|
|
345
451
|
summaryAttemptsPerPhase, summaryAttemptPhase: summaryAttemptPhase + 1 }, options);
|
|
346
|
-
if (delaySeconds > 0) {
|
|
347
|
-
this.logger.sendPerformanceEvent(Object.assign({ eventName: "SummarizeAttemptDelay", duration: delaySeconds, summaryNackDelay: overrideDelaySeconds !== undefined }, summarizeProps));
|
|
348
|
-
await (0, common_utils_1.delay)(delaySeconds * 1000);
|
|
349
|
-
}
|
|
350
|
-
// Make sure the refresh Summary Ack is not being executed.
|
|
351
|
-
await this.refreshSummaryAckLock;
|
|
352
452
|
// Note: no need to account for cancellationToken.waitCancelled here, as
|
|
353
453
|
// this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.
|
|
354
454
|
const resultSummarize = this.generator.summarize(summarizeProps, options, cancellationToken);
|
|
@@ -364,16 +464,33 @@ class RunningSummarizer {
|
|
|
364
464
|
summaryAttemptsPerPhase = 0;
|
|
365
465
|
}
|
|
366
466
|
lastResult = result;
|
|
467
|
+
const delaySeconds = overrideDelaySeconds !== null && overrideDelaySeconds !== void 0 ? overrideDelaySeconds : regularDelaySeconds;
|
|
468
|
+
if (delaySeconds > 0) {
|
|
469
|
+
this.mc.logger.sendPerformanceEvent(Object.assign({ eventName: "SummarizeAttemptDelay", duration: delaySeconds, summaryNackDelay: overrideDelaySeconds !== undefined }, summarizeProps));
|
|
470
|
+
await (0, common_utils_1.delay)(delaySeconds * 1000);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (this.shouldAbortOnSummaryFailure) {
|
|
474
|
+
this.mc.logger.sendTelemetryEvent({
|
|
475
|
+
eventName: "ClosingSummarizerOnSummaryStale",
|
|
476
|
+
reason,
|
|
477
|
+
message: lastResult === null || lastResult === void 0 ? void 0 : lastResult.message,
|
|
478
|
+
}, lastResult === null || lastResult === void 0 ? void 0 : lastResult.error);
|
|
479
|
+
this.stopSummarizerCallback("latestSummaryStateStale");
|
|
480
|
+
this.runtime.closeFn();
|
|
481
|
+
return;
|
|
367
482
|
}
|
|
368
483
|
// If all attempts failed, log error (with last attempt info) and close the summarizer container
|
|
369
|
-
this.logger.sendErrorEvent({
|
|
484
|
+
this.mc.logger.sendErrorEvent({
|
|
370
485
|
eventName: "FailToSummarize",
|
|
371
486
|
reason,
|
|
372
487
|
message: lastResult === null || lastResult === void 0 ? void 0 : lastResult.message,
|
|
373
488
|
}, lastResult === null || lastResult === void 0 ? void 0 : lastResult.error);
|
|
374
489
|
this.stopSummarizerCallback("failToSummarize");
|
|
490
|
+
}, () => {
|
|
491
|
+
this.afterSummaryAction();
|
|
375
492
|
}).catch((error) => {
|
|
376
|
-
this.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
|
|
493
|
+
this.mc.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
|
|
377
494
|
});
|
|
378
495
|
}
|
|
379
496
|
/** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */
|
|
@@ -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\nconst numberOfAttemptsOnRestartAsRecovery = 1; // Only summarize once\n\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\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\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\tprivate readonly shouldAbortOnSummaryFailure: boolean;\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 readonly deltaManagerListener;\n\tprivate readonly runtimeListener;\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 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\tthis.shouldAbortOnSummaryFailure =\n\t\t\tthis.mc.config.getString(\"Fluid.ContainerRuntime.Test.SummarizationRecoveryMethod\") ===\n\t\t\t\"restart\";\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// 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\tmessage: \"Pending summary ack not received in time\",\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\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 to deltaManager for non-runtime ops\n\t\tthis.deltaManagerListener = (op) => {\n\t\t\tif (!isRuntimeMessage(op)) {\n\t\t\t\tthis.handleOp(op, false);\n\t\t\t}\n\t\t};\n\n\t\t// Listen to runtime for runtime ops\n\t\tthis.runtimeListener = (op, runtimeMessage) => {\n\t\t\tif (runtimeMessage) {\n\t\t\t\tthis.handleOp(op, true);\n\t\t\t}\n\t\t};\n\n\t\t// Purpose of listening to deltaManager is for back-compat\n\t\t// Can remove and only listen to runtime once loader version is past 2.0.0-internal.1.2.0 (https://github.com/microsoft/FluidFramework/pull/11832)\n\t\t// Tracked by AB#3883\n\t\tthis.runtime.deltaManager.on(\"op\", this.deltaManagerListener);\n\t\tthis.runtime.on?.(\"op\", this.runtimeListener);\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\tconst summaryOpHandle = lastAck.summaryOp.contents.handle;\n\t\t\tconst summaryAckHandle = lastAck.summaryAck.contents.handle;\n\t\t\twhile (this.summarizingLock !== undefined) {\n\t\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"RefreshAttemptWithSummarizerRunning\",\n\t\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t});\n\t\t\t\tawait this.summarizingLock;\n\t\t\t}\n\n\t\t\t// Make sure we block any summarizer from being executed/enqueued while\n\t\t\t// executing the refreshLatestSummaryAck.\n\t\t\t// https://dev.azure.com/fluidframework/internal/_workitems/edit/779\n\t\t\tawait this.lockedSummaryAction(\n\t\t\t\t() => {},\n\t\t\t\tasync () =>\n\t\t\t\t\tthis.refreshLatestSummaryAckCallback({\n\t\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\t\tsummaryRefSeq: refSequenceNumber,\n\t\t\t\t\t\tsummaryLogger,\n\t\t\t\t\t}).catch(async (error) => {\n\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// ignore this error in that case, as that means we will have another summaryAck for the\n\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// 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// code in `submitSummary` function in container runtime, will refresh the latest state\n\t\t\t\t\t\t// by calling `refreshLatestSummaryAckFromServer` and we will be fine.\n\t\t\t\t\t\tconst isIgnoredError =\n\t\t\t\t\t\t\tisFluidError(error) &&\n\t\t\t\t\t\t\terror.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError;\n\n\t\t\t\t\t\tsummaryLogger.sendTelemetryEvent(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\teventName: isIgnoredError\n\t\t\t\t\t\t\t\t\t? \"HandleSummaryAckErrorIgnored\"\n\t\t\t\t\t\t\t\t\t: \"HandleLastSummaryAckError\",\n\t\t\t\t\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\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\", this.deltaManagerListener);\n\t\tthis.runtime.off?.(\"op\", this.runtimeListener);\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, runtimeMessage: boolean) {\n\t\tthis.heuristicData.lastOpSequenceNumber = op.sequenceNumber;\n\n\t\tif (runtimeMessage) {\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, runtimeMessage) &&\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, runtimeMessage: boolean): 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 runtimeMessage || 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 = this.shouldAbortOnSummaryFailure\n\t\t\t\t\t? numberOfAttemptsOnRestartAsRecovery\n\t\t\t\t\t: this.mc.config.getNumber(\"Fluid.Summarizer.Attempts\") ??\n\t\t\t\t\t defaultNumberSummarizationAttempts;\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\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\tif (this.shouldAbortOnSummaryFailure) {\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"ClosingSummarizerOnSummaryStale\",\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tmessage: lastResult?.message,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tlastResult?.error,\n\t\t\t\t\t);\n\n\t\t\t\t\tthis.stopSummarizerCallback(\"latestSummaryStateStale\");\n\t\t\t\t\tthis.runtime.closeFn();\n\t\t\t\t\treturn;\n\t\t\t\t}\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"]}
|
|
@@ -6,12 +6,11 @@ import { EventEmitter } from "events";
|
|
|
6
6
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
7
7
|
import { ILoader } from "@fluidframework/container-definitions";
|
|
8
8
|
import { IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils";
|
|
9
|
-
import { IFluidHandleContext
|
|
10
|
-
import { ISummaryConfiguration } from "
|
|
9
|
+
import { IFluidHandleContext } from "@fluidframework/core-interfaces";
|
|
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";
|
|
@@ -37,16 +36,13 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
37
36
|
private readonly internalsProvider;
|
|
38
37
|
readonly summaryCollection: SummaryCollection;
|
|
39
38
|
private readonly runCoordinatorCreateFn;
|
|
40
|
-
get IFluidLoadable(): this;
|
|
41
39
|
get ISummarizer(): this;
|
|
42
40
|
private readonly logger;
|
|
43
41
|
private runningSummarizer?;
|
|
44
42
|
private _disposed;
|
|
45
43
|
private starting;
|
|
46
|
-
private readonly innerHandle;
|
|
47
|
-
get handle(): IFluidHandle<this>;
|
|
48
44
|
private readonly stopDeferred;
|
|
49
|
-
constructor(
|
|
45
|
+
constructor(
|
|
50
46
|
/** Reference to runtime that created this object.
|
|
51
47
|
* i.e. runtime with clientType === "summarizer"
|
|
52
48
|
*/
|
|
@@ -100,6 +96,5 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
100
96
|
dispose(): void;
|
|
101
97
|
readonly summarizeOnDemand: ISummarizer["summarizeOnDemand"];
|
|
102
98
|
readonly enqueueSummarize: ISummarizer["enqueueSummarize"];
|
|
103
|
-
private handleSummaryAcks;
|
|
104
99
|
}
|
|
105
100
|
//# sourceMappingURL=summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/summary/summarizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAgB,MAAM,uCAAuC,CAAC;AAI9E,OAAO,EAEN,eAAe,EACf,YAAY,EAEZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAe,mBAAmB,EAAY,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAElF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,4BAA4B,EAC5B,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,MAAM,mBAAmB,CAAC;AAM3B,qBAAa,kBACZ,SAAQ,YACR,YAAW,mBAAmB,EAAE,eAAe;IAKb,QAAQ,CAAC,MAAM,EAAE,OAAO;IAH1D,QAAQ,CAAC,SAAS,sBAAoB;IACtC,QAAQ,CAAC,QAAQ,QAAQ;gBAEb,YAAY,EAAE,MAAM,EAAW,MAAM,GAAE,OAAe;IAIlE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAiB,EAAE,MAAM,EAAE,gBAAgB;CAIzE;AAED,eAAO,MAAM,wBAAwB,iBAAkB,MAAM,UAAU,OAAO,uBACjC,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,YAAa,YAAW,WAAW;IAajE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB;aAElB,iBAAiB,EAAE,iBAAiB;IACpD,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAvBxC,IAAW,WAAW,SAErB;IAED,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;;IAGpE;;OAEG;IACc,OAAO,EAAE,kBAAkB,EAC3B,mBAAmB,EAAE,MAAM,qBAAqB;IACjE;;OAEG;IACc,iBAAiB,EAAE,4BAA4B,EAChE,aAAa,EAAE,mBAAmB,EAClB,iBAAiB,EAAE,iBAAiB,EACnC,sBAAsB,EAAE,CACxC,OAAO,EAAE,mBAAmB,KACxB,OAAO,CAAC,gCAAgC,CAAC;IAM/C;;;;;;;;OAQG;WACiB,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA0BjE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWnE;;;;OAIG;IACI,IAAI,CAAC,MAAM,EAAE,oBAAoB;IAIjC,KAAK;YAOE,OAAO;IAmDrB;;;;;OAKG;WACW,2BAA2B,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO;IAIpF;;;;;;;;OAQG;YACW,KAAK;IAkDnB;;;;;OAKG;IACI,OAAO;IAWd,SAAgB,iBAAiB,EAAE,WAAW,CAAC,mBAAmB,CAAC,CA0DjE;IAEF,SAAgB,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAS/D;CACF"}
|