@fluidframework/container-runtime 2.23.0 → 2.31.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/CHANGELOG.md +593 -537
- package/api-report/container-runtime.legacy.alpha.api.md +0 -246
- package/dist/blobManager/blobManager.d.ts +11 -9
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +38 -39
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts +2 -4
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js +6 -6
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/channelCollection.d.ts +1 -7
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +2 -27
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +0 -43
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +40 -145
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +149 -364
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +6 -14
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +14 -26
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +2 -20
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +0 -2
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +8 -24
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +1 -3
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +1 -4
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +0 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +6 -18
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +0 -29
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +16 -5
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +12 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +41 -21
- package/dist/opLifecycle/outbox.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 +1 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +12 -2
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runCounter.d.ts +11 -0
- package/dist/runCounter.d.ts.map +1 -0
- package/dist/runCounter.js +43 -0
- package/dist/runCounter.js.map +1 -0
- package/dist/runtimeLayerCompatState.d.ts +51 -0
- package/dist/runtimeLayerCompatState.d.ts.map +1 -0
- package/dist/runtimeLayerCompatState.js +123 -0
- package/dist/runtimeLayerCompatState.js.map +1 -0
- package/dist/signalTelemetryProcessing.d.ts +33 -0
- package/dist/signalTelemetryProcessing.d.ts.map +1 -0
- package/dist/signalTelemetryProcessing.js +149 -0
- package/dist/signalTelemetryProcessing.js.map +1 -0
- package/dist/summary/documentSchema.d.ts +7 -31
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +2 -18
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +2 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +7 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -3
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -3
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +2 -7
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +1 -2
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +4 -23
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -5
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +3 -11
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +0 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +4 -4
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -18
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +0 -27
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -2
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +109 -22
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -9
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +3 -9
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryHelpers.d.ts +19 -0
- package/dist/summary/summaryHelpers.d.ts.map +1 -0
- package/dist/summary/summaryHelpers.js +90 -0
- package/dist/summary/summaryHelpers.js.map +1 -0
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +0 -2
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +11 -9
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +37 -37
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts +2 -4
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js +6 -6
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/channelCollection.d.ts +1 -7
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +3 -30
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +0 -43
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +40 -145
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +151 -372
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +6 -14
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +14 -26
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +3 -23
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +0 -2
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +8 -24
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +1 -3
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +1 -4
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +0 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +7 -21
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +0 -29
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +16 -5
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +12 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +43 -23
- package/lib/opLifecycle/outbox.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 +1 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +12 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runCounter.d.ts +11 -0
- package/lib/runCounter.d.ts.map +1 -0
- package/lib/runCounter.js +39 -0
- package/lib/runCounter.js.map +1 -0
- package/lib/runtimeLayerCompatState.d.ts +51 -0
- package/lib/runtimeLayerCompatState.d.ts.map +1 -0
- package/lib/runtimeLayerCompatState.js +118 -0
- package/lib/runtimeLayerCompatState.js.map +1 -0
- package/lib/signalTelemetryProcessing.d.ts +33 -0
- package/lib/signalTelemetryProcessing.d.ts.map +1 -0
- package/lib/signalTelemetryProcessing.js +145 -0
- package/lib/signalTelemetryProcessing.js.map +1 -0
- package/lib/summary/documentSchema.d.ts +7 -31
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +2 -18
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +2 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -0
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -3
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -3
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +2 -7
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +1 -2
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +4 -23
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -5
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +3 -11
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +0 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +2 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +5 -5
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -18
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +1 -25
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -2
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +109 -22
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -9
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +3 -9
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryHelpers.d.ts +19 -0
- package/lib/summary/summaryHelpers.d.ts.map +1 -0
- package/lib/summary/summaryHelpers.js +84 -0
- package/lib/summary/summaryHelpers.js.map +1 -0
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +0 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +20 -23
- package/src/blobManager/blobManager.ts +70 -62
- package/src/blobManager/blobManagerSnapSum.ts +7 -9
- package/src/channelCollection.ts +4 -32
- package/src/connectionTelemetry.ts +0 -51
- package/src/containerRuntime.ts +259 -622
- package/src/dataStoreContext.ts +24 -33
- package/src/gc/{garbageCollection.md → README.md} +17 -19
- package/src/gc/garbageCollection.ts +9 -26
- package/src/gc/gcConfigs.ts +3 -6
- package/src/gc/gcDefinitions.ts +10 -28
- package/src/gc/gcHelpers.ts +0 -5
- package/src/gc/gcSummaryStateTracker.ts +1 -2
- package/src/gc/gcTelemetry.ts +8 -15
- package/src/index.ts +6 -6
- package/src/messageTypes.ts +0 -2
- package/src/opLifecycle/batchManager.ts +20 -6
- package/src/opLifecycle/outbox.ts +64 -24
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +18 -2
- package/src/runCounter.ts +25 -0
- package/src/runtimeLayerCompatState.ts +143 -0
- package/src/signalTelemetryProcessing.ts +233 -0
- package/src/summary/documentSchema.ts +7 -38
- package/src/summary/index.ts +12 -0
- package/src/summary/orderedClientElection.ts +1 -3
- package/src/summary/runWhileConnectedCoordinator.ts +3 -8
- package/src/summary/runningSummarizer.ts +12 -20
- package/src/summary/summarizer.ts +6 -18
- package/src/summary/summarizerClientElection.ts +0 -2
- package/src/summary/summarizerHeuristics.ts +1 -2
- package/src/summary/summarizerNode/summarizerNode.ts +6 -5
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +1 -27
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +2 -3
- package/src/summary/summarizerTypes.ts +119 -23
- package/src/summary/summaryFormat.ts +4 -13
- package/src/summary/summaryGenerator.ts +1 -8
- package/src/summary/summaryHelpers.ts +118 -0
- package/src/summary/summaryManager.ts +0 -2
- package/tsconfig.json +1 -0
- package/dist/layerCompatState.d.ts +0 -19
- package/dist/layerCompatState.d.ts.map +0 -1
- package/dist/layerCompatState.js +0 -64
- package/dist/layerCompatState.js.map +0 -1
- package/lib/layerCompatState.d.ts +0 -19
- package/lib/layerCompatState.d.ts.map +0 -1
- package/lib/layerCompatState.js +0 -60
- package/lib/layerCompatState.js.map +0 -1
- package/prettier.config.cjs +0 -8
- package/src/layerCompatState.ts +0 -75
package/lib/containerRuntime.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { Trace, TypedEventEmitter
|
|
6
|
-
import { AttachState
|
|
7
|
-
import {
|
|
5
|
+
import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
6
|
+
import { AttachState } from "@fluidframework/container-definitions";
|
|
7
|
+
import { isIDeltaManagerFull } from "@fluidframework/container-definitions/internal";
|
|
8
8
|
import { assert, Deferred, LazyPromise, PromiseCache, delay, } from "@fluidframework/core-utils/internal";
|
|
9
|
-
import { SummaryType
|
|
10
|
-
import {
|
|
9
|
+
import { SummaryType } from "@fluidframework/driver-definitions";
|
|
10
|
+
import { FetchSource, MessageType } from "@fluidframework/driver-definitions/internal";
|
|
11
11
|
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
12
12
|
import { FlushMode, FlushModeExperimental, channelsTreeName, gcTreeKey, } from "@fluidframework/runtime-definitions/internal";
|
|
13
|
-
import { GCDataBuilder, RequestParser, TelemetryContext, addBlobToSummary, addSummarizeResultToSummary, calculateStats, create404Response, exceptionToResponse,
|
|
13
|
+
import { GCDataBuilder, RequestParser, TelemetryContext, addBlobToSummary, addSummarizeResultToSummary, calculateStats, create404Response, exceptionToResponse, seqFromTree, } from "@fluidframework/runtime-utils/internal";
|
|
14
14
|
import { DataCorruptionError, DataProcessingError, extractSafePropertiesFromMessage, GenericError, LoggingError, PerformanceEvent,
|
|
15
15
|
// eslint-disable-next-line import/no-deprecated
|
|
16
16
|
TaggedLoggerAdapter, UsageError, createChildLogger, createChildMonitoringContext, createSampledLogger, loggerToMonitoringContext, raiseConnectedEvent, wrapError, tagCodeArtifacts, } from "@fluidframework/telemetry-utils/internal";
|
|
@@ -24,20 +24,16 @@ import { channelToDataStore } from "./dataStore.js";
|
|
|
24
24
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
25
25
|
import { DeltaManagerPendingOpsProxy, DeltaManagerSummarizerProxy, } from "./deltaManagerProxies.js";
|
|
26
26
|
import { DeltaScheduler } from "./deltaScheduler.js";
|
|
27
|
-
import {
|
|
28
|
-
// eslint-disable-next-line import/no-deprecated
|
|
29
|
-
GCNodeType, GarbageCollector, gcGenerationOptionName, } from "./gc/index.js";
|
|
27
|
+
import { GCNodeType, GarbageCollector, gcGenerationOptionName, } from "./gc/index.js";
|
|
30
28
|
import { InboundBatchAggregator } from "./inboundBatchAggregator.js";
|
|
31
|
-
import { RuntimeCompatDetails, validateLoaderCompatibility } from "./layerCompatState.js";
|
|
32
29
|
import { ContainerMessageType, } from "./messageTypes.js";
|
|
33
30
|
import { DuplicateBatchDetector, ensureContentsDeserialized, OpCompressor, OpDecompressor, OpGroupingManager, OpSplitter, Outbox, RemoteMessageProcessor, serializeOpContents, } from "./opLifecycle/index.js";
|
|
34
31
|
import { pkgVersion } from "./packageVersion.js";
|
|
35
32
|
import { PendingStateManager, } from "./pendingStateManager.js";
|
|
36
|
-
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Summarizer, SummarizerClientElection, SummaryCollection, SummaryManager, aliasBlobName, chunksBlobName, recentBatchInfoBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, rootHasIsolatedChannels, summarizerClientType, wrapSummaryInChannelsTree, } from "./summary/index.js";
|
|
33
|
+
import { RunCounter } from "./runCounter.js";
|
|
34
|
+
import { runtimeCompatDetailsForLoader, validateLoaderCompatibility, } from "./runtimeLayerCompatState.js";
|
|
35
|
+
import { SignalTelemetryManager } from "./signalTelemetryProcessing.js";
|
|
36
|
+
import { DocumentsSchemaController, OrderedClientCollection, OrderedClientElection, RetriableSummaryError, RunWhileConnectedCoordinator, Summarizer, SummarizerClientElection, SummaryCollection, SummaryManager, aliasBlobName, chunksBlobName, recentBatchInfoBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, rootHasIsolatedChannels, summarizerClientType, wrapSummaryInChannelsTree, formCreateSummarizerFn, summarizerRequestUrl, validateSummaryHeuristicConfiguration, DefaultSummaryConfiguration, isSummariesDisabled, } from "./summary/index.js";
|
|
41
37
|
import { Throttler, formExponentialFn } from "./throttler.js";
|
|
42
38
|
/**
|
|
43
39
|
* Creates an error object to be thrown / passed to Container's close fn in case of an unknown message type.
|
|
@@ -58,32 +54,9 @@ function getUnknownMessageTypeError(unknownContainerRuntimeMessageType, codePath
|
|
|
58
54
|
},
|
|
59
55
|
});
|
|
60
56
|
}
|
|
61
|
-
export function isSummariesDisabled(config) {
|
|
62
|
-
return config.state === "disabled";
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* @legacy
|
|
66
|
-
* @alpha
|
|
67
|
-
*/
|
|
68
|
-
export const DefaultSummaryConfiguration = {
|
|
69
|
-
state: "enabled",
|
|
70
|
-
minIdleTime: 0,
|
|
71
|
-
maxIdleTime: 30 * 1000, // 30 secs.
|
|
72
|
-
maxTime: 60 * 1000, // 1 min.
|
|
73
|
-
maxOps: 100, // Summarize if 100 weighted ops received since last snapshot.
|
|
74
|
-
minOpsForLastSummaryAttempt: 10,
|
|
75
|
-
maxAckWaitTime: 3 * 60 * 1000, // 3 mins.
|
|
76
|
-
maxOpsSinceLastSummary: 7000,
|
|
77
|
-
initialSummarizerDelayMs: 5 * 1000, // 5 secs.
|
|
78
|
-
nonRuntimeOpWeight: 0.1,
|
|
79
|
-
runtimeOpWeight: 1,
|
|
80
|
-
nonRuntimeHeuristicThreshold: 20,
|
|
81
|
-
};
|
|
82
57
|
/**
|
|
83
58
|
* Error responses when requesting a deleted object will have this header set to true
|
|
84
|
-
* @
|
|
85
|
-
* @alpha
|
|
86
|
-
* @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
|
|
59
|
+
* @internal
|
|
87
60
|
*/
|
|
88
61
|
export const DeletedResponseHeaderKey = "wasDeleted";
|
|
89
62
|
/**
|
|
@@ -199,55 +172,13 @@ export const makeLegacySendBatchFn = (submitFn, deltaManager) => (batch) => {
|
|
|
199
172
|
deltaManager.flush();
|
|
200
173
|
return clientSequenceNumber;
|
|
201
174
|
};
|
|
202
|
-
const summarizerRequestUrl = "_summarizer";
|
|
203
|
-
/**
|
|
204
|
-
* Create and retrieve the summmarizer
|
|
205
|
-
*/
|
|
206
|
-
async function createSummarizer(loader, url) {
|
|
207
|
-
const request = {
|
|
208
|
-
headers: {
|
|
209
|
-
[LoaderHeader.cache]: false,
|
|
210
|
-
[LoaderHeader.clientDetails]: {
|
|
211
|
-
capabilities: { interactive: false },
|
|
212
|
-
type: summarizerClientType,
|
|
213
|
-
},
|
|
214
|
-
[DriverHeader.summarizingClient]: true,
|
|
215
|
-
[LoaderHeader.reconnect]: false,
|
|
216
|
-
},
|
|
217
|
-
url,
|
|
218
|
-
};
|
|
219
|
-
const resolvedContainer = await loader.resolve(request);
|
|
220
|
-
let fluidObject;
|
|
221
|
-
// Older containers may not have the "getEntryPoint" API
|
|
222
|
-
// ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
|
|
223
|
-
if (resolvedContainer.getEntryPoint === undefined) {
|
|
224
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
|
|
225
|
-
const response = (await resolvedContainer.request({
|
|
226
|
-
url: `/${summarizerRequestUrl}`,
|
|
227
|
-
}));
|
|
228
|
-
if (response.status !== 200 || response.mimeType !== "fluid/object") {
|
|
229
|
-
throw responseToException(response, request);
|
|
230
|
-
}
|
|
231
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
232
|
-
fluidObject = response.value;
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
fluidObject = await resolvedContainer.getEntryPoint();
|
|
236
|
-
}
|
|
237
|
-
if (fluidObject?.ISummarizer === undefined) {
|
|
238
|
-
throw new UsageError("Fluid object does not implement ISummarizer");
|
|
239
|
-
}
|
|
240
|
-
return fluidObject.ISummarizer;
|
|
241
|
-
}
|
|
242
175
|
/**
|
|
243
176
|
* Extract last message from the snapshot metadata.
|
|
244
177
|
* Uses legacy property if not using explicit schema control, otherwise uses the new property.
|
|
245
178
|
* This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
|
|
246
179
|
* Please see addMetadataToSummary() as well
|
|
247
180
|
*/
|
|
248
|
-
function lastMessageFromMetadata(
|
|
249
|
-
// eslint-disable-next-line import/no-deprecated
|
|
250
|
-
metadata) {
|
|
181
|
+
function lastMessageFromMetadata(metadata) {
|
|
251
182
|
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
252
183
|
? metadata?.lastMessage
|
|
253
184
|
: metadata?.message;
|
|
@@ -279,7 +210,6 @@ export async function loadContainerRuntime(params) {
|
|
|
279
210
|
return ContainerRuntime.loadRuntime(params);
|
|
280
211
|
}
|
|
281
212
|
const defaultMaxConsecutiveReconnects = 7;
|
|
282
|
-
const defaultTelemetrySignalSampleCount = 100;
|
|
283
213
|
/**
|
|
284
214
|
* Represents the runtime of the container. Contains helper functions/state of the container.
|
|
285
215
|
* It will define the store level mappings.
|
|
@@ -335,15 +265,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
335
265
|
const [chunks, recentBatchInfo, metadata, electedSummarizerData, aliases, serializedIdCompressor,] = await Promise.all([
|
|
336
266
|
tryFetchBlob(chunksBlobName),
|
|
337
267
|
tryFetchBlob(recentBatchInfoBlobName),
|
|
338
|
-
// eslint-disable-next-line import/no-deprecated
|
|
339
268
|
tryFetchBlob(metadataBlobName),
|
|
340
|
-
// eslint-disable-next-line import/no-deprecated
|
|
341
269
|
tryFetchBlob(electedSummarizerBlobName),
|
|
342
270
|
tryFetchBlob(aliasBlobName),
|
|
343
271
|
tryFetchBlob(idCompressorBlobName),
|
|
344
272
|
]);
|
|
345
273
|
// read snapshot blobs needed for BlobManager to load
|
|
346
|
-
const
|
|
274
|
+
const blobManagerLoadInfo = await loadBlobManagerLoadInfo(context);
|
|
347
275
|
const messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
348
276
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
349
277
|
const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
|
|
@@ -447,7 +375,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
447
375
|
};
|
|
448
376
|
const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !== Number.POSITIVE_INFINITY &&
|
|
449
377
|
compressionOptions.compressionAlgorithm === "lz4";
|
|
450
|
-
// eslint-disable-next-line import/no-deprecated
|
|
451
378
|
const documentSchemaController = new DocumentsSchemaController(existing, protocolSequenceNumber, metadata?.documentSchema, {
|
|
452
379
|
explicitSchemaControl,
|
|
453
380
|
compressionLz4,
|
|
@@ -475,7 +402,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
475
402
|
enableGroupedBatching,
|
|
476
403
|
explicitSchemaControl,
|
|
477
404
|
};
|
|
478
|
-
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], internalRuntimeOptions, containerScope, logger, existing,
|
|
405
|
+
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], internalRuntimeOptions, containerScope, logger, existing, blobManagerLoadInfo, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined, // summaryConfiguration
|
|
479
406
|
recentBatchInfo);
|
|
480
407
|
runtime.blobManager.stashedBlobsUploadP.then(() => {
|
|
481
408
|
// make sure we didn't reconnect before the promise resolved
|
|
@@ -559,18 +486,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
559
486
|
* Invokes the given callback and expects that no ops are submitted
|
|
560
487
|
* until execution finishes. If an op is submitted, an error will be raised.
|
|
561
488
|
*
|
|
562
|
-
* Can be disabled by feature gate `Fluid.ContainerRuntime.DisableOpReentryCheck`
|
|
563
|
-
*
|
|
564
489
|
* @param callback - the callback to be invoked
|
|
565
490
|
*/
|
|
566
491
|
ensureNoDataModelChanges(callback) {
|
|
567
|
-
this.
|
|
568
|
-
try {
|
|
569
|
-
return callback();
|
|
570
|
-
}
|
|
571
|
-
finally {
|
|
572
|
-
this.ensureNoDataModelChangesCalls--;
|
|
573
|
-
}
|
|
492
|
+
return this.dataModelChangeRunner.run(callback);
|
|
574
493
|
}
|
|
575
494
|
get connected() {
|
|
576
495
|
return this._connected;
|
|
@@ -600,27 +519,23 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
600
519
|
get gcThrowOnTombstoneUsage() {
|
|
601
520
|
return false;
|
|
602
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* The compatibility details of the Runtime layer that is exposed to the Loader layer
|
|
524
|
+
* for validating Loader-Runtime compatibility.
|
|
525
|
+
*/
|
|
603
526
|
get ILayerCompatDetails() {
|
|
604
|
-
return
|
|
527
|
+
return runtimeCompatDetailsForLoader;
|
|
605
528
|
}
|
|
606
529
|
/***/
|
|
607
|
-
constructor(context, registry,
|
|
608
|
-
// eslint-disable-next-line import/no-deprecated
|
|
609
|
-
metadata,
|
|
610
|
-
// eslint-disable-next-line import/no-deprecated
|
|
611
|
-
electedSummarizerData, chunks, dataStoreAliasMap, baseRuntimeOptions, containerScope,
|
|
530
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope,
|
|
612
531
|
// Create a custom ITelemetryBaseLogger to output telemetry events.
|
|
613
|
-
baseLogger, existing,
|
|
614
|
-
// eslint-disable-next-line import/no-deprecated
|
|
615
|
-
blobManagerSnapshot, _storage, createIdCompressor,
|
|
616
|
-
// eslint-disable-next-line import/no-deprecated
|
|
617
|
-
documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler,
|
|
532
|
+
baseLogger, existing, blobManagerLoadInfo, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler,
|
|
618
533
|
// eslint-disable-next-line unicorn/no-object-as-default-parameter
|
|
619
534
|
summaryConfiguration = {
|
|
620
535
|
// the defaults
|
|
621
536
|
...DefaultSummaryConfiguration,
|
|
622
537
|
// the runtime configuration overrides
|
|
623
|
-
...
|
|
538
|
+
...runtimeOptions.summaryOptions?.summaryConfigOverrides,
|
|
624
539
|
}, recentBatchInfo) {
|
|
625
540
|
super();
|
|
626
541
|
this.registry = registry;
|
|
@@ -635,23 +550,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
635
550
|
// We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
|
|
636
551
|
// Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
|
|
637
552
|
this.pendingIdCompressorOps = [];
|
|
638
|
-
this.
|
|
553
|
+
this.batchRunner = new RunCounter();
|
|
639
554
|
this.flushTaskExists = false;
|
|
640
555
|
this.consecutiveReconnects = 0;
|
|
641
|
-
this.
|
|
556
|
+
this.dataModelChangeRunner = new RunCounter();
|
|
642
557
|
this._disposed = false;
|
|
643
558
|
this.emitDirtyDocumentEvent = true;
|
|
644
|
-
this.
|
|
645
|
-
totalSignalsSentInLatencyWindow: 0,
|
|
646
|
-
signalsLost: 0,
|
|
647
|
-
signalsOutOfOrder: 0,
|
|
648
|
-
signalsSentSinceLastLatencyMeasurement: 0,
|
|
649
|
-
broadcastSignalSequenceNumber: 0,
|
|
650
|
-
signalTimestamp: 0,
|
|
651
|
-
roundTripSignalSequenceNumber: undefined,
|
|
652
|
-
trackingSignalSequenceNumber: undefined,
|
|
653
|
-
minimumTrackingSignalSequenceNumber: undefined,
|
|
654
|
-
};
|
|
559
|
+
this.signalTelemetryManager = new SignalTelemetryManager();
|
|
655
560
|
/**
|
|
656
561
|
* It a cache for holding mapping for loading groupIds with its snapshot from the service. Add expiry policy of 1 minute.
|
|
657
562
|
* Starting with 1 min and based on recorded usage we can tweak it later on.
|
|
@@ -663,13 +568,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
663
568
|
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, snapshotWithContents, } = context;
|
|
664
569
|
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
665
570
|
this.disposeFn = disposeFn ?? closeFn;
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
const runtimeOptions = {
|
|
670
|
-
flushMode: defaultFlushMode,
|
|
671
|
-
...baseRuntimeOptions,
|
|
672
|
-
};
|
|
571
|
+
// Validate that the Loader is compatible with this Runtime.
|
|
572
|
+
const maybeloaderCompatDetailsForRuntime = context;
|
|
573
|
+
validateLoaderCompatibility(maybeloaderCompatDetailsForRuntime.ILayerCompatDetails, this.disposeFn);
|
|
673
574
|
this.mc = createChildMonitoringContext({
|
|
674
575
|
logger: this.baseLogger,
|
|
675
576
|
namespace: "ContainerRuntime",
|
|
@@ -717,6 +618,22 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
717
618
|
// customer should observe dirty state on the runtime (the owner of dirty state) directly, rather than on the IContainer.
|
|
718
619
|
this.on("dirty", () => context.updateDirtyContainerState(true));
|
|
719
620
|
this.on("saved", () => context.updateDirtyContainerState(false));
|
|
621
|
+
// Telemetry for when the container is attached and subsequently saved for the first time.
|
|
622
|
+
// These events are useful for investigating the validity of container "saved" eventing upon attach.
|
|
623
|
+
// See this.setAttachState() and this.updateDocumentDirtyState() for more details on "attached" and "saved" events.
|
|
624
|
+
this.once("attached", () => {
|
|
625
|
+
this.mc.logger.sendTelemetryEvent({
|
|
626
|
+
eventName: "Attached",
|
|
627
|
+
details: {
|
|
628
|
+
dirtyContainer: this.dirtyContainer,
|
|
629
|
+
hasPendingMessages: this.hasPendingMessages(),
|
|
630
|
+
},
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
this.once("saved", () => this.mc.logger.sendTelemetryEvent({
|
|
634
|
+
eventName: "Saved",
|
|
635
|
+
details: { attachState: this.attachState },
|
|
636
|
+
}));
|
|
720
637
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
721
638
|
this.closeFn = isSummarizerClient ? this.disposeFn : closeFn;
|
|
722
639
|
let loadSummaryNumber;
|
|
@@ -781,7 +698,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
781
698
|
this._deltaManager = outerDeltaManager;
|
|
782
699
|
this.handleContext = new ContainerFluidHandleContext("", this);
|
|
783
700
|
if (summaryConfiguration.state === "enabled") {
|
|
784
|
-
|
|
701
|
+
validateSummaryHeuristicConfiguration(summaryConfiguration);
|
|
785
702
|
}
|
|
786
703
|
this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
|
|
787
704
|
const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(summaryConfiguration)
|
|
@@ -798,7 +715,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
798
715
|
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? defaultMaxConsecutiveReconnects;
|
|
799
716
|
// If the context has ILayerCompatDetails, it supports referenceSequenceNumbers since that features
|
|
800
717
|
// predates ILayerCompatDetails.
|
|
801
|
-
const referenceSequenceNumbersSupported =
|
|
718
|
+
const referenceSequenceNumbersSupported = maybeloaderCompatDetailsForRuntime.ILayerCompatDetails === undefined
|
|
802
719
|
? supportedFeatures?.get("referenceSequenceNumbers") === true
|
|
803
720
|
: true;
|
|
804
721
|
if (runtimeOptions.flushMode === FlushModeExperimental.Async &&
|
|
@@ -879,9 +796,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
879
796
|
// what is the interface of passing signals, we need the
|
|
880
797
|
// downstream stores to wrap the signal.
|
|
881
798
|
parentContext.submitSignal = (type, content, targetClientId) => {
|
|
799
|
+
// Future: Can the `content` argument type be IEnvelope?
|
|
800
|
+
// verifyNotClosed is called in FluidDataStoreContext, which is *the* expected caller.
|
|
882
801
|
const envelope1 = content;
|
|
883
|
-
const envelope2 =
|
|
884
|
-
|
|
802
|
+
const envelope2 = createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
|
|
803
|
+
if (targetClientId === undefined) {
|
|
804
|
+
this.signalTelemetryManager.applyTrackingToBroadcastSignalEnvelope(envelope2);
|
|
805
|
+
}
|
|
806
|
+
this.submitSignalFn(envelope2, targetClientId);
|
|
885
807
|
};
|
|
886
808
|
let snapshot = getSummaryForDatastores(baseSnapshot, metadata);
|
|
887
809
|
if (snapshot !== undefined && snapshotWithContents !== undefined) {
|
|
@@ -896,8 +818,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
896
818
|
}), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap), async (runtime) => provideEntryPoint);
|
|
897
819
|
this.blobManager = new BlobManager({
|
|
898
820
|
routeContext: this.handleContext,
|
|
899
|
-
|
|
900
|
-
|
|
821
|
+
blobManagerLoadInfo,
|
|
822
|
+
storage: this.storage,
|
|
901
823
|
sendBlobAttachOp: (localId, blobId) => {
|
|
902
824
|
if (!this.disposed) {
|
|
903
825
|
this.submit({ type: ContainerMessageType.BlobAttach, contents: undefined }, undefined, {
|
|
@@ -917,8 +839,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
917
839
|
});
|
|
918
840
|
this.deltaScheduler = new DeltaScheduler(this.innerDeltaManager, this, createChildLogger({ logger: this.baseLogger, namespace: "DeltaScheduler" }));
|
|
919
841
|
this.inboundBatchAggregator = new InboundBatchAggregator(this.innerDeltaManager, () => this.clientId, createChildLogger({ logger: this.baseLogger, namespace: "InboundBatchAggregator" }));
|
|
920
|
-
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
921
842
|
const legacySendBatchFn = makeLegacySendBatchFn(submitFn, this.innerDeltaManager);
|
|
843
|
+
this.disableFlushBeforeProcess =
|
|
844
|
+
this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableFlushBeforeProcess") === true;
|
|
922
845
|
this.outbox = new Outbox({
|
|
923
846
|
shouldSend: () => this.canSendOps(),
|
|
924
847
|
pendingStateManager: this.pendingStateManager,
|
|
@@ -929,16 +852,18 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
929
852
|
config: {
|
|
930
853
|
compressionOptions,
|
|
931
854
|
maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
|
|
932
|
-
|
|
855
|
+
// If we disable flush before process, we must be ready to flush partial batches
|
|
856
|
+
flushPartialBatches: this.disableFlushBeforeProcess,
|
|
933
857
|
},
|
|
934
858
|
logger: this.mc.logger,
|
|
935
859
|
groupingManager: opGroupingManager,
|
|
936
860
|
getCurrentSequenceNumbers: () => ({
|
|
861
|
+
// Note: These sequence numbers only change when DeltaManager processes an incoming op
|
|
937
862
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
938
863
|
clientSequenceNumber: this._processedClientSequenceNumber,
|
|
939
864
|
}),
|
|
940
865
|
reSubmit: this.reSubmit.bind(this),
|
|
941
|
-
opReentrancy: () => this.
|
|
866
|
+
opReentrancy: () => this.dataModelChangeRunner.running,
|
|
942
867
|
closeContainer: this.closeFn,
|
|
943
868
|
});
|
|
944
869
|
this._quorum = quorum;
|
|
@@ -985,10 +910,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
985
910
|
const orderedClientElectionForSummarizer = new OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, SummarizerClientElection.isClientEligible, this.mc.config.getBoolean("Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents"));
|
|
986
911
|
this.summarizerClientElection = new SummarizerClientElection(orderedClientLogger, summaryCollection, orderedClientElectionForSummarizer, maxOpsSinceLastSummary);
|
|
987
912
|
if (isSummarizerClient) {
|
|
988
|
-
|
|
989
|
-
this._summarizer = new Summarizer(this /* ISummarizerRuntime */, () => summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, summaryCollection,
|
|
990
|
-
// eslint-disable-next-line import/no-deprecated
|
|
991
|
-
async (runtime) => RunWhileConnectedCoordinator.create(runtime,
|
|
913
|
+
this._summarizer = new Summarizer(this /* ISummarizerRuntime */, () => summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, summaryCollection, async (runtime) => RunWhileConnectedCoordinator.create(runtime,
|
|
992
914
|
// Summarization runs in summarizer client and needs access to the real (non-proxy) active
|
|
993
915
|
// information. The proxy delta manager would always return false for summarizer client.
|
|
994
916
|
() => this.innerDeltaManager.active));
|
|
@@ -1016,7 +938,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1016
938
|
summaryCollection.on("default", defaultAction);
|
|
1017
939
|
// Create the SummaryManager and mark the initial state
|
|
1018
940
|
this.summaryManager = new SummaryManager(this.summarizerClientElection, this, // IConnectedState
|
|
1019
|
-
summaryCollection, this.baseLogger,
|
|
941
|
+
summaryCollection, this.baseLogger, formCreateSummarizerFn(loader), new Throttler(60 * 1000, // 60 sec delay window
|
|
1020
942
|
30 * 1000, // 30 sec max delay
|
|
1021
943
|
// throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
|
|
1022
944
|
formExponentialFn({ coefficient: 20, initialDelay: 0 })), {
|
|
@@ -1051,14 +973,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1051
973
|
summaryFormatVersion: metadata?.summaryFormatVersion,
|
|
1052
974
|
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
1053
975
|
gcVersion: metadata?.gcFeature,
|
|
1054
|
-
options: JSON.stringify(
|
|
976
|
+
options: JSON.stringify(runtimeOptions),
|
|
1055
977
|
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
1056
978
|
idCompressorMode: this.sessionSchema.idCompressorMode,
|
|
1057
979
|
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
1058
980
|
featureGates: JSON.stringify({
|
|
1059
981
|
...featureGatesForTelemetry,
|
|
1060
|
-
disablePartialFlush,
|
|
1061
982
|
closeSummarizerDelayOverride,
|
|
983
|
+
disableFlushBeforeProcess: this.disableFlushBeforeProcess,
|
|
1062
984
|
}),
|
|
1063
985
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
1064
986
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
@@ -1076,7 +998,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1076
998
|
// saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
|
|
1077
999
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
1078
1000
|
}
|
|
1079
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1080
1001
|
onSchemaChange(schema) {
|
|
1081
1002
|
this.mc.logger.sendTelemetryEvent({
|
|
1082
1003
|
eventName: "SchemaChangeAccept",
|
|
@@ -1287,13 +1208,11 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1287
1208
|
}
|
|
1288
1209
|
if (id === blobManagerBasePath && requestParser.isLeaf(2)) {
|
|
1289
1210
|
const blob = await this.blobManager.getBlob(requestParser.pathParts[1]);
|
|
1290
|
-
return
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
}
|
|
1296
|
-
: create404Response(request);
|
|
1211
|
+
return {
|
|
1212
|
+
status: 200,
|
|
1213
|
+
mimeType: "fluid/object",
|
|
1214
|
+
value: blob,
|
|
1215
|
+
};
|
|
1297
1216
|
}
|
|
1298
1217
|
else if (requestParser.pathParts.length > 0) {
|
|
1299
1218
|
return await this.channelCollection.request(request);
|
|
@@ -1324,7 +1243,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1324
1243
|
const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
|
|
1325
1244
|
// Is document schema explicit control on?
|
|
1326
1245
|
const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
1327
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1328
1246
|
const metadata = {
|
|
1329
1247
|
...this.createContainerMetadata,
|
|
1330
1248
|
// Increment the summary number for the next summary that will be generated.
|
|
@@ -1338,8 +1256,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1338
1256
|
// last message's sequence number.
|
|
1339
1257
|
// See also lastMessageFromMetadata()
|
|
1340
1258
|
message: explicitSchemaControl
|
|
1341
|
-
?
|
|
1342
|
-
{ sequenceNumber: -1 }
|
|
1259
|
+
? { sequenceNumber: -1 }
|
|
1343
1260
|
: message,
|
|
1344
1261
|
lastMessage: explicitSchemaControl ? message : undefined,
|
|
1345
1262
|
documentSchema,
|
|
@@ -1561,14 +1478,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1561
1478
|
if (connected) {
|
|
1562
1479
|
assert(this.attachState === AttachState.Attached, 0x3cd /* Connection is possible only if container exists in storage */);
|
|
1563
1480
|
if (changeOfState) {
|
|
1564
|
-
this.
|
|
1565
|
-
this._signalTracking.signalsOutOfOrder = 0;
|
|
1566
|
-
this._signalTracking.signalTimestamp = 0;
|
|
1567
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement = 0;
|
|
1568
|
-
this._signalTracking.totalSignalsSentInLatencyWindow = 0;
|
|
1569
|
-
this._signalTracking.roundTripSignalSequenceNumber = undefined;
|
|
1570
|
-
this._signalTracking.trackingSignalSequenceNumber = undefined;
|
|
1571
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber = undefined;
|
|
1481
|
+
this.signalTelemetryManager.resetTracking();
|
|
1572
1482
|
}
|
|
1573
1483
|
}
|
|
1574
1484
|
// Fail while disconnected
|
|
@@ -1602,6 +1512,21 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1602
1512
|
// spread operator above ensure we make a shallow copy of message, as the processing flow will modify it.
|
|
1603
1513
|
// There might be multiple container instances receiving the same message.
|
|
1604
1514
|
this.verifyNotClosed();
|
|
1515
|
+
if (!this.disableFlushBeforeProcess) {
|
|
1516
|
+
// Reference Sequence Number may be about to change, and it must be consistent across a batch, so flush now
|
|
1517
|
+
this.outbox.flush();
|
|
1518
|
+
}
|
|
1519
|
+
this.ensureNoDataModelChanges(() => {
|
|
1520
|
+
this.processInboundMessageOrBatch(messageCopy, local);
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Implementation of core logic for {@link ContainerRuntime.process}, once preconditions are established
|
|
1525
|
+
*
|
|
1526
|
+
* @param messageCopy - Shallow copy of the sequenced message. If it's a virtualized batch, we'll process
|
|
1527
|
+
* all messages in the batch here.
|
|
1528
|
+
*/
|
|
1529
|
+
processInboundMessageOrBatch(messageCopy, local) {
|
|
1605
1530
|
// Whether or not the message appears to be a runtime message from an up-to-date client.
|
|
1606
1531
|
// It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
|
|
1607
1532
|
// or something different, like a system message.
|
|
@@ -1710,9 +1635,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1710
1635
|
try {
|
|
1711
1636
|
if (!runtimeBatch) {
|
|
1712
1637
|
for (const { message } of messagesWithMetadata) {
|
|
1713
|
-
this.
|
|
1714
|
-
this.observeNonRuntimeMessage(message);
|
|
1715
|
-
});
|
|
1638
|
+
this.observeNonRuntimeMessage(message);
|
|
1716
1639
|
}
|
|
1717
1640
|
return;
|
|
1718
1641
|
}
|
|
@@ -1732,29 +1655,23 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1732
1655
|
if (!groupedBatch) {
|
|
1733
1656
|
for (const { message, localOpMetadata } of messagesWithMetadata) {
|
|
1734
1657
|
updateSequenceNumbers(message);
|
|
1735
|
-
this.
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
this.emit("op", message, true /* runtimeMessage */);
|
|
1744
|
-
});
|
|
1658
|
+
this.validateAndProcessRuntimeMessages(message, [
|
|
1659
|
+
{
|
|
1660
|
+
contents: message.contents,
|
|
1661
|
+
localOpMetadata,
|
|
1662
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
1663
|
+
},
|
|
1664
|
+
], local, savedOp);
|
|
1665
|
+
this.emit("op", message, true /* runtimeMessage */);
|
|
1745
1666
|
}
|
|
1746
1667
|
return;
|
|
1747
1668
|
}
|
|
1748
1669
|
let bunchedMessagesContent = [];
|
|
1749
1670
|
let previousMessage;
|
|
1750
1671
|
// Process the previous bunch of messages.
|
|
1751
|
-
const
|
|
1672
|
+
const processBunchedMessages = () => {
|
|
1752
1673
|
assert(previousMessage !== undefined, 0xa67 /* previous message must exist */);
|
|
1753
|
-
this.
|
|
1754
|
-
this.validateAndProcessRuntimeMessages(
|
|
1755
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1756
|
-
previousMessage, bunchedMessagesContent, local, savedOp);
|
|
1757
|
-
});
|
|
1674
|
+
this.validateAndProcessRuntimeMessages(previousMessage, bunchedMessagesContent, local, savedOp);
|
|
1758
1675
|
bunchedMessagesContent = [];
|
|
1759
1676
|
};
|
|
1760
1677
|
/**
|
|
@@ -1765,7 +1682,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1765
1682
|
for (const { message, localOpMetadata } of messagesWithMetadata) {
|
|
1766
1683
|
const currentMessage = updateSequenceNumbers(message);
|
|
1767
1684
|
if (previousMessage && previousMessage.type !== currentMessage.type) {
|
|
1768
|
-
|
|
1685
|
+
processBunchedMessages();
|
|
1769
1686
|
}
|
|
1770
1687
|
previousMessage = currentMessage;
|
|
1771
1688
|
bunchedMessagesContent.push({
|
|
@@ -1775,7 +1692,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1775
1692
|
});
|
|
1776
1693
|
}
|
|
1777
1694
|
// Process the last bunch of messages.
|
|
1778
|
-
|
|
1695
|
+
processBunchedMessages();
|
|
1779
1696
|
// Send the "op" events for the messages now that the ops have been processed.
|
|
1780
1697
|
for (const { message } of messagesWithMetadata) {
|
|
1781
1698
|
this.emit("op", message, true /* runtimeMessage */);
|
|
@@ -1867,9 +1784,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1867
1784
|
break;
|
|
1868
1785
|
}
|
|
1869
1786
|
case ContainerMessageType.DocumentSchemaChange: {
|
|
1870
|
-
this.documentsSchemaController.processDocumentSchemaMessages(
|
|
1871
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1872
|
-
contents, local, message.sequenceNumber);
|
|
1787
|
+
this.documentsSchemaController.processDocumentSchemaMessages(contents, local, message.sequenceNumber);
|
|
1873
1788
|
break;
|
|
1874
1789
|
}
|
|
1875
1790
|
default: {
|
|
@@ -1899,90 +1814,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1899
1814
|
}
|
|
1900
1815
|
}
|
|
1901
1816
|
}
|
|
1902
|
-
/**
|
|
1903
|
-
* Emits the Signal event and update the perf signal data.
|
|
1904
|
-
*/
|
|
1905
|
-
sendSignalTelemetryEvent() {
|
|
1906
|
-
const duration = Date.now() - this._signalTracking.signalTimestamp;
|
|
1907
|
-
this.mc.logger.sendPerformanceEvent({
|
|
1908
|
-
eventName: "SignalLatency",
|
|
1909
|
-
details: {
|
|
1910
|
-
duration, // Roundtrip duration of the tracked signal in milliseconds.
|
|
1911
|
-
sent: this._signalTracking.totalSignalsSentInLatencyWindow, // Signals sent since the last logged SignalLatency event.
|
|
1912
|
-
lost: this._signalTracking.signalsLost, // Signals lost since the last logged SignalLatency event.
|
|
1913
|
-
outOfOrder: this._signalTracking.signalsOutOfOrder, // Out of order signals since the last logged SignalLatency event.
|
|
1914
|
-
reconnectCount: this.consecutiveReconnects, // Container reconnect count.
|
|
1915
|
-
},
|
|
1916
|
-
});
|
|
1917
|
-
this._signalTracking.signalsLost = 0;
|
|
1918
|
-
this._signalTracking.signalsOutOfOrder = 0;
|
|
1919
|
-
this._signalTracking.signalTimestamp = 0;
|
|
1920
|
-
this._signalTracking.totalSignalsSentInLatencyWindow = 0;
|
|
1921
|
-
}
|
|
1922
|
-
/**
|
|
1923
|
-
* Updates signal telemetry including emitting telemetry events.
|
|
1924
|
-
*/
|
|
1925
|
-
processSignalForTelemetry(envelope) {
|
|
1926
|
-
const { clientBroadcastSignalSequenceNumber, contents: envelopeContents, address: envelopeAddress, } = envelope;
|
|
1927
|
-
if (clientBroadcastSignalSequenceNumber === undefined) {
|
|
1928
|
-
return;
|
|
1929
|
-
}
|
|
1930
|
-
if (this._signalTracking.trackingSignalSequenceNumber === undefined ||
|
|
1931
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber === undefined) {
|
|
1932
|
-
return;
|
|
1933
|
-
}
|
|
1934
|
-
if (clientBroadcastSignalSequenceNumber >= this._signalTracking.trackingSignalSequenceNumber) {
|
|
1935
|
-
// Calculate the number of signals lost and log the event.
|
|
1936
|
-
const signalsLost = clientBroadcastSignalSequenceNumber -
|
|
1937
|
-
this._signalTracking.trackingSignalSequenceNumber;
|
|
1938
|
-
if (signalsLost > 0) {
|
|
1939
|
-
this._signalTracking.signalsLost += signalsLost;
|
|
1940
|
-
this.mc.logger.sendErrorEvent({
|
|
1941
|
-
eventName: "SignalLost",
|
|
1942
|
-
details: {
|
|
1943
|
-
signalsLost, // Number of lost signals detected.
|
|
1944
|
-
expectedSequenceNumber: this._signalTracking.trackingSignalSequenceNumber, // The next expected signal sequence number.
|
|
1945
|
-
clientBroadcastSignalSequenceNumber, // Actual signal sequence number received.
|
|
1946
|
-
},
|
|
1947
|
-
});
|
|
1948
|
-
}
|
|
1949
|
-
// Update the tracking signal sequence number to the next expected signal in the sequence.
|
|
1950
|
-
this._signalTracking.trackingSignalSequenceNumber =
|
|
1951
|
-
clientBroadcastSignalSequenceNumber + 1;
|
|
1952
|
-
}
|
|
1953
|
-
else if (
|
|
1954
|
-
// Check if this is a signal in range of interest.
|
|
1955
|
-
clientBroadcastSignalSequenceNumber >=
|
|
1956
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber) {
|
|
1957
|
-
this._signalTracking.signalsOutOfOrder++;
|
|
1958
|
-
const details = {
|
|
1959
|
-
expectedSequenceNumber: this._signalTracking.trackingSignalSequenceNumber, // The next expected signal sequence number.
|
|
1960
|
-
clientBroadcastSignalSequenceNumber, // Sequence number of the out of order signal.
|
|
1961
|
-
};
|
|
1962
|
-
// Only log `contents.type` when address is for container to avoid
|
|
1963
|
-
// chance that contents type is customer data.
|
|
1964
|
-
if (envelopeAddress === undefined) {
|
|
1965
|
-
details.contentsType = envelopeContents.type; // Type of signal that was received out of order.
|
|
1966
|
-
}
|
|
1967
|
-
this.mc.logger.sendTelemetryEvent({
|
|
1968
|
-
eventName: "SignalOutOfOrder",
|
|
1969
|
-
details,
|
|
1970
|
-
});
|
|
1971
|
-
}
|
|
1972
|
-
if (this._signalTracking.roundTripSignalSequenceNumber !== undefined &&
|
|
1973
|
-
clientBroadcastSignalSequenceNumber >= this._signalTracking.roundTripSignalSequenceNumber) {
|
|
1974
|
-
if (clientBroadcastSignalSequenceNumber ===
|
|
1975
|
-
this._signalTracking.roundTripSignalSequenceNumber) {
|
|
1976
|
-
// Latency tracked signal has been received.
|
|
1977
|
-
// We now log the roundtrip duration of the tracked signal.
|
|
1978
|
-
// This telemetry event also logs metrics for broadcast signals
|
|
1979
|
-
// sent, lost, and out of order.
|
|
1980
|
-
// These metrics are reset after logging the telemetry event.
|
|
1981
|
-
this.sendSignalTelemetryEvent();
|
|
1982
|
-
}
|
|
1983
|
-
this._signalTracking.roundTripSignalSequenceNumber = undefined;
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
1817
|
processSignal(message, local) {
|
|
1987
1818
|
const envelope = message.content;
|
|
1988
1819
|
const transformed = {
|
|
@@ -1993,7 +1824,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1993
1824
|
};
|
|
1994
1825
|
// Only collect signal telemetry for broadcast messages sent by the current client.
|
|
1995
1826
|
if (message.clientId === this.clientId) {
|
|
1996
|
-
this.
|
|
1827
|
+
this.signalTelemetryManager.trackReceivedSignal(envelope, this.mc.logger, this.consecutiveReconnects);
|
|
1997
1828
|
}
|
|
1998
1829
|
if (envelope.address === undefined) {
|
|
1999
1830
|
// No address indicates a container signal message.
|
|
@@ -2017,7 +1848,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2017
1848
|
* with the given Batch ID, which must be preserved
|
|
2018
1849
|
*/
|
|
2019
1850
|
flush(resubmittingBatchId) {
|
|
2020
|
-
assert(this.
|
|
1851
|
+
assert(!this.batchRunner.running, 0x24c /* "Cannot call `flush()` while manually accumulating a batch (e.g. under orderSequentially) */);
|
|
2021
1852
|
this.outbox.flush(resubmittingBatchId);
|
|
2022
1853
|
assert(this.outbox.isEmpty, 0x3cf /* reentrancy */);
|
|
2023
1854
|
}
|
|
@@ -2026,43 +1857,45 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2026
1857
|
*/
|
|
2027
1858
|
orderSequentially(callback) {
|
|
2028
1859
|
let checkpoint;
|
|
2029
|
-
|
|
1860
|
+
const checkpointDirtyState = this.dirtyContainer;
|
|
2030
1861
|
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
2031
1862
|
// Note: we are not touching any batches other than mainBatch here, for two reasons:
|
|
2032
1863
|
// 1. It would not help, as other batches are flushed independently from main batch.
|
|
2033
1864
|
// 2. There is no way to undo process of data store creation, blob creation, ID compressor ops, or other things tracked by other batches.
|
|
2034
1865
|
checkpoint = this.outbox.getBatchCheckpoints().mainBatch;
|
|
2035
1866
|
}
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
1867
|
+
const result = this.batchRunner.run(() => {
|
|
1868
|
+
try {
|
|
1869
|
+
return callback();
|
|
1870
|
+
}
|
|
1871
|
+
catch (error) {
|
|
1872
|
+
if (checkpoint) {
|
|
1873
|
+
// This will throw and close the container if rollback fails
|
|
1874
|
+
try {
|
|
1875
|
+
checkpoint.rollback((message) => this.rollback(message.contents, message.localOpMetadata));
|
|
1876
|
+
// reset the dirty state after rollback to what it was before to keep it consistent
|
|
1877
|
+
if (this.dirtyContainer !== checkpointDirtyState) {
|
|
1878
|
+
this.updateDocumentDirtyState(checkpointDirtyState);
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
catch (error_) {
|
|
1882
|
+
const error2 = wrapError(error_, (message) => {
|
|
1883
|
+
return DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
|
|
1884
|
+
});
|
|
1885
|
+
this.closeFn(error2);
|
|
1886
|
+
throw error2;
|
|
1887
|
+
}
|
|
2045
1888
|
}
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
});
|
|
2050
|
-
this.closeFn(error2);
|
|
2051
|
-
throw error2;
|
|
1889
|
+
else {
|
|
1890
|
+
this.closeFn(wrapError(error, (errorMessage) => new GenericError(`orderSequentially callback exception: ${errorMessage}`, error, {
|
|
1891
|
+
orderSequentiallyCalls: this.batchRunner.runs,
|
|
1892
|
+
})));
|
|
2052
1893
|
}
|
|
1894
|
+
throw error; // throw the original error for the consumer of the runtime
|
|
2053
1895
|
}
|
|
2054
|
-
|
|
2055
|
-
this.closeFn(wrapError(error, (errorMessage) => new GenericError(`orderSequentially callback exception: ${errorMessage}`, error, {
|
|
2056
|
-
orderSequentiallyCalls: this._orderSequentiallyCalls,
|
|
2057
|
-
})));
|
|
2058
|
-
}
|
|
2059
|
-
throw error; // throw the original error for the consumer of the runtime
|
|
2060
|
-
}
|
|
2061
|
-
finally {
|
|
2062
|
-
this._orderSequentiallyCalls--;
|
|
2063
|
-
}
|
|
1896
|
+
});
|
|
2064
1897
|
// We don't flush on TurnBased since we expect all messages in the same JS turn to be part of the same batch
|
|
2065
|
-
if (this.flushMode !== FlushMode.TurnBased && this.
|
|
1898
|
+
if (this.flushMode !== FlushMode.TurnBased && !this.batchRunner.running) {
|
|
2066
1899
|
this.flush();
|
|
2067
1900
|
}
|
|
2068
1901
|
return result;
|
|
@@ -2117,7 +1950,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2117
1950
|
* Typically ops are batched and later flushed together, but in some cases we want to flush immediately.
|
|
2118
1951
|
*/
|
|
2119
1952
|
currentlyBatching() {
|
|
2120
|
-
return this.flushMode !== FlushMode.Immediate || this.
|
|
1953
|
+
return this.flushMode !== FlushMode.Immediate || this.batchRunner.running;
|
|
2121
1954
|
}
|
|
2122
1955
|
getQuorum() {
|
|
2123
1956
|
return this._quorum;
|
|
@@ -2161,43 +1994,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2161
1994
|
}
|
|
2162
1995
|
return true;
|
|
2163
1996
|
}
|
|
2164
|
-
createNewSignalEnvelope(address, type, content) {
|
|
2165
|
-
const newEnvelope = {
|
|
2166
|
-
address,
|
|
2167
|
-
contents: { type, content },
|
|
2168
|
-
};
|
|
2169
|
-
return newEnvelope;
|
|
2170
|
-
}
|
|
2171
|
-
submitEnvelopedSignal(envelope, targetClientId) {
|
|
2172
|
-
const isBroadcastSignal = targetClientId === undefined;
|
|
2173
|
-
if (isBroadcastSignal) {
|
|
2174
|
-
const clientBroadcastSignalSequenceNumber = ++this._signalTracking
|
|
2175
|
-
.broadcastSignalSequenceNumber;
|
|
2176
|
-
// Stamp with the broadcast signal sequence number.
|
|
2177
|
-
envelope.clientBroadcastSignalSequenceNumber = clientBroadcastSignalSequenceNumber;
|
|
2178
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement++;
|
|
2179
|
-
if (this._signalTracking.minimumTrackingSignalSequenceNumber === undefined ||
|
|
2180
|
-
this._signalTracking.trackingSignalSequenceNumber === undefined) {
|
|
2181
|
-
// Signal monitoring window is undefined
|
|
2182
|
-
// Initialize tracking to expect the next signal sent by the connected client.
|
|
2183
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber =
|
|
2184
|
-
clientBroadcastSignalSequenceNumber;
|
|
2185
|
-
this._signalTracking.trackingSignalSequenceNumber =
|
|
2186
|
-
clientBroadcastSignalSequenceNumber;
|
|
2187
|
-
}
|
|
2188
|
-
// We should not track the round trip of a new signal in the case we are already tracking one.
|
|
2189
|
-
if (clientBroadcastSignalSequenceNumber % defaultTelemetrySignalSampleCount === 1 &&
|
|
2190
|
-
this._signalTracking.roundTripSignalSequenceNumber === undefined) {
|
|
2191
|
-
this._signalTracking.signalTimestamp = Date.now();
|
|
2192
|
-
this._signalTracking.roundTripSignalSequenceNumber =
|
|
2193
|
-
clientBroadcastSignalSequenceNumber;
|
|
2194
|
-
this._signalTracking.totalSignalsSentInLatencyWindow +=
|
|
2195
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement;
|
|
2196
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement = 0;
|
|
2197
|
-
}
|
|
2198
|
-
}
|
|
2199
|
-
this.submitSignalFn(envelope, targetClientId);
|
|
2200
|
-
}
|
|
2201
1997
|
/**
|
|
2202
1998
|
* Submits the signal to be sent to other clients.
|
|
2203
1999
|
* @param type - Type of the signal.
|
|
@@ -2212,8 +2008,11 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2212
2008
|
*/
|
|
2213
2009
|
submitSignal(type, content, targetClientId) {
|
|
2214
2010
|
this.verifyNotClosed();
|
|
2215
|
-
const envelope =
|
|
2216
|
-
|
|
2011
|
+
const envelope = createNewSignalEnvelope(undefined /* address */, type, content);
|
|
2012
|
+
if (targetClientId === undefined) {
|
|
2013
|
+
this.signalTelemetryManager.applyTrackingToBroadcastSignalEnvelope(envelope);
|
|
2014
|
+
}
|
|
2015
|
+
this.submitSignalFn(envelope, targetClientId);
|
|
2217
2016
|
}
|
|
2218
2017
|
setAttachState(attachState) {
|
|
2219
2018
|
if (attachState === AttachState.Attaching) {
|
|
@@ -2367,13 +2166,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2367
2166
|
* Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
|
|
2368
2167
|
* blob manager.
|
|
2369
2168
|
*/
|
|
2370
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2371
2169
|
getNodeType(nodePath) {
|
|
2372
2170
|
if (isBlobPath(nodePath)) {
|
|
2373
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2374
2171
|
return GCNodeType.Blob;
|
|
2375
2172
|
}
|
|
2376
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2377
2173
|
return this.channelCollection.getGCNodeType(nodePath) ?? GCNodeType.Other;
|
|
2378
2174
|
}
|
|
2379
2175
|
/**
|
|
@@ -2387,13 +2183,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2387
2183
|
return ["_gcRoot"];
|
|
2388
2184
|
}
|
|
2389
2185
|
switch (this.getNodeType(nodePath)) {
|
|
2390
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2391
2186
|
case GCNodeType.Blob: {
|
|
2392
2187
|
return [blobManagerBasePath];
|
|
2393
2188
|
}
|
|
2394
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2395
2189
|
case GCNodeType.DataStore:
|
|
2396
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2397
2190
|
case GCNodeType.SubDataStore: {
|
|
2398
2191
|
return this.channelCollection.getDataStorePackagePath(nodePath);
|
|
2399
2192
|
}
|
|
@@ -2461,7 +2254,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2461
2254
|
* op processing, updating SummarizerNode state tracking, and garbage collection.
|
|
2462
2255
|
* @param options - options controlling how the summary is generated or submitted
|
|
2463
2256
|
*/
|
|
2464
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2465
2257
|
async submitSummary(options) {
|
|
2466
2258
|
const { cancellationToken, fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
|
|
2467
2259
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
@@ -2950,7 +2742,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2950
2742
|
break;
|
|
2951
2743
|
}
|
|
2952
2744
|
default: {
|
|
2953
|
-
assert(this.
|
|
2745
|
+
assert(this.batchRunner.running, 0x587 /* Unreachable unless manually accumulating a batch */);
|
|
2954
2746
|
break;
|
|
2955
2747
|
}
|
|
2956
2748
|
}
|
|
@@ -2978,7 +2770,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2978
2770
|
* for correlation to detect container forking.
|
|
2979
2771
|
*/
|
|
2980
2772
|
reSubmitBatch(batch, batchId) {
|
|
2981
|
-
this.
|
|
2773
|
+
this.batchRunner.run(() => {
|
|
2982
2774
|
for (const message of batch) {
|
|
2983
2775
|
this.reSubmit(message);
|
|
2984
2776
|
}
|
|
@@ -3063,7 +2855,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
3063
2855
|
/**
|
|
3064
2856
|
* Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck
|
|
3065
2857
|
*/
|
|
3066
|
-
// eslint-disable-next-line import/no-deprecated
|
|
3067
2858
|
async refreshLatestSummaryAck(options) {
|
|
3068
2859
|
const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
|
|
3069
2860
|
// proposalHandle is always passed from RunningSummarizer.
|
|
@@ -3160,8 +2951,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
3160
2951
|
}
|
|
3161
2952
|
getPendingLocalState(props) {
|
|
3162
2953
|
this.verifyNotClosed();
|
|
3163
|
-
if (this.
|
|
3164
|
-
throw new UsageError("can't get state
|
|
2954
|
+
if (this.batchRunner.running) {
|
|
2955
|
+
throw new UsageError("can't get state while manually accumulating a batch");
|
|
3165
2956
|
}
|
|
3166
2957
|
this.imminentClosure ||= props?.notifyImminentClosure ?? false;
|
|
3167
2958
|
const getSyncState = (pendingAttachmentBlobs) => {
|
|
@@ -3222,27 +3013,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
3222
3013
|
return this.summaryManager.enqueueSummarize(options);
|
|
3223
3014
|
}
|
|
3224
3015
|
}
|
|
3225
|
-
/**
|
|
3226
|
-
* Forms a function that will create and retrieve a Summarizer.
|
|
3227
|
-
*/
|
|
3228
|
-
formCreateSummarizerFn(loader) {
|
|
3229
|
-
return async () => {
|
|
3230
|
-
return createSummarizer(loader, `/${summarizerRequestUrl}`);
|
|
3231
|
-
};
|
|
3232
|
-
}
|
|
3233
|
-
validateSummaryHeuristicConfiguration(configuration) {
|
|
3234
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
3235
|
-
for (const prop in configuration) {
|
|
3236
|
-
if (typeof configuration[prop] === "number" && configuration[prop] < 0) {
|
|
3237
|
-
throw new UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
|
|
3238
|
-
}
|
|
3239
|
-
}
|
|
3240
|
-
if (configuration.minIdleTime > configuration.maxIdleTime) {
|
|
3241
|
-
throw new UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
|
|
3242
|
-
}
|
|
3243
|
-
}
|
|
3244
3016
|
get groupedBatchingEnabled() {
|
|
3245
3017
|
return this.sessionSchema.opGroupingEnabled === true;
|
|
3246
3018
|
}
|
|
3247
3019
|
}
|
|
3020
|
+
export function createNewSignalEnvelope(address, type, content) {
|
|
3021
|
+
const newEnvelope = {
|
|
3022
|
+
address,
|
|
3023
|
+
contents: { type, content },
|
|
3024
|
+
};
|
|
3025
|
+
return newEnvelope;
|
|
3026
|
+
}
|
|
3248
3027
|
//# sourceMappingURL=containerRuntime.js.map
|