@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/src/containerRuntime.ts
CHANGED
|
@@ -3,47 +3,44 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type ILayerCompatDetails,
|
|
10
|
-
type IProvideLayerCompatDetails,
|
|
6
|
+
import type {
|
|
7
|
+
ILayerCompatDetails,
|
|
8
|
+
IProvideLayerCompatDetails,
|
|
11
9
|
} from "@fluid-internal/client-utils";
|
|
12
|
-
import {
|
|
13
|
-
|
|
10
|
+
import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
11
|
+
import type {
|
|
14
12
|
IAudience,
|
|
15
13
|
ISelf,
|
|
16
14
|
ICriticalContainerError,
|
|
17
|
-
|
|
15
|
+
IAudienceEvents,
|
|
18
16
|
} from "@fluidframework/container-definitions";
|
|
19
|
-
import {
|
|
17
|
+
import { AttachState } from "@fluidframework/container-definitions";
|
|
18
|
+
import type {
|
|
20
19
|
IContainerContext,
|
|
21
20
|
IGetPendingLocalStateProps,
|
|
22
|
-
ILoader,
|
|
23
21
|
IRuntime,
|
|
24
|
-
LoaderHeader,
|
|
25
22
|
IDeltaManager,
|
|
26
23
|
IDeltaManagerFull,
|
|
27
|
-
isIDeltaManagerFull,
|
|
28
24
|
} from "@fluidframework/container-definitions/internal";
|
|
29
|
-
import {
|
|
25
|
+
import { isIDeltaManagerFull } from "@fluidframework/container-definitions/internal";
|
|
26
|
+
import type {
|
|
30
27
|
IContainerRuntime,
|
|
31
28
|
IContainerRuntimeEvents,
|
|
32
29
|
} from "@fluidframework/container-runtime-definitions/internal";
|
|
33
|
-
import {
|
|
30
|
+
import type {
|
|
34
31
|
FluidObject,
|
|
35
32
|
IFluidHandle,
|
|
36
33
|
IRequest,
|
|
37
34
|
IResponse,
|
|
38
35
|
ITelemetryBaseLogger,
|
|
39
36
|
} from "@fluidframework/core-interfaces";
|
|
40
|
-
import {
|
|
41
|
-
|
|
37
|
+
import type {
|
|
38
|
+
IErrorBase,
|
|
42
39
|
IFluidHandleContext,
|
|
43
|
-
|
|
40
|
+
IFluidHandleInternal,
|
|
44
41
|
IProvideFluidHandleContext,
|
|
42
|
+
ISignalEnvelope,
|
|
45
43
|
} from "@fluidframework/core-interfaces/internal";
|
|
46
|
-
import { ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
|
|
47
44
|
import {
|
|
48
45
|
assert,
|
|
49
46
|
Deferred,
|
|
@@ -51,25 +48,23 @@ import {
|
|
|
51
48
|
PromiseCache,
|
|
52
49
|
delay,
|
|
53
50
|
} from "@fluidframework/core-utils/internal";
|
|
54
|
-
import {
|
|
51
|
+
import type {
|
|
55
52
|
IClientDetails,
|
|
56
53
|
IQuorumClients,
|
|
57
54
|
ISummaryTree,
|
|
58
|
-
SummaryType,
|
|
59
55
|
} from "@fluidframework/driver-definitions";
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
FetchSource,
|
|
56
|
+
import { SummaryType } from "@fluidframework/driver-definitions";
|
|
57
|
+
import type {
|
|
63
58
|
IDocumentStorageService,
|
|
64
|
-
type ISnapshot,
|
|
65
59
|
IDocumentMessage,
|
|
66
|
-
ISnapshotTree,
|
|
67
|
-
ISummaryContent,
|
|
68
|
-
MessageType,
|
|
69
60
|
ISequencedDocumentMessage,
|
|
70
61
|
ISignalMessage,
|
|
71
|
-
|
|
62
|
+
ISnapshot,
|
|
63
|
+
ISnapshotTree,
|
|
64
|
+
ISummaryContent,
|
|
65
|
+
ISummaryContext,
|
|
72
66
|
} from "@fluidframework/driver-definitions/internal";
|
|
67
|
+
import { FetchSource, MessageType } from "@fluidframework/driver-definitions/internal";
|
|
73
68
|
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
74
69
|
import type { IIdCompressor } from "@fluidframework/id-compressor";
|
|
75
70
|
import type {
|
|
@@ -78,13 +73,11 @@ import type {
|
|
|
78
73
|
SerializedIdCompressorWithNoSession,
|
|
79
74
|
SerializedIdCompressorWithOngoingSession,
|
|
80
75
|
} from "@fluidframework/id-compressor/internal";
|
|
81
|
-
import {
|
|
76
|
+
import type {
|
|
82
77
|
ISummaryTreeWithStats,
|
|
83
78
|
ITelemetryContext,
|
|
84
79
|
IGarbageCollectionData,
|
|
85
80
|
CreateChildSummarizerNodeParam,
|
|
86
|
-
FlushMode,
|
|
87
|
-
FlushModeExperimental,
|
|
88
81
|
IDataStore,
|
|
89
82
|
IEnvelope,
|
|
90
83
|
IFluidDataStoreContextDetached,
|
|
@@ -93,11 +86,15 @@ import {
|
|
|
93
86
|
InboundAttachMessage,
|
|
94
87
|
NamedFluidDataStoreRegistryEntries,
|
|
95
88
|
SummarizeInternalFn,
|
|
89
|
+
IInboundSignalMessage,
|
|
90
|
+
IRuntimeMessagesContent,
|
|
91
|
+
ISummarizerNodeWithGC,
|
|
92
|
+
} from "@fluidframework/runtime-definitions/internal";
|
|
93
|
+
import {
|
|
94
|
+
FlushMode,
|
|
95
|
+
FlushModeExperimental,
|
|
96
96
|
channelsTreeName,
|
|
97
97
|
gcTreeKey,
|
|
98
|
-
IInboundSignalMessage,
|
|
99
|
-
type IRuntimeMessagesContent,
|
|
100
|
-
type ISummarizerNodeWithGC,
|
|
101
98
|
} from "@fluidframework/runtime-definitions/internal";
|
|
102
99
|
import {
|
|
103
100
|
GCDataBuilder,
|
|
@@ -108,23 +105,21 @@ import {
|
|
|
108
105
|
calculateStats,
|
|
109
106
|
create404Response,
|
|
110
107
|
exceptionToResponse,
|
|
111
|
-
responseToException,
|
|
112
108
|
seqFromTree,
|
|
113
109
|
} from "@fluidframework/runtime-utils/internal";
|
|
114
110
|
import type {
|
|
111
|
+
IEventSampler,
|
|
115
112
|
IFluidErrorBase,
|
|
116
113
|
ITelemetryGenericEventExt,
|
|
117
|
-
|
|
114
|
+
ITelemetryLoggerExt,
|
|
115
|
+
MonitoringContext,
|
|
118
116
|
} from "@fluidframework/telemetry-utils/internal";
|
|
119
117
|
import {
|
|
120
|
-
ITelemetryLoggerExt,
|
|
121
118
|
DataCorruptionError,
|
|
122
119
|
DataProcessingError,
|
|
123
120
|
extractSafePropertiesFromMessage,
|
|
124
121
|
GenericError,
|
|
125
|
-
IEventSampler,
|
|
126
122
|
LoggingError,
|
|
127
|
-
MonitoringContext,
|
|
128
123
|
PerformanceEvent,
|
|
129
124
|
// eslint-disable-next-line import/no-deprecated
|
|
130
125
|
TaggedLoggerAdapter,
|
|
@@ -147,7 +142,6 @@ import {
|
|
|
147
142
|
blobsTreeName,
|
|
148
143
|
isBlobPath,
|
|
149
144
|
loadBlobManagerLoadInfo,
|
|
150
|
-
// eslint-disable-next-line import/no-deprecated
|
|
151
145
|
type IBlobManagerLoadInfo,
|
|
152
146
|
} from "./blobManager/index.js";
|
|
153
147
|
import {
|
|
@@ -155,7 +149,7 @@ import {
|
|
|
155
149
|
getSummaryForDatastores,
|
|
156
150
|
wrapContext,
|
|
157
151
|
} from "./channelCollection.js";
|
|
158
|
-
import {
|
|
152
|
+
import { ReportOpPerfTelemetry } from "./connectionTelemetry.js";
|
|
159
153
|
import { ContainerFluidHandleContext } from "./containerHandleContext.js";
|
|
160
154
|
import { channelToDataStore } from "./dataStore.js";
|
|
161
155
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
@@ -165,18 +159,15 @@ import {
|
|
|
165
159
|
} from "./deltaManagerProxies.js";
|
|
166
160
|
import { DeltaScheduler } from "./deltaScheduler.js";
|
|
167
161
|
import {
|
|
168
|
-
// eslint-disable-next-line import/no-deprecated
|
|
169
162
|
GCNodeType,
|
|
170
163
|
GarbageCollector,
|
|
171
164
|
IGCRuntimeOptions,
|
|
172
|
-
// eslint-disable-next-line import/no-deprecated
|
|
173
165
|
IGCStats,
|
|
174
166
|
IGarbageCollector,
|
|
175
167
|
gcGenerationOptionName,
|
|
176
168
|
type GarbageCollectionMessage,
|
|
177
169
|
} from "./gc/index.js";
|
|
178
170
|
import { InboundBatchAggregator } from "./inboundBatchAggregator.js";
|
|
179
|
-
import { RuntimeCompatDetails, validateLoaderCompatibility } from "./layerCompatState.js";
|
|
180
171
|
import {
|
|
181
172
|
ContainerMessageType,
|
|
182
173
|
type ContainerRuntimeDocumentSchemaMessage,
|
|
@@ -210,39 +201,32 @@ import {
|
|
|
210
201
|
IPendingLocalState,
|
|
211
202
|
PendingStateManager,
|
|
212
203
|
} from "./pendingStateManager.js";
|
|
204
|
+
import { RunCounter } from "./runCounter.js";
|
|
205
|
+
import {
|
|
206
|
+
runtimeCompatDetailsForLoader,
|
|
207
|
+
validateLoaderCompatibility,
|
|
208
|
+
} from "./runtimeLayerCompatState.js";
|
|
209
|
+
import { SignalTelemetryManager } from "./signalTelemetryProcessing.js";
|
|
213
210
|
import {
|
|
214
|
-
// eslint-disable-next-line import/no-deprecated
|
|
215
211
|
DocumentsSchemaController,
|
|
216
212
|
EnqueueSummarizeResult,
|
|
217
213
|
IBaseSummarizeResult,
|
|
218
|
-
// eslint-disable-next-line import/no-deprecated
|
|
219
214
|
IConnectableRuntime,
|
|
220
|
-
// eslint-disable-next-line import/no-deprecated
|
|
221
215
|
IContainerRuntimeMetadata,
|
|
222
|
-
// eslint-disable-next-line import/no-deprecated
|
|
223
216
|
ICreateContainerMetadata,
|
|
224
|
-
// eslint-disable-next-line import/no-deprecated
|
|
225
217
|
type IDocumentSchemaChangeMessage,
|
|
226
|
-
// eslint-disable-next-line import/no-deprecated
|
|
227
218
|
type IDocumentSchemaCurrent,
|
|
228
219
|
IEnqueueSummarizeOptions,
|
|
229
220
|
IGenerateSummaryTreeResult,
|
|
230
221
|
IGeneratedSummaryStats,
|
|
231
222
|
IOnDemandSummarizeOptions,
|
|
232
|
-
// eslint-disable-next-line import/no-deprecated
|
|
233
223
|
IRefreshSummaryAckOptions,
|
|
234
224
|
IRootSummarizerNodeWithGC,
|
|
235
|
-
// eslint-disable-next-line import/no-deprecated
|
|
236
225
|
ISerializedElection,
|
|
237
|
-
// eslint-disable-next-line import/no-deprecated
|
|
238
226
|
ISubmitSummaryOptions,
|
|
239
227
|
ISummarizeResults,
|
|
240
|
-
ISummarizer,
|
|
241
|
-
// eslint-disable-next-line import/no-deprecated
|
|
242
228
|
ISummarizerInternalsProvider,
|
|
243
|
-
// eslint-disable-next-line import/no-deprecated
|
|
244
229
|
ISummarizerRuntime,
|
|
245
|
-
// eslint-disable-next-line import/no-deprecated
|
|
246
230
|
ISummaryMetadataMessage,
|
|
247
231
|
IdCompressorMode,
|
|
248
232
|
OrderedClientCollection,
|
|
@@ -250,7 +234,6 @@ import {
|
|
|
250
234
|
RetriableSummaryError,
|
|
251
235
|
RunWhileConnectedCoordinator,
|
|
252
236
|
SubmitSummaryResult,
|
|
253
|
-
// eslint-disable-next-line import/no-deprecated
|
|
254
237
|
Summarizer,
|
|
255
238
|
SummarizerClientElection,
|
|
256
239
|
SummaryCollection,
|
|
@@ -266,8 +249,13 @@ import {
|
|
|
266
249
|
rootHasIsolatedChannels,
|
|
267
250
|
summarizerClientType,
|
|
268
251
|
wrapSummaryInChannelsTree,
|
|
269
|
-
// eslint-disable-next-line import/no-deprecated
|
|
270
252
|
type IDocumentSchemaFeatures,
|
|
253
|
+
formCreateSummarizerFn,
|
|
254
|
+
summarizerRequestUrl,
|
|
255
|
+
validateSummaryHeuristicConfiguration,
|
|
256
|
+
ISummaryConfiguration,
|
|
257
|
+
DefaultSummaryConfiguration,
|
|
258
|
+
isSummariesDisabled,
|
|
271
259
|
} from "./summary/index.js";
|
|
272
260
|
import { Throttler, formExponentialFn } from "./throttler.js";
|
|
273
261
|
|
|
@@ -300,154 +288,6 @@ function getUnknownMessageTypeError(
|
|
|
300
288
|
);
|
|
301
289
|
}
|
|
302
290
|
|
|
303
|
-
/**
|
|
304
|
-
* @legacy
|
|
305
|
-
* @alpha
|
|
306
|
-
*/
|
|
307
|
-
export interface ISummaryBaseConfiguration {
|
|
308
|
-
/**
|
|
309
|
-
* Delay before first attempt to spawn summarizing container.
|
|
310
|
-
*/
|
|
311
|
-
initialSummarizerDelayMs: number;
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Defines the maximum allowed time to wait for a pending summary ack.
|
|
315
|
-
* The maximum amount of time client will wait for a summarize is the minimum of
|
|
316
|
-
* maxSummarizeAckWaitTime (currently 3 * 60 * 1000) and maxAckWaitTime.
|
|
317
|
-
*/
|
|
318
|
-
maxAckWaitTime: number;
|
|
319
|
-
/**
|
|
320
|
-
* Defines the maximum number of Ops in between Summaries that can be
|
|
321
|
-
* allowed before forcibly electing a new summarizer client.
|
|
322
|
-
*/
|
|
323
|
-
maxOpsSinceLastSummary: number;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* @legacy
|
|
328
|
-
* @alpha
|
|
329
|
-
*/
|
|
330
|
-
export interface ISummaryConfigurationHeuristics extends ISummaryBaseConfiguration {
|
|
331
|
-
state: "enabled";
|
|
332
|
-
/**
|
|
333
|
-
* Defines the maximum allowed time, since the last received Ack, before running the summary
|
|
334
|
-
* with reason maxTime.
|
|
335
|
-
* For example, say we receive ops one by one just before the idle time is triggered.
|
|
336
|
-
* In this case, we still want to run a summary since it's been a while since the last summary.
|
|
337
|
-
*/
|
|
338
|
-
maxTime: number;
|
|
339
|
-
/**
|
|
340
|
-
* Defines the maximum number of Ops, since the last received Ack, that can be allowed
|
|
341
|
-
* before running the summary with reason maxOps.
|
|
342
|
-
*/
|
|
343
|
-
maxOps: number;
|
|
344
|
-
/**
|
|
345
|
-
* Defines the minimum number of Ops, since the last received Ack, that can be allowed
|
|
346
|
-
* before running the last summary.
|
|
347
|
-
*/
|
|
348
|
-
minOpsForLastSummaryAttempt: number;
|
|
349
|
-
/**
|
|
350
|
-
* Defines the lower boundary for the allowed time in between summarizations.
|
|
351
|
-
* Pairs with maxIdleTime to form a range.
|
|
352
|
-
* For example, if we only receive 1 op, we don't want to have the same idle time as say 100 ops.
|
|
353
|
-
* Based on the boundaries we set in minIdleTime and maxIdleTime, the idle time will change
|
|
354
|
-
* linearly depending on the number of ops we receive.
|
|
355
|
-
*/
|
|
356
|
-
minIdleTime: number;
|
|
357
|
-
/**
|
|
358
|
-
* Defines the upper boundary for the allowed time in between summarizations.
|
|
359
|
-
* Pairs with minIdleTime to form a range.
|
|
360
|
-
* For example, if we only receive 1 op, we don't want to have the same idle time as say 100 ops.
|
|
361
|
-
* Based on the boundaries we set in minIdleTime and maxIdleTime, the idle time will change
|
|
362
|
-
* linearly depending on the number of ops we receive.
|
|
363
|
-
*/
|
|
364
|
-
maxIdleTime: number;
|
|
365
|
-
/**
|
|
366
|
-
* Runtime op weight to use in heuristic summarizing.
|
|
367
|
-
* This number is a multiplier on the number of runtime ops we process when running summarize heuristics.
|
|
368
|
-
* For example: (multiplier) * (number of runtime ops) = weighted number of runtime ops
|
|
369
|
-
*/
|
|
370
|
-
runtimeOpWeight: number;
|
|
371
|
-
/**
|
|
372
|
-
* Non-runtime op weight to use in heuristic summarizing
|
|
373
|
-
* This number is a multiplier on the number of non-runtime ops we process when running summarize heuristics.
|
|
374
|
-
* For example: (multiplier) * (number of non-runtime ops) = weighted number of non-runtime ops
|
|
375
|
-
*/
|
|
376
|
-
nonRuntimeOpWeight: number;
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Number of ops since last summary needed before a non-runtime op can trigger running summary heuristics.
|
|
380
|
-
*
|
|
381
|
-
* Note: Any runtime ops sent before the threshold is reached will trigger heuristics normally.
|
|
382
|
-
* This threshold ONLY applies to non-runtime ops triggering summaries.
|
|
383
|
-
*
|
|
384
|
-
* For example: Say the threshold is 20. Sending 19 non-runtime ops will not trigger any heuristic checks.
|
|
385
|
-
* Sending the 20th non-runtime op will trigger the heuristic checks for summarizing.
|
|
386
|
-
*/
|
|
387
|
-
nonRuntimeHeuristicThreshold?: number;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* @legacy
|
|
392
|
-
* @alpha
|
|
393
|
-
*/
|
|
394
|
-
export interface ISummaryConfigurationDisableSummarizer {
|
|
395
|
-
state: "disabled";
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* @legacy
|
|
400
|
-
* @alpha
|
|
401
|
-
*/
|
|
402
|
-
export interface ISummaryConfigurationDisableHeuristics extends ISummaryBaseConfiguration {
|
|
403
|
-
state: "disableHeuristics";
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* @legacy
|
|
408
|
-
* @alpha
|
|
409
|
-
*/
|
|
410
|
-
export type ISummaryConfiguration =
|
|
411
|
-
| ISummaryConfigurationDisableSummarizer
|
|
412
|
-
| ISummaryConfigurationDisableHeuristics
|
|
413
|
-
| ISummaryConfigurationHeuristics;
|
|
414
|
-
|
|
415
|
-
export function isSummariesDisabled(
|
|
416
|
-
config: ISummaryConfiguration,
|
|
417
|
-
): config is ISummaryConfigurationDisableSummarizer {
|
|
418
|
-
return config.state === "disabled";
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* @legacy
|
|
423
|
-
* @alpha
|
|
424
|
-
*/
|
|
425
|
-
export const DefaultSummaryConfiguration: ISummaryConfiguration = {
|
|
426
|
-
state: "enabled",
|
|
427
|
-
|
|
428
|
-
minIdleTime: 0,
|
|
429
|
-
|
|
430
|
-
maxIdleTime: 30 * 1000, // 30 secs.
|
|
431
|
-
|
|
432
|
-
maxTime: 60 * 1000, // 1 min.
|
|
433
|
-
|
|
434
|
-
maxOps: 100, // Summarize if 100 weighted ops received since last snapshot.
|
|
435
|
-
|
|
436
|
-
minOpsForLastSummaryAttempt: 10,
|
|
437
|
-
|
|
438
|
-
maxAckWaitTime: 3 * 60 * 1000, // 3 mins.
|
|
439
|
-
|
|
440
|
-
maxOpsSinceLastSummary: 7000,
|
|
441
|
-
|
|
442
|
-
initialSummarizerDelayMs: 5 * 1000, // 5 secs.
|
|
443
|
-
|
|
444
|
-
nonRuntimeOpWeight: 0.1,
|
|
445
|
-
|
|
446
|
-
runtimeOpWeight: 1,
|
|
447
|
-
|
|
448
|
-
nonRuntimeHeuristicThreshold: 20,
|
|
449
|
-
};
|
|
450
|
-
|
|
451
291
|
/**
|
|
452
292
|
* @legacy
|
|
453
293
|
* @alpha
|
|
@@ -565,7 +405,7 @@ export interface IContainerRuntimeOptions {
|
|
|
565
405
|
*
|
|
566
406
|
* These options are not available to consumers when creating a new container runtime,
|
|
567
407
|
* but we do need to expose them for internal use, e.g. when configuring the container runtime
|
|
568
|
-
* to ensure
|
|
408
|
+
* to ensure compatibility with older versions.
|
|
569
409
|
*
|
|
570
410
|
* @internal
|
|
571
411
|
*/
|
|
@@ -587,9 +427,7 @@ export interface IContainerRuntimeOptionsInternal extends IContainerRuntimeOptio
|
|
|
587
427
|
|
|
588
428
|
/**
|
|
589
429
|
* Error responses when requesting a deleted object will have this header set to true
|
|
590
|
-
* @
|
|
591
|
-
* @alpha
|
|
592
|
-
* @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
|
|
430
|
+
* @internal
|
|
593
431
|
*/
|
|
594
432
|
export const DeletedResponseHeaderKey = "wasDeleted";
|
|
595
433
|
/**
|
|
@@ -782,50 +620,6 @@ export const makeLegacySendBatchFn =
|
|
|
782
620
|
return clientSequenceNumber;
|
|
783
621
|
};
|
|
784
622
|
|
|
785
|
-
const summarizerRequestUrl = "_summarizer";
|
|
786
|
-
|
|
787
|
-
/**
|
|
788
|
-
* Create and retrieve the summmarizer
|
|
789
|
-
*/
|
|
790
|
-
async function createSummarizer(loader: ILoader, url: string): Promise<ISummarizer> {
|
|
791
|
-
const request: IRequest = {
|
|
792
|
-
headers: {
|
|
793
|
-
[LoaderHeader.cache]: false,
|
|
794
|
-
[LoaderHeader.clientDetails]: {
|
|
795
|
-
capabilities: { interactive: false },
|
|
796
|
-
type: summarizerClientType,
|
|
797
|
-
},
|
|
798
|
-
[DriverHeader.summarizingClient]: true,
|
|
799
|
-
[LoaderHeader.reconnect]: false,
|
|
800
|
-
},
|
|
801
|
-
url,
|
|
802
|
-
};
|
|
803
|
-
|
|
804
|
-
const resolvedContainer = await loader.resolve(request);
|
|
805
|
-
let fluidObject: FluidObject<ISummarizer> | undefined;
|
|
806
|
-
|
|
807
|
-
// Older containers may not have the "getEntryPoint" API
|
|
808
|
-
// ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
|
|
809
|
-
if (resolvedContainer.getEntryPoint === undefined) {
|
|
810
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
|
|
811
|
-
const response = (await (resolvedContainer as any).request({
|
|
812
|
-
url: `/${summarizerRequestUrl}`,
|
|
813
|
-
})) as IResponse;
|
|
814
|
-
if (response.status !== 200 || response.mimeType !== "fluid/object") {
|
|
815
|
-
throw responseToException(response, request);
|
|
816
|
-
}
|
|
817
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
818
|
-
fluidObject = response.value;
|
|
819
|
-
} else {
|
|
820
|
-
fluidObject = await resolvedContainer.getEntryPoint();
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
if (fluidObject?.ISummarizer === undefined) {
|
|
824
|
-
throw new UsageError("Fluid object does not implement ISummarizer");
|
|
825
|
-
}
|
|
826
|
-
return fluidObject.ISummarizer;
|
|
827
|
-
}
|
|
828
|
-
|
|
829
623
|
/**
|
|
830
624
|
* Extract last message from the snapshot metadata.
|
|
831
625
|
* Uses legacy property if not using explicit schema control, otherwise uses the new property.
|
|
@@ -833,9 +627,7 @@ async function createSummarizer(loader: ILoader, url: string): Promise<ISummariz
|
|
|
833
627
|
* Please see addMetadataToSummary() as well
|
|
834
628
|
*/
|
|
835
629
|
function lastMessageFromMetadata(
|
|
836
|
-
// eslint-disable-next-line import/no-deprecated
|
|
837
630
|
metadata: IContainerRuntimeMetadata | undefined,
|
|
838
|
-
// eslint-disable-next-line import/no-deprecated
|
|
839
631
|
): ISummaryMetadataMessage | undefined {
|
|
840
632
|
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
841
633
|
? metadata?.lastMessage
|
|
@@ -913,8 +705,6 @@ export async function loadContainerRuntime(
|
|
|
913
705
|
|
|
914
706
|
const defaultMaxConsecutiveReconnects = 7;
|
|
915
707
|
|
|
916
|
-
const defaultTelemetrySignalSampleCount = 100;
|
|
917
|
-
|
|
918
708
|
/**
|
|
919
709
|
* Represents the runtime of the container. Contains helper functions/state of the container.
|
|
920
710
|
* It will define the store level mappings.
|
|
@@ -926,9 +716,7 @@ export class ContainerRuntime
|
|
|
926
716
|
implements
|
|
927
717
|
IContainerRuntime,
|
|
928
718
|
IRuntime,
|
|
929
|
-
// eslint-disable-next-line import/no-deprecated
|
|
930
719
|
ISummarizerRuntime,
|
|
931
|
-
// eslint-disable-next-line import/no-deprecated
|
|
932
720
|
ISummarizerInternalsProvider,
|
|
933
721
|
IProvideFluidHandleContext,
|
|
934
722
|
IProvideLayerCompatDetails
|
|
@@ -952,7 +740,7 @@ export class ContainerRuntime
|
|
|
952
740
|
context: IContainerContext;
|
|
953
741
|
registryEntries: NamedFluidDataStoreRegistryEntries;
|
|
954
742
|
existing: boolean;
|
|
955
|
-
runtimeOptions?:
|
|
743
|
+
runtimeOptions?: IContainerRuntimeOptionsInternal;
|
|
956
744
|
containerScope?: FluidObject;
|
|
957
745
|
containerRuntimeCtor?: typeof ContainerRuntime;
|
|
958
746
|
/**
|
|
@@ -967,7 +755,7 @@ export class ContainerRuntime
|
|
|
967
755
|
existing,
|
|
968
756
|
requestHandler,
|
|
969
757
|
provideEntryPoint,
|
|
970
|
-
runtimeOptions = {} satisfies
|
|
758
|
+
runtimeOptions = {} satisfies IContainerRuntimeOptionsInternal,
|
|
971
759
|
containerScope = {},
|
|
972
760
|
containerRuntimeCtor = ContainerRuntime,
|
|
973
761
|
} = params;
|
|
@@ -1032,16 +820,16 @@ export class ContainerRuntime
|
|
|
1032
820
|
tryFetchBlob<ReturnType<DuplicateBatchDetector["getRecentBatchInfoForSummary"]>>(
|
|
1033
821
|
recentBatchInfoBlobName,
|
|
1034
822
|
),
|
|
1035
|
-
|
|
823
|
+
|
|
1036
824
|
tryFetchBlob<IContainerRuntimeMetadata>(metadataBlobName),
|
|
1037
|
-
|
|
825
|
+
|
|
1038
826
|
tryFetchBlob<ISerializedElection>(electedSummarizerBlobName),
|
|
1039
827
|
tryFetchBlob<[string, string][]>(aliasBlobName),
|
|
1040
828
|
tryFetchBlob<SerializedIdCompressorWithNoSession>(idCompressorBlobName),
|
|
1041
829
|
]);
|
|
1042
830
|
|
|
1043
831
|
// read snapshot blobs needed for BlobManager to load
|
|
1044
|
-
const
|
|
832
|
+
const blobManagerLoadInfo = await loadBlobManagerLoadInfo(context);
|
|
1045
833
|
|
|
1046
834
|
const messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
1047
835
|
|
|
@@ -1170,7 +958,6 @@ export class ContainerRuntime
|
|
|
1170
958
|
compressionOptions.minimumBatchSizeInBytes !== Number.POSITIVE_INFINITY &&
|
|
1171
959
|
compressionOptions.compressionAlgorithm === "lz4";
|
|
1172
960
|
|
|
1173
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1174
961
|
const documentSchemaController = new DocumentsSchemaController(
|
|
1175
962
|
existing,
|
|
1176
963
|
protocolSequenceNumber,
|
|
@@ -1219,7 +1006,7 @@ export class ContainerRuntime
|
|
|
1219
1006
|
containerScope,
|
|
1220
1007
|
logger,
|
|
1221
1008
|
existing,
|
|
1222
|
-
|
|
1009
|
+
blobManagerLoadInfo,
|
|
1223
1010
|
context.storage,
|
|
1224
1011
|
createIdCompressorFn,
|
|
1225
1012
|
documentSchemaController,
|
|
@@ -1308,11 +1095,9 @@ export class ContainerRuntime
|
|
|
1308
1095
|
* this op roundtrips, compression will be On. Client can't send compressed ops until it's change in schema.
|
|
1309
1096
|
*/
|
|
1310
1097
|
public get sessionSchema(): {
|
|
1311
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1312
1098
|
[P in keyof IDocumentSchemaFeatures]?: IDocumentSchemaFeatures[P] extends boolean
|
|
1313
1099
|
? true
|
|
1314
|
-
:
|
|
1315
|
-
IDocumentSchemaFeatures[P];
|
|
1100
|
+
: IDocumentSchemaFeatures[P];
|
|
1316
1101
|
} {
|
|
1317
1102
|
return this.documentsSchemaController.sessionSchema.runtime;
|
|
1318
1103
|
}
|
|
@@ -1394,7 +1179,7 @@ export class ContainerRuntime
|
|
|
1394
1179
|
|
|
1395
1180
|
private readonly maxConsecutiveReconnects: number;
|
|
1396
1181
|
|
|
1397
|
-
private
|
|
1182
|
+
private readonly batchRunner = new RunCounter();
|
|
1398
1183
|
private readonly _flushMode: FlushMode;
|
|
1399
1184
|
private readonly offlineEnabled: boolean;
|
|
1400
1185
|
private flushTaskExists = false;
|
|
@@ -1409,23 +1194,16 @@ export class ContainerRuntime
|
|
|
1409
1194
|
*/
|
|
1410
1195
|
private delayConnectClientId?: string;
|
|
1411
1196
|
|
|
1412
|
-
private
|
|
1197
|
+
private readonly dataModelChangeRunner = new RunCounter();
|
|
1413
1198
|
|
|
1414
1199
|
/**
|
|
1415
1200
|
* Invokes the given callback and expects that no ops are submitted
|
|
1416
1201
|
* until execution finishes. If an op is submitted, an error will be raised.
|
|
1417
1202
|
*
|
|
1418
|
-
* Can be disabled by feature gate `Fluid.ContainerRuntime.DisableOpReentryCheck`
|
|
1419
|
-
*
|
|
1420
1203
|
* @param callback - the callback to be invoked
|
|
1421
1204
|
*/
|
|
1422
1205
|
public ensureNoDataModelChanges<T>(callback: () => T): T {
|
|
1423
|
-
this.
|
|
1424
|
-
try {
|
|
1425
|
-
return callback();
|
|
1426
|
-
} finally {
|
|
1427
|
-
this.ensureNoDataModelChangesCalls--;
|
|
1428
|
-
}
|
|
1206
|
+
return this.dataModelChangeRunner.run(callback);
|
|
1429
1207
|
}
|
|
1430
1208
|
|
|
1431
1209
|
public get connected(): boolean {
|
|
@@ -1448,24 +1226,15 @@ export class ContainerRuntime
|
|
|
1448
1226
|
private emitDirtyDocumentEvent = true;
|
|
1449
1227
|
private readonly useDeltaManagerOpsProxy: boolean;
|
|
1450
1228
|
private readonly closeSummarizerDelayMs: number;
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
signalsLost: 0,
|
|
1454
|
-
signalsOutOfOrder: 0,
|
|
1455
|
-
signalsSentSinceLastLatencyMeasurement: 0,
|
|
1456
|
-
broadcastSignalSequenceNumber: 0,
|
|
1457
|
-
signalTimestamp: 0,
|
|
1458
|
-
roundTripSignalSequenceNumber: undefined,
|
|
1459
|
-
trackingSignalSequenceNumber: undefined,
|
|
1460
|
-
minimumTrackingSignalSequenceNumber: undefined,
|
|
1461
|
-
};
|
|
1229
|
+
|
|
1230
|
+
private readonly signalTelemetryManager = new SignalTelemetryManager();
|
|
1462
1231
|
|
|
1463
1232
|
/**
|
|
1464
1233
|
* Summarizer is responsible for coordinating when to send generate and send summaries.
|
|
1465
1234
|
* It is the main entry point for summary work.
|
|
1466
1235
|
* It is created only by summarizing container (i.e. one with clientType === "summarizer")
|
|
1467
1236
|
*/
|
|
1468
|
-
|
|
1237
|
+
|
|
1469
1238
|
private readonly _summarizer?: Summarizer;
|
|
1470
1239
|
private readonly deltaScheduler: DeltaScheduler;
|
|
1471
1240
|
private readonly inboundBatchAggregator: InboundBatchAggregator;
|
|
@@ -1481,12 +1250,11 @@ export class ContainerRuntime
|
|
|
1481
1250
|
/**
|
|
1482
1251
|
* The last message processed at the time of the last summary.
|
|
1483
1252
|
*/
|
|
1484
|
-
|
|
1253
|
+
|
|
1485
1254
|
private messageAtLastSummary: ISummaryMetadataMessage | undefined;
|
|
1486
1255
|
|
|
1487
1256
|
private readonly summariesDisabled: boolean;
|
|
1488
1257
|
|
|
1489
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1490
1258
|
private readonly createContainerMetadata: ICreateContainerMetadata;
|
|
1491
1259
|
/**
|
|
1492
1260
|
* The summary number of the next summary that will be generated for this container. This is incremented every time
|
|
@@ -1538,30 +1306,41 @@ export class ContainerRuntime
|
|
|
1538
1306
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
1539
1307
|
});
|
|
1540
1308
|
|
|
1309
|
+
/**
|
|
1310
|
+
* The compatibility details of the Runtime layer that is exposed to the Loader layer
|
|
1311
|
+
* for validating Loader-Runtime compatibility.
|
|
1312
|
+
*/
|
|
1541
1313
|
public get ILayerCompatDetails(): ILayerCompatDetails {
|
|
1542
|
-
return
|
|
1314
|
+
return runtimeCompatDetailsForLoader;
|
|
1543
1315
|
}
|
|
1544
1316
|
|
|
1317
|
+
/**
|
|
1318
|
+
* If true, will skip Outbox flushing before processing an incoming message,
|
|
1319
|
+
* and instead the Outbox will check for a split batch on every submit.
|
|
1320
|
+
* This is a kill-bit switch for this simplification of logic, in case it causes unexpected issues.
|
|
1321
|
+
*/
|
|
1322
|
+
private readonly disableFlushBeforeProcess: boolean;
|
|
1323
|
+
|
|
1545
1324
|
/***/
|
|
1546
1325
|
protected constructor(
|
|
1547
1326
|
context: IContainerContext,
|
|
1548
1327
|
private readonly registry: IFluidDataStoreRegistry,
|
|
1549
|
-
|
|
1328
|
+
|
|
1550
1329
|
private readonly metadata: IContainerRuntimeMetadata | undefined,
|
|
1551
|
-
|
|
1330
|
+
|
|
1552
1331
|
electedSummarizerData: ISerializedElection | undefined,
|
|
1553
1332
|
chunks: [string, string[]][],
|
|
1554
1333
|
dataStoreAliasMap: [string, string][],
|
|
1555
|
-
|
|
1334
|
+
runtimeOptions: Readonly<Required<IContainerRuntimeOptionsInternal>>,
|
|
1556
1335
|
private readonly containerScope: FluidObject,
|
|
1557
1336
|
// Create a custom ITelemetryBaseLogger to output telemetry events.
|
|
1558
1337
|
public readonly baseLogger: ITelemetryBaseLogger,
|
|
1559
1338
|
existing: boolean,
|
|
1560
|
-
|
|
1561
|
-
|
|
1339
|
+
|
|
1340
|
+
blobManagerLoadInfo: IBlobManagerLoadInfo,
|
|
1562
1341
|
private readonly _storage: IDocumentStorageService,
|
|
1563
1342
|
private readonly createIdCompressor: () => Promise<IIdCompressor & IIdCompressorCore>,
|
|
1564
|
-
|
|
1343
|
+
|
|
1565
1344
|
private readonly documentsSchemaController: DocumentsSchemaController,
|
|
1566
1345
|
featureGatesForTelemetry: Record<string, boolean | number | undefined>,
|
|
1567
1346
|
provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>,
|
|
@@ -1574,7 +1353,7 @@ export class ContainerRuntime
|
|
|
1574
1353
|
// the defaults
|
|
1575
1354
|
...DefaultSummaryConfiguration,
|
|
1576
1355
|
// the runtime configuration overrides
|
|
1577
|
-
...
|
|
1356
|
+
...runtimeOptions.summaryOptions?.summaryConfigOverrides,
|
|
1578
1357
|
},
|
|
1579
1358
|
recentBatchInfo?: [number, string][],
|
|
1580
1359
|
) {
|
|
@@ -1603,14 +1382,13 @@ export class ContainerRuntime
|
|
|
1603
1382
|
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
1604
1383
|
this.disposeFn = disposeFn ?? closeFn;
|
|
1605
1384
|
|
|
1606
|
-
|
|
1607
|
-
|
|
1385
|
+
// Validate that the Loader is compatible with this Runtime.
|
|
1386
|
+
const maybeloaderCompatDetailsForRuntime = context as FluidObject<ILayerCompatDetails>;
|
|
1387
|
+
validateLoaderCompatibility(
|
|
1388
|
+
maybeloaderCompatDetailsForRuntime.ILayerCompatDetails,
|
|
1389
|
+
this.disposeFn,
|
|
1390
|
+
);
|
|
1608
1391
|
|
|
1609
|
-
// Backfill in defaults for the internal runtimeOptions, since they may not be present on the provided runtimeOptions object
|
|
1610
|
-
const runtimeOptions = {
|
|
1611
|
-
flushMode: defaultFlushMode,
|
|
1612
|
-
...baseRuntimeOptions,
|
|
1613
|
-
};
|
|
1614
1392
|
this.mc = createChildMonitoringContext({
|
|
1615
1393
|
logger: this.baseLogger,
|
|
1616
1394
|
namespace: "ContainerRuntime",
|
|
@@ -1663,6 +1441,25 @@ export class ContainerRuntime
|
|
|
1663
1441
|
this.on("dirty", () => context.updateDirtyContainerState(true));
|
|
1664
1442
|
this.on("saved", () => context.updateDirtyContainerState(false));
|
|
1665
1443
|
|
|
1444
|
+
// Telemetry for when the container is attached and subsequently saved for the first time.
|
|
1445
|
+
// These events are useful for investigating the validity of container "saved" eventing upon attach.
|
|
1446
|
+
// See this.setAttachState() and this.updateDocumentDirtyState() for more details on "attached" and "saved" events.
|
|
1447
|
+
this.once("attached", () => {
|
|
1448
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1449
|
+
eventName: "Attached",
|
|
1450
|
+
details: {
|
|
1451
|
+
dirtyContainer: this.dirtyContainer,
|
|
1452
|
+
hasPendingMessages: this.hasPendingMessages(),
|
|
1453
|
+
},
|
|
1454
|
+
});
|
|
1455
|
+
});
|
|
1456
|
+
this.once("saved", () =>
|
|
1457
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1458
|
+
eventName: "Saved",
|
|
1459
|
+
details: { attachState: this.attachState },
|
|
1460
|
+
}),
|
|
1461
|
+
);
|
|
1462
|
+
|
|
1666
1463
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
1667
1464
|
this.closeFn = isSummarizerClient ? this.disposeFn : closeFn;
|
|
1668
1465
|
|
|
@@ -1762,7 +1559,7 @@ export class ContainerRuntime
|
|
|
1762
1559
|
this.handleContext = new ContainerFluidHandleContext("", this);
|
|
1763
1560
|
|
|
1764
1561
|
if (summaryConfiguration.state === "enabled") {
|
|
1765
|
-
|
|
1562
|
+
validateSummaryHeuristicConfiguration(summaryConfiguration);
|
|
1766
1563
|
}
|
|
1767
1564
|
|
|
1768
1565
|
this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
|
|
@@ -1785,7 +1582,7 @@ export class ContainerRuntime
|
|
|
1785
1582
|
// If the context has ILayerCompatDetails, it supports referenceSequenceNumbers since that features
|
|
1786
1583
|
// predates ILayerCompatDetails.
|
|
1787
1584
|
const referenceSequenceNumbersSupported =
|
|
1788
|
-
|
|
1585
|
+
maybeloaderCompatDetailsForRuntime.ILayerCompatDetails === undefined
|
|
1789
1586
|
? supportedFeatures?.get("referenceSequenceNumbers") === true
|
|
1790
1587
|
: true;
|
|
1791
1588
|
if (
|
|
@@ -1883,13 +1680,14 @@ export class ContainerRuntime
|
|
|
1883
1680
|
// what is the interface of passing signals, we need the
|
|
1884
1681
|
// downstream stores to wrap the signal.
|
|
1885
1682
|
parentContext.submitSignal = (type: string, content: unknown, targetClientId?: string) => {
|
|
1683
|
+
// Future: Can the `content` argument type be IEnvelope?
|
|
1684
|
+
// verifyNotClosed is called in FluidDataStoreContext, which is *the* expected caller.
|
|
1886
1685
|
const envelope1 = content as IEnvelope;
|
|
1887
|
-
const envelope2 =
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
);
|
|
1892
|
-
return this.submitEnvelopedSignal(envelope2, targetClientId);
|
|
1686
|
+
const envelope2 = createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
|
|
1687
|
+
if (targetClientId === undefined) {
|
|
1688
|
+
this.signalTelemetryManager.applyTrackingToBroadcastSignalEnvelope(envelope2);
|
|
1689
|
+
}
|
|
1690
|
+
this.submitSignalFn(envelope2, targetClientId);
|
|
1893
1691
|
};
|
|
1894
1692
|
|
|
1895
1693
|
let snapshot: ISnapshot | ISnapshotTree | undefined = getSummaryForDatastores(
|
|
@@ -1919,8 +1717,8 @@ export class ContainerRuntime
|
|
|
1919
1717
|
|
|
1920
1718
|
this.blobManager = new BlobManager({
|
|
1921
1719
|
routeContext: this.handleContext,
|
|
1922
|
-
|
|
1923
|
-
|
|
1720
|
+
blobManagerLoadInfo,
|
|
1721
|
+
storage: this.storage,
|
|
1924
1722
|
sendBlobAttachOp: (localId: string, blobId?: string) => {
|
|
1925
1723
|
if (!this.disposed) {
|
|
1926
1724
|
this.submit(
|
|
@@ -1956,12 +1754,11 @@ export class ContainerRuntime
|
|
|
1956
1754
|
createChildLogger({ logger: this.baseLogger, namespace: "InboundBatchAggregator" }),
|
|
1957
1755
|
);
|
|
1958
1756
|
|
|
1959
|
-
const disablePartialFlush = this.mc.config.getBoolean(
|
|
1960
|
-
"Fluid.ContainerRuntime.DisablePartialFlush",
|
|
1961
|
-
);
|
|
1962
|
-
|
|
1963
1757
|
const legacySendBatchFn = makeLegacySendBatchFn(submitFn, this.innerDeltaManager);
|
|
1964
1758
|
|
|
1759
|
+
this.disableFlushBeforeProcess =
|
|
1760
|
+
this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableFlushBeforeProcess") === true;
|
|
1761
|
+
|
|
1965
1762
|
this.outbox = new Outbox({
|
|
1966
1763
|
shouldSend: () => this.canSendOps(),
|
|
1967
1764
|
pendingStateManager: this.pendingStateManager,
|
|
@@ -1972,16 +1769,18 @@ export class ContainerRuntime
|
|
|
1972
1769
|
config: {
|
|
1973
1770
|
compressionOptions,
|
|
1974
1771
|
maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
|
|
1975
|
-
|
|
1772
|
+
// If we disable flush before process, we must be ready to flush partial batches
|
|
1773
|
+
flushPartialBatches: this.disableFlushBeforeProcess,
|
|
1976
1774
|
},
|
|
1977
1775
|
logger: this.mc.logger,
|
|
1978
1776
|
groupingManager: opGroupingManager,
|
|
1979
1777
|
getCurrentSequenceNumbers: () => ({
|
|
1778
|
+
// Note: These sequence numbers only change when DeltaManager processes an incoming op
|
|
1980
1779
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
1981
1780
|
clientSequenceNumber: this._processedClientSequenceNumber,
|
|
1982
1781
|
}),
|
|
1983
1782
|
reSubmit: this.reSubmit.bind(this),
|
|
1984
|
-
opReentrancy: () => this.
|
|
1783
|
+
opReentrancy: () => this.dataModelChangeRunner.running,
|
|
1985
1784
|
closeContainer: this.closeFn,
|
|
1986
1785
|
});
|
|
1987
1786
|
|
|
@@ -2058,14 +1857,13 @@ export class ContainerRuntime
|
|
|
2058
1857
|
);
|
|
2059
1858
|
|
|
2060
1859
|
if (isSummarizerClient) {
|
|
2061
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2062
1860
|
this._summarizer = new Summarizer(
|
|
2063
1861
|
this /* ISummarizerRuntime */,
|
|
2064
1862
|
() => summaryConfiguration,
|
|
2065
1863
|
this /* ISummarizerInternalsProvider */,
|
|
2066
1864
|
this.handleContext,
|
|
2067
1865
|
summaryCollection,
|
|
2068
|
-
|
|
1866
|
+
|
|
2069
1867
|
async (runtime: IConnectableRuntime) =>
|
|
2070
1868
|
RunWhileConnectedCoordinator.create(
|
|
2071
1869
|
runtime,
|
|
@@ -2103,7 +1901,7 @@ export class ContainerRuntime
|
|
|
2103
1901
|
this, // IConnectedState
|
|
2104
1902
|
summaryCollection,
|
|
2105
1903
|
this.baseLogger,
|
|
2106
|
-
|
|
1904
|
+
formCreateSummarizerFn(loader),
|
|
2107
1905
|
new Throttler(
|
|
2108
1906
|
60 * 1000, // 60 sec delay window
|
|
2109
1907
|
30 * 1000, // 30 sec max delay
|
|
@@ -2146,14 +1944,14 @@ export class ContainerRuntime
|
|
|
2146
1944
|
summaryFormatVersion: metadata?.summaryFormatVersion,
|
|
2147
1945
|
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
2148
1946
|
gcVersion: metadata?.gcFeature,
|
|
2149
|
-
options: JSON.stringify(
|
|
1947
|
+
options: JSON.stringify(runtimeOptions),
|
|
2150
1948
|
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
2151
1949
|
idCompressorMode: this.sessionSchema.idCompressorMode,
|
|
2152
1950
|
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
2153
1951
|
featureGates: JSON.stringify({
|
|
2154
1952
|
...featureGatesForTelemetry,
|
|
2155
|
-
disablePartialFlush,
|
|
2156
1953
|
closeSummarizerDelayOverride,
|
|
1954
|
+
disableFlushBeforeProcess: this.disableFlushBeforeProcess,
|
|
2157
1955
|
}),
|
|
2158
1956
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
2159
1957
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
@@ -2175,7 +1973,6 @@ export class ContainerRuntime
|
|
|
2175
1973
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
2176
1974
|
}
|
|
2177
1975
|
|
|
2178
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2179
1976
|
public onSchemaChange(schema: IDocumentSchemaCurrent): void {
|
|
2180
1977
|
this.mc.logger.sendTelemetryEvent({
|
|
2181
1978
|
eventName: "SchemaChangeAccept",
|
|
@@ -2453,13 +2250,11 @@ export class ContainerRuntime
|
|
|
2453
2250
|
|
|
2454
2251
|
if (id === blobManagerBasePath && requestParser.isLeaf(2)) {
|
|
2455
2252
|
const blob = await this.blobManager.getBlob(requestParser.pathParts[1]);
|
|
2456
|
-
return
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
}
|
|
2462
|
-
: create404Response(request);
|
|
2253
|
+
return {
|
|
2254
|
+
status: 200,
|
|
2255
|
+
mimeType: "fluid/object",
|
|
2256
|
+
value: blob,
|
|
2257
|
+
};
|
|
2463
2258
|
} else if (requestParser.pathParts.length > 0) {
|
|
2464
2259
|
return await this.channelCollection.request(request);
|
|
2465
2260
|
}
|
|
@@ -2499,7 +2294,6 @@ export class ContainerRuntime
|
|
|
2499
2294
|
// Is document schema explicit control on?
|
|
2500
2295
|
const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
2501
2296
|
|
|
2502
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2503
2297
|
const metadata: IContainerRuntimeMetadata = {
|
|
2504
2298
|
...this.createContainerMetadata,
|
|
2505
2299
|
// Increment the summary number for the next summary that will be generated.
|
|
@@ -2513,8 +2307,7 @@ export class ContainerRuntime
|
|
|
2513
2307
|
// last message's sequence number.
|
|
2514
2308
|
// See also lastMessageFromMetadata()
|
|
2515
2309
|
message: explicitSchemaControl
|
|
2516
|
-
?
|
|
2517
|
-
({ sequenceNumber: -1 } as unknown as ISummaryMetadataMessage)
|
|
2310
|
+
? ({ sequenceNumber: -1 } as unknown as ISummaryMetadataMessage)
|
|
2518
2311
|
: message,
|
|
2519
2312
|
lastMessage: explicitSchemaControl ? message : undefined,
|
|
2520
2313
|
documentSchema,
|
|
@@ -2796,14 +2589,7 @@ export class ContainerRuntime
|
|
|
2796
2589
|
0x3cd /* Connection is possible only if container exists in storage */,
|
|
2797
2590
|
);
|
|
2798
2591
|
if (changeOfState) {
|
|
2799
|
-
this.
|
|
2800
|
-
this._signalTracking.signalsOutOfOrder = 0;
|
|
2801
|
-
this._signalTracking.signalTimestamp = 0;
|
|
2802
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement = 0;
|
|
2803
|
-
this._signalTracking.totalSignalsSentInLatencyWindow = 0;
|
|
2804
|
-
this._signalTracking.roundTripSignalSequenceNumber = undefined;
|
|
2805
|
-
this._signalTracking.trackingSignalSequenceNumber = undefined;
|
|
2806
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber = undefined;
|
|
2592
|
+
this.signalTelemetryManager.resetTracking();
|
|
2807
2593
|
}
|
|
2808
2594
|
}
|
|
2809
2595
|
|
|
@@ -2853,6 +2639,26 @@ export class ContainerRuntime
|
|
|
2853
2639
|
|
|
2854
2640
|
this.verifyNotClosed();
|
|
2855
2641
|
|
|
2642
|
+
if (!this.disableFlushBeforeProcess) {
|
|
2643
|
+
// Reference Sequence Number may be about to change, and it must be consistent across a batch, so flush now
|
|
2644
|
+
this.outbox.flush();
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
this.ensureNoDataModelChanges(() => {
|
|
2648
|
+
this.processInboundMessageOrBatch(messageCopy, local);
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
/**
|
|
2653
|
+
* Implementation of core logic for {@link ContainerRuntime.process}, once preconditions are established
|
|
2654
|
+
*
|
|
2655
|
+
* @param messageCopy - Shallow copy of the sequenced message. If it's a virtualized batch, we'll process
|
|
2656
|
+
* all messages in the batch here.
|
|
2657
|
+
*/
|
|
2658
|
+
private processInboundMessageOrBatch(
|
|
2659
|
+
messageCopy: ISequencedDocumentMessage,
|
|
2660
|
+
local: boolean,
|
|
2661
|
+
): void {
|
|
2856
2662
|
// Whether or not the message appears to be a runtime message from an up-to-date client.
|
|
2857
2663
|
// It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
|
|
2858
2664
|
// or something different, like a system message.
|
|
@@ -3014,9 +2820,7 @@ export class ContainerRuntime
|
|
|
3014
2820
|
try {
|
|
3015
2821
|
if (!runtimeBatch) {
|
|
3016
2822
|
for (const { message } of messagesWithMetadata) {
|
|
3017
|
-
this.
|
|
3018
|
-
this.observeNonRuntimeMessage(message);
|
|
3019
|
-
});
|
|
2823
|
+
this.observeNonRuntimeMessage(message);
|
|
3020
2824
|
}
|
|
3021
2825
|
return;
|
|
3022
2826
|
}
|
|
@@ -3040,21 +2844,19 @@ export class ContainerRuntime
|
|
|
3040
2844
|
if (!groupedBatch) {
|
|
3041
2845
|
for (const { message, localOpMetadata } of messagesWithMetadata) {
|
|
3042
2846
|
updateSequenceNumbers(message);
|
|
3043
|
-
this.
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
this.emit("op", message, true /* runtimeMessage */);
|
|
3057
|
-
});
|
|
2847
|
+
this.validateAndProcessRuntimeMessages(
|
|
2848
|
+
message as InboundSequencedContainerRuntimeMessage,
|
|
2849
|
+
[
|
|
2850
|
+
{
|
|
2851
|
+
contents: message.contents,
|
|
2852
|
+
localOpMetadata,
|
|
2853
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
2854
|
+
},
|
|
2855
|
+
],
|
|
2856
|
+
local,
|
|
2857
|
+
savedOp,
|
|
2858
|
+
);
|
|
2859
|
+
this.emit("op", message, true /* runtimeMessage */);
|
|
3058
2860
|
}
|
|
3059
2861
|
return;
|
|
3060
2862
|
}
|
|
@@ -3063,17 +2865,14 @@ export class ContainerRuntime
|
|
|
3063
2865
|
let previousMessage: InboundSequencedContainerRuntimeMessage | undefined;
|
|
3064
2866
|
|
|
3065
2867
|
// Process the previous bunch of messages.
|
|
3066
|
-
const
|
|
2868
|
+
const processBunchedMessages = (): void => {
|
|
3067
2869
|
assert(previousMessage !== undefined, 0xa67 /* previous message must exist */);
|
|
3068
|
-
this.
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
savedOp,
|
|
3075
|
-
);
|
|
3076
|
-
});
|
|
2870
|
+
this.validateAndProcessRuntimeMessages(
|
|
2871
|
+
previousMessage,
|
|
2872
|
+
bunchedMessagesContent,
|
|
2873
|
+
local,
|
|
2874
|
+
savedOp,
|
|
2875
|
+
);
|
|
3077
2876
|
bunchedMessagesContent = [];
|
|
3078
2877
|
};
|
|
3079
2878
|
|
|
@@ -3085,7 +2884,7 @@ export class ContainerRuntime
|
|
|
3085
2884
|
for (const { message, localOpMetadata } of messagesWithMetadata) {
|
|
3086
2885
|
const currentMessage = updateSequenceNumbers(message);
|
|
3087
2886
|
if (previousMessage && previousMessage.type !== currentMessage.type) {
|
|
3088
|
-
|
|
2887
|
+
processBunchedMessages();
|
|
3089
2888
|
}
|
|
3090
2889
|
previousMessage = currentMessage;
|
|
3091
2890
|
bunchedMessagesContent.push({
|
|
@@ -3096,7 +2895,7 @@ export class ContainerRuntime
|
|
|
3096
2895
|
}
|
|
3097
2896
|
|
|
3098
2897
|
// Process the last bunch of messages.
|
|
3099
|
-
|
|
2898
|
+
processBunchedMessages();
|
|
3100
2899
|
|
|
3101
2900
|
// Send the "op" events for the messages now that the ops have been processed.
|
|
3102
2901
|
for (const { message } of messagesWithMetadata) {
|
|
@@ -3207,7 +3006,6 @@ export class ContainerRuntime
|
|
|
3207
3006
|
}
|
|
3208
3007
|
case ContainerMessageType.DocumentSchemaChange: {
|
|
3209
3008
|
this.documentsSchemaController.processDocumentSchemaMessages(
|
|
3210
|
-
// eslint-disable-next-line import/no-deprecated
|
|
3211
3009
|
contents as IDocumentSchemaChangeMessage[],
|
|
3212
3010
|
local,
|
|
3213
3011
|
message.sequenceNumber,
|
|
@@ -3255,107 +3053,6 @@ export class ContainerRuntime
|
|
|
3255
3053
|
}
|
|
3256
3054
|
}
|
|
3257
3055
|
|
|
3258
|
-
/**
|
|
3259
|
-
* Emits the Signal event and update the perf signal data.
|
|
3260
|
-
*/
|
|
3261
|
-
private sendSignalTelemetryEvent(): void {
|
|
3262
|
-
const duration = Date.now() - this._signalTracking.signalTimestamp;
|
|
3263
|
-
this.mc.logger.sendPerformanceEvent({
|
|
3264
|
-
eventName: "SignalLatency",
|
|
3265
|
-
details: {
|
|
3266
|
-
duration, // Roundtrip duration of the tracked signal in milliseconds.
|
|
3267
|
-
sent: this._signalTracking.totalSignalsSentInLatencyWindow, // Signals sent since the last logged SignalLatency event.
|
|
3268
|
-
lost: this._signalTracking.signalsLost, // Signals lost since the last logged SignalLatency event.
|
|
3269
|
-
outOfOrder: this._signalTracking.signalsOutOfOrder, // Out of order signals since the last logged SignalLatency event.
|
|
3270
|
-
reconnectCount: this.consecutiveReconnects, // Container reconnect count.
|
|
3271
|
-
},
|
|
3272
|
-
});
|
|
3273
|
-
this._signalTracking.signalsLost = 0;
|
|
3274
|
-
this._signalTracking.signalsOutOfOrder = 0;
|
|
3275
|
-
this._signalTracking.signalTimestamp = 0;
|
|
3276
|
-
this._signalTracking.totalSignalsSentInLatencyWindow = 0;
|
|
3277
|
-
}
|
|
3278
|
-
|
|
3279
|
-
/**
|
|
3280
|
-
* Updates signal telemetry including emitting telemetry events.
|
|
3281
|
-
*/
|
|
3282
|
-
private processSignalForTelemetry(envelope: ISignalEnvelope): void {
|
|
3283
|
-
const {
|
|
3284
|
-
clientBroadcastSignalSequenceNumber,
|
|
3285
|
-
contents: envelopeContents,
|
|
3286
|
-
address: envelopeAddress,
|
|
3287
|
-
} = envelope;
|
|
3288
|
-
if (clientBroadcastSignalSequenceNumber === undefined) {
|
|
3289
|
-
return;
|
|
3290
|
-
}
|
|
3291
|
-
|
|
3292
|
-
if (
|
|
3293
|
-
this._signalTracking.trackingSignalSequenceNumber === undefined ||
|
|
3294
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber === undefined
|
|
3295
|
-
) {
|
|
3296
|
-
return;
|
|
3297
|
-
}
|
|
3298
|
-
|
|
3299
|
-
if (
|
|
3300
|
-
clientBroadcastSignalSequenceNumber >= this._signalTracking.trackingSignalSequenceNumber
|
|
3301
|
-
) {
|
|
3302
|
-
// Calculate the number of signals lost and log the event.
|
|
3303
|
-
const signalsLost =
|
|
3304
|
-
clientBroadcastSignalSequenceNumber -
|
|
3305
|
-
this._signalTracking.trackingSignalSequenceNumber;
|
|
3306
|
-
if (signalsLost > 0) {
|
|
3307
|
-
this._signalTracking.signalsLost += signalsLost;
|
|
3308
|
-
this.mc.logger.sendErrorEvent({
|
|
3309
|
-
eventName: "SignalLost",
|
|
3310
|
-
details: {
|
|
3311
|
-
signalsLost, // Number of lost signals detected.
|
|
3312
|
-
expectedSequenceNumber: this._signalTracking.trackingSignalSequenceNumber, // The next expected signal sequence number.
|
|
3313
|
-
clientBroadcastSignalSequenceNumber, // Actual signal sequence number received.
|
|
3314
|
-
},
|
|
3315
|
-
});
|
|
3316
|
-
}
|
|
3317
|
-
// Update the tracking signal sequence number to the next expected signal in the sequence.
|
|
3318
|
-
this._signalTracking.trackingSignalSequenceNumber =
|
|
3319
|
-
clientBroadcastSignalSequenceNumber + 1;
|
|
3320
|
-
} else if (
|
|
3321
|
-
// Check if this is a signal in range of interest.
|
|
3322
|
-
clientBroadcastSignalSequenceNumber >=
|
|
3323
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber
|
|
3324
|
-
) {
|
|
3325
|
-
this._signalTracking.signalsOutOfOrder++;
|
|
3326
|
-
const details: TelemetryEventPropertyTypeExt = {
|
|
3327
|
-
expectedSequenceNumber: this._signalTracking.trackingSignalSequenceNumber, // The next expected signal sequence number.
|
|
3328
|
-
clientBroadcastSignalSequenceNumber, // Sequence number of the out of order signal.
|
|
3329
|
-
};
|
|
3330
|
-
// Only log `contents.type` when address is for container to avoid
|
|
3331
|
-
// chance that contents type is customer data.
|
|
3332
|
-
if (envelopeAddress === undefined) {
|
|
3333
|
-
details.contentsType = envelopeContents.type; // Type of signal that was received out of order.
|
|
3334
|
-
}
|
|
3335
|
-
this.mc.logger.sendTelemetryEvent({
|
|
3336
|
-
eventName: "SignalOutOfOrder",
|
|
3337
|
-
details,
|
|
3338
|
-
});
|
|
3339
|
-
}
|
|
3340
|
-
if (
|
|
3341
|
-
this._signalTracking.roundTripSignalSequenceNumber !== undefined &&
|
|
3342
|
-
clientBroadcastSignalSequenceNumber >= this._signalTracking.roundTripSignalSequenceNumber
|
|
3343
|
-
) {
|
|
3344
|
-
if (
|
|
3345
|
-
clientBroadcastSignalSequenceNumber ===
|
|
3346
|
-
this._signalTracking.roundTripSignalSequenceNumber
|
|
3347
|
-
) {
|
|
3348
|
-
// Latency tracked signal has been received.
|
|
3349
|
-
// We now log the roundtrip duration of the tracked signal.
|
|
3350
|
-
// This telemetry event also logs metrics for broadcast signals
|
|
3351
|
-
// sent, lost, and out of order.
|
|
3352
|
-
// These metrics are reset after logging the telemetry event.
|
|
3353
|
-
this.sendSignalTelemetryEvent();
|
|
3354
|
-
}
|
|
3355
|
-
this._signalTracking.roundTripSignalSequenceNumber = undefined;
|
|
3356
|
-
}
|
|
3357
|
-
}
|
|
3358
|
-
|
|
3359
3056
|
public processSignal(message: ISignalMessage, local: boolean): void {
|
|
3360
3057
|
const envelope = message.content as ISignalEnvelope;
|
|
3361
3058
|
const transformed: IInboundSignalMessage = {
|
|
@@ -3367,7 +3064,11 @@ export class ContainerRuntime
|
|
|
3367
3064
|
|
|
3368
3065
|
// Only collect signal telemetry for broadcast messages sent by the current client.
|
|
3369
3066
|
if (message.clientId === this.clientId) {
|
|
3370
|
-
this.
|
|
3067
|
+
this.signalTelemetryManager.trackReceivedSignal(
|
|
3068
|
+
envelope,
|
|
3069
|
+
this.mc.logger,
|
|
3070
|
+
this.consecutiveReconnects,
|
|
3071
|
+
);
|
|
3371
3072
|
}
|
|
3372
3073
|
|
|
3373
3074
|
if (envelope.address === undefined) {
|
|
@@ -3396,8 +3097,8 @@ export class ContainerRuntime
|
|
|
3396
3097
|
*/
|
|
3397
3098
|
private flush(resubmittingBatchId?: BatchId): void {
|
|
3398
3099
|
assert(
|
|
3399
|
-
this.
|
|
3400
|
-
0x24c /* "Cannot call `flush()`
|
|
3100
|
+
!this.batchRunner.running,
|
|
3101
|
+
0x24c /* "Cannot call `flush()` while manually accumulating a batch (e.g. under orderSequentially) */,
|
|
3401
3102
|
);
|
|
3402
3103
|
|
|
3403
3104
|
this.outbox.flush(resubmittingBatchId);
|
|
@@ -3409,57 +3110,60 @@ export class ContainerRuntime
|
|
|
3409
3110
|
*/
|
|
3410
3111
|
public orderSequentially<T>(callback: () => T): T {
|
|
3411
3112
|
let checkpoint: IBatchCheckpoint | undefined;
|
|
3412
|
-
|
|
3113
|
+
const checkpointDirtyState = this.dirtyContainer;
|
|
3413
3114
|
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
3414
3115
|
// Note: we are not touching any batches other than mainBatch here, for two reasons:
|
|
3415
3116
|
// 1. It would not help, as other batches are flushed independently from main batch.
|
|
3416
3117
|
// 2. There is no way to undo process of data store creation, blob creation, ID compressor ops, or other things tracked by other batches.
|
|
3417
3118
|
checkpoint = this.outbox.getBatchCheckpoints().mainBatch;
|
|
3418
3119
|
}
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3120
|
+
const result = this.batchRunner.run(() => {
|
|
3121
|
+
try {
|
|
3122
|
+
return callback();
|
|
3123
|
+
} catch (error) {
|
|
3124
|
+
if (checkpoint) {
|
|
3125
|
+
// This will throw and close the container if rollback fails
|
|
3126
|
+
try {
|
|
3127
|
+
checkpoint.rollback((message: BatchMessage) =>
|
|
3128
|
+
this.rollback(message.contents, message.localOpMetadata),
|
|
3129
|
+
);
|
|
3130
|
+
// reset the dirty state after rollback to what it was before to keep it consistent
|
|
3131
|
+
if (this.dirtyContainer !== checkpointDirtyState) {
|
|
3132
|
+
this.updateDocumentDirtyState(checkpointDirtyState);
|
|
3133
|
+
}
|
|
3134
|
+
} catch (error_) {
|
|
3135
|
+
const error2 = wrapError(error_, (message) => {
|
|
3136
|
+
return DataProcessingError.create(
|
|
3137
|
+
`RollbackError: ${message}`,
|
|
3138
|
+
"checkpointRollback",
|
|
3139
|
+
undefined,
|
|
3140
|
+
) as DataProcessingError;
|
|
3141
|
+
});
|
|
3142
|
+
this.closeFn(error2);
|
|
3143
|
+
throw error2;
|
|
3144
|
+
}
|
|
3145
|
+
} else {
|
|
3146
|
+
this.closeFn(
|
|
3147
|
+
wrapError(
|
|
3148
|
+
error,
|
|
3149
|
+
(errorMessage) =>
|
|
3150
|
+
new GenericError(
|
|
3151
|
+
`orderSequentially callback exception: ${errorMessage}`,
|
|
3152
|
+
error,
|
|
3153
|
+
{
|
|
3154
|
+
orderSequentiallyCalls: this.batchRunner.runs,
|
|
3155
|
+
},
|
|
3156
|
+
),
|
|
3157
|
+
),
|
|
3428
3158
|
);
|
|
3429
|
-
} catch (error_) {
|
|
3430
|
-
const error2 = wrapError(error_, (message) => {
|
|
3431
|
-
return DataProcessingError.create(
|
|
3432
|
-
`RollbackError: ${message}`,
|
|
3433
|
-
"checkpointRollback",
|
|
3434
|
-
undefined,
|
|
3435
|
-
) as DataProcessingError;
|
|
3436
|
-
});
|
|
3437
|
-
this.closeFn(error2);
|
|
3438
|
-
throw error2;
|
|
3439
3159
|
}
|
|
3440
|
-
} else {
|
|
3441
|
-
this.closeFn(
|
|
3442
|
-
wrapError(
|
|
3443
|
-
error,
|
|
3444
|
-
(errorMessage) =>
|
|
3445
|
-
new GenericError(
|
|
3446
|
-
`orderSequentially callback exception: ${errorMessage}`,
|
|
3447
|
-
error,
|
|
3448
|
-
{
|
|
3449
|
-
orderSequentiallyCalls: this._orderSequentiallyCalls,
|
|
3450
|
-
},
|
|
3451
|
-
),
|
|
3452
|
-
),
|
|
3453
|
-
);
|
|
3454
|
-
}
|
|
3455
3160
|
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
}
|
|
3161
|
+
throw error; // throw the original error for the consumer of the runtime
|
|
3162
|
+
}
|
|
3163
|
+
});
|
|
3460
3164
|
|
|
3461
3165
|
// We don't flush on TurnBased since we expect all messages in the same JS turn to be part of the same batch
|
|
3462
|
-
if (this.flushMode !== FlushMode.TurnBased && this.
|
|
3166
|
+
if (this.flushMode !== FlushMode.TurnBased && !this.batchRunner.running) {
|
|
3463
3167
|
this.flush();
|
|
3464
3168
|
}
|
|
3465
3169
|
return result;
|
|
@@ -3540,7 +3244,7 @@ export class ContainerRuntime
|
|
|
3540
3244
|
* Typically ops are batched and later flushed together, but in some cases we want to flush immediately.
|
|
3541
3245
|
*/
|
|
3542
3246
|
private currentlyBatching(): boolean {
|
|
3543
|
-
return this.flushMode !== FlushMode.Immediate || this.
|
|
3247
|
+
return this.flushMode !== FlushMode.Immediate || this.batchRunner.running;
|
|
3544
3248
|
}
|
|
3545
3249
|
|
|
3546
3250
|
private readonly _quorum: IQuorumClients;
|
|
@@ -3594,59 +3298,6 @@ export class ContainerRuntime
|
|
|
3594
3298
|
return true;
|
|
3595
3299
|
}
|
|
3596
3300
|
|
|
3597
|
-
private createNewSignalEnvelope(
|
|
3598
|
-
address: string | undefined,
|
|
3599
|
-
type: string,
|
|
3600
|
-
content: unknown,
|
|
3601
|
-
): Omit<ISignalEnvelope, "broadcastSignalSequenceNumber"> {
|
|
3602
|
-
const newEnvelope: Omit<ISignalEnvelope, "broadcastSignalSequenceNumber"> = {
|
|
3603
|
-
address,
|
|
3604
|
-
contents: { type, content },
|
|
3605
|
-
};
|
|
3606
|
-
|
|
3607
|
-
return newEnvelope;
|
|
3608
|
-
}
|
|
3609
|
-
|
|
3610
|
-
private submitEnvelopedSignal(envelope: ISignalEnvelope, targetClientId?: string): void {
|
|
3611
|
-
const isBroadcastSignal = targetClientId === undefined;
|
|
3612
|
-
|
|
3613
|
-
if (isBroadcastSignal) {
|
|
3614
|
-
const clientBroadcastSignalSequenceNumber = ++this._signalTracking
|
|
3615
|
-
.broadcastSignalSequenceNumber;
|
|
3616
|
-
// Stamp with the broadcast signal sequence number.
|
|
3617
|
-
envelope.clientBroadcastSignalSequenceNumber = clientBroadcastSignalSequenceNumber;
|
|
3618
|
-
|
|
3619
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement++;
|
|
3620
|
-
|
|
3621
|
-
if (
|
|
3622
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber === undefined ||
|
|
3623
|
-
this._signalTracking.trackingSignalSequenceNumber === undefined
|
|
3624
|
-
) {
|
|
3625
|
-
// Signal monitoring window is undefined
|
|
3626
|
-
// Initialize tracking to expect the next signal sent by the connected client.
|
|
3627
|
-
this._signalTracking.minimumTrackingSignalSequenceNumber =
|
|
3628
|
-
clientBroadcastSignalSequenceNumber;
|
|
3629
|
-
this._signalTracking.trackingSignalSequenceNumber =
|
|
3630
|
-
clientBroadcastSignalSequenceNumber;
|
|
3631
|
-
}
|
|
3632
|
-
|
|
3633
|
-
// We should not track the round trip of a new signal in the case we are already tracking one.
|
|
3634
|
-
if (
|
|
3635
|
-
clientBroadcastSignalSequenceNumber % defaultTelemetrySignalSampleCount === 1 &&
|
|
3636
|
-
this._signalTracking.roundTripSignalSequenceNumber === undefined
|
|
3637
|
-
) {
|
|
3638
|
-
this._signalTracking.signalTimestamp = Date.now();
|
|
3639
|
-
this._signalTracking.roundTripSignalSequenceNumber =
|
|
3640
|
-
clientBroadcastSignalSequenceNumber;
|
|
3641
|
-
this._signalTracking.totalSignalsSentInLatencyWindow +=
|
|
3642
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement;
|
|
3643
|
-
this._signalTracking.signalsSentSinceLastLatencyMeasurement = 0;
|
|
3644
|
-
}
|
|
3645
|
-
}
|
|
3646
|
-
|
|
3647
|
-
this.submitSignalFn(envelope, targetClientId);
|
|
3648
|
-
}
|
|
3649
|
-
|
|
3650
3301
|
/**
|
|
3651
3302
|
* Submits the signal to be sent to other clients.
|
|
3652
3303
|
* @param type - Type of the signal.
|
|
@@ -3661,8 +3312,11 @@ export class ContainerRuntime
|
|
|
3661
3312
|
*/
|
|
3662
3313
|
public submitSignal(type: string, content: unknown, targetClientId?: string): void {
|
|
3663
3314
|
this.verifyNotClosed();
|
|
3664
|
-
const envelope =
|
|
3665
|
-
|
|
3315
|
+
const envelope = createNewSignalEnvelope(undefined /* address */, type, content);
|
|
3316
|
+
if (targetClientId === undefined) {
|
|
3317
|
+
this.signalTelemetryManager.applyTrackingToBroadcastSignalEnvelope(envelope);
|
|
3318
|
+
}
|
|
3319
|
+
this.submitSignalFn(envelope, targetClientId);
|
|
3666
3320
|
}
|
|
3667
3321
|
|
|
3668
3322
|
public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {
|
|
@@ -3911,13 +3565,12 @@ export class ContainerRuntime
|
|
|
3911
3565
|
* Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
|
|
3912
3566
|
* blob manager.
|
|
3913
3567
|
*/
|
|
3914
|
-
|
|
3568
|
+
|
|
3915
3569
|
public getNodeType(nodePath: string): GCNodeType {
|
|
3916
3570
|
if (isBlobPath(nodePath)) {
|
|
3917
|
-
// eslint-disable-next-line import/no-deprecated
|
|
3918
3571
|
return GCNodeType.Blob;
|
|
3919
3572
|
}
|
|
3920
|
-
|
|
3573
|
+
|
|
3921
3574
|
return this.channelCollection.getGCNodeType(nodePath) ?? GCNodeType.Other;
|
|
3922
3575
|
}
|
|
3923
3576
|
|
|
@@ -3933,13 +3586,12 @@ export class ContainerRuntime
|
|
|
3933
3586
|
}
|
|
3934
3587
|
|
|
3935
3588
|
switch (this.getNodeType(nodePath)) {
|
|
3936
|
-
// eslint-disable-next-line import/no-deprecated
|
|
3937
3589
|
case GCNodeType.Blob: {
|
|
3938
3590
|
return [blobManagerBasePath];
|
|
3939
3591
|
}
|
|
3940
|
-
|
|
3592
|
+
|
|
3941
3593
|
case GCNodeType.DataStore:
|
|
3942
|
-
|
|
3594
|
+
|
|
3943
3595
|
case GCNodeType.SubDataStore: {
|
|
3944
3596
|
return this.channelCollection.getDataStorePackagePath(nodePath);
|
|
3945
3597
|
}
|
|
@@ -3991,7 +3643,6 @@ export class ContainerRuntime
|
|
|
3991
3643
|
fullGC?: boolean;
|
|
3992
3644
|
},
|
|
3993
3645
|
telemetryContext?: ITelemetryContext,
|
|
3994
|
-
// eslint-disable-next-line import/no-deprecated
|
|
3995
3646
|
): Promise<IGCStats | undefined> {
|
|
3996
3647
|
return this.garbageCollector.collectGarbage(options, telemetryContext);
|
|
3997
3648
|
}
|
|
@@ -4034,7 +3685,7 @@ export class ContainerRuntime
|
|
|
4034
3685
|
* op processing, updating SummarizerNode state tracking, and garbage collection.
|
|
4035
3686
|
* @param options - options controlling how the summary is generated or submitted
|
|
4036
3687
|
*/
|
|
4037
|
-
|
|
3688
|
+
|
|
4038
3689
|
public async submitSummary(options: ISubmitSummaryOptions): Promise<SubmitSummaryResult> {
|
|
4039
3690
|
const {
|
|
4040
3691
|
cancellationToken,
|
|
@@ -4662,8 +4313,8 @@ export class ContainerRuntime
|
|
|
4662
4313
|
|
|
4663
4314
|
default: {
|
|
4664
4315
|
assert(
|
|
4665
|
-
this.
|
|
4666
|
-
0x587 /* Unreachable unless
|
|
4316
|
+
this.batchRunner.running,
|
|
4317
|
+
0x587 /* Unreachable unless manually accumulating a batch */,
|
|
4667
4318
|
);
|
|
4668
4319
|
break;
|
|
4669
4320
|
}
|
|
@@ -4703,7 +4354,7 @@ export class ContainerRuntime
|
|
|
4703
4354
|
* for correlation to detect container forking.
|
|
4704
4355
|
*/
|
|
4705
4356
|
private reSubmitBatch(batch: PendingMessageResubmitData[], batchId: BatchId): void {
|
|
4706
|
-
this.
|
|
4357
|
+
this.batchRunner.run(() => {
|
|
4707
4358
|
for (const message of batch) {
|
|
4708
4359
|
this.reSubmit(message);
|
|
4709
4360
|
}
|
|
@@ -4800,7 +4451,7 @@ export class ContainerRuntime
|
|
|
4800
4451
|
/**
|
|
4801
4452
|
* Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck
|
|
4802
4453
|
*/
|
|
4803
|
-
|
|
4454
|
+
|
|
4804
4455
|
public async refreshLatestSummaryAck(options: IRefreshSummaryAckOptions): Promise<void> {
|
|
4805
4456
|
const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
|
|
4806
4457
|
// proposalHandle is always passed from RunningSummarizer.
|
|
@@ -4951,8 +4602,8 @@ export class ContainerRuntime
|
|
|
4951
4602
|
public getPendingLocalState(props?: IGetPendingLocalStateProps): unknown {
|
|
4952
4603
|
this.verifyNotClosed();
|
|
4953
4604
|
|
|
4954
|
-
if (this.
|
|
4955
|
-
throw new UsageError("can't get state
|
|
4605
|
+
if (this.batchRunner.running) {
|
|
4606
|
+
throw new UsageError("can't get state while manually accumulating a batch");
|
|
4956
4607
|
}
|
|
4957
4608
|
this.imminentClosure ||= props?.notifyImminentClosure ?? false;
|
|
4958
4609
|
|
|
@@ -5032,34 +4683,20 @@ export class ContainerRuntime
|
|
|
5032
4683
|
}
|
|
5033
4684
|
}
|
|
5034
4685
|
|
|
5035
|
-
/**
|
|
5036
|
-
* Forms a function that will create and retrieve a Summarizer.
|
|
5037
|
-
*/
|
|
5038
|
-
private formCreateSummarizerFn(loader: ILoader) {
|
|
5039
|
-
return async () => {
|
|
5040
|
-
return createSummarizer(loader, `/${summarizerRequestUrl}`);
|
|
5041
|
-
};
|
|
5042
|
-
}
|
|
5043
|
-
|
|
5044
|
-
private validateSummaryHeuristicConfiguration(
|
|
5045
|
-
configuration: ISummaryConfigurationHeuristics,
|
|
5046
|
-
): void {
|
|
5047
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
5048
|
-
for (const prop in configuration) {
|
|
5049
|
-
if (typeof configuration[prop] === "number" && configuration[prop] < 0) {
|
|
5050
|
-
throw new UsageError(
|
|
5051
|
-
`Summary heuristic configuration property "${prop}" cannot be less than 0`,
|
|
5052
|
-
);
|
|
5053
|
-
}
|
|
5054
|
-
}
|
|
5055
|
-
if (configuration.minIdleTime > configuration.maxIdleTime) {
|
|
5056
|
-
throw new UsageError(
|
|
5057
|
-
`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`,
|
|
5058
|
-
);
|
|
5059
|
-
}
|
|
5060
|
-
}
|
|
5061
|
-
|
|
5062
4686
|
private get groupedBatchingEnabled(): boolean {
|
|
5063
4687
|
return this.sessionSchema.opGroupingEnabled === true;
|
|
5064
4688
|
}
|
|
5065
4689
|
}
|
|
4690
|
+
|
|
4691
|
+
export function createNewSignalEnvelope(
|
|
4692
|
+
address: string | undefined,
|
|
4693
|
+
type: string,
|
|
4694
|
+
content: unknown,
|
|
4695
|
+
): Omit<ISignalEnvelope, "broadcastSignalSequenceNumber"> {
|
|
4696
|
+
const newEnvelope: Omit<ISignalEnvelope, "broadcastSignalSequenceNumber"> = {
|
|
4697
|
+
address,
|
|
4698
|
+
contents: { type, content },
|
|
4699
|
+
};
|
|
4700
|
+
|
|
4701
|
+
return newEnvelope;
|
|
4702
|
+
}
|