@fluidframework/container-runtime 2.0.0-internal.5.1.1 → 2.0.0-internal.5.3.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 +20 -0
- package/dist/blobManager.d.ts +5 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +51 -22
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +8 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +5 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +27 -7
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -2
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +4 -3
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +2 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +2 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStores.d.ts +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +2 -1
- package/dist/dataStores.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +4 -3
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +0 -1
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +18 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +7 -0
- package/dist/metadata.js.map +1 -0
- package/dist/opLifecycle/batchManager.d.ts +2 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +5 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +11 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +14 -8
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +2 -6
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +2 -0
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +33 -2
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +128 -42
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +3 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +7 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +36 -21
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +8 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +1 -1
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +3 -3
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +3 -2
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +2 -1
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -1
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +4 -0
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +1 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +2 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +1 -1
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +2 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/blobManager.d.ts +5 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +51 -22
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +8 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +5 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +29 -9
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -2
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +4 -3
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +2 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +2 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStores.d.ts +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +2 -1
- package/lib/dataStores.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +2 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +0 -1
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/metadata.d.ts +18 -0
- package/lib/metadata.d.ts.map +1 -0
- package/lib/metadata.js +6 -0
- package/lib/metadata.js.map +1 -0
- package/lib/opLifecycle/batchManager.d.ts +2 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +5 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +11 -0
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +14 -8
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +2 -6
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +2 -0
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +33 -2
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +126 -41
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +3 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +7 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +36 -21
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +8 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +1 -1
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +3 -3
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +2 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +2 -1
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -1
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +4 -0
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +1 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +2 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +1 -1
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +2 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +20 -19
- package/src/blobManager.ts +68 -27
- package/src/connectionTelemetry.ts +10 -1
- package/src/containerRuntime.ts +37 -14
- package/src/dataStoreContext.ts +12 -5
- package/src/dataStoreContexts.ts +4 -2
- package/src/dataStores.ts +8 -3
- package/src/gc/garbageCollection.ts +2 -1
- package/src/gc/gcDefinitions.ts +0 -1
- package/src/gc/gcTelemetry.ts +1 -1
- package/src/index.ts +1 -0
- package/src/metadata.ts +19 -0
- package/src/opLifecycle/README.md +20 -0
- package/src/opLifecycle/batchManager.ts +9 -1
- package/src/opLifecycle/definitions.ts +11 -0
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opDecompressor.ts +41 -13
- package/src/opLifecycle/opGroupingManager.ts +14 -7
- package/src/opLifecycle/opSplitter.ts +3 -1
- package/src/opLifecycle/outbox.ts +163 -49
- package/src/opLifecycle/remoteMessageProcessor.ts +5 -1
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +56 -41
- package/src/scheduleManager.ts +15 -6
- package/src/summary/index.ts +1 -0
- package/src/summary/runningSummarizer.ts +1 -1
- package/src/summary/summarizerNode/summarizerNode.ts +4 -4
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +2 -1
- package/src/summary/summarizerTypes.ts +2 -1
- package/src/summary/summaryCollection.ts +8 -3
- package/src/summary/summaryFormat.ts +5 -1
- package/src/summary/summaryGenerator.ts +1 -1
- package/src/summary/summaryManager.ts +2 -1
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
MonitoringContext,
|
|
11
11
|
} from "@fluidframework/telemetry-utils";
|
|
12
12
|
import { assert } from "@fluidframework/common-utils";
|
|
13
|
-
import { IContainerContext } from "@fluidframework/container-definitions";
|
|
13
|
+
import { IContainerContext, ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
14
14
|
import { GenericError, UsageError } from "@fluidframework/container-utils";
|
|
15
15
|
import { MessageType } from "@fluidframework/protocol-definitions";
|
|
16
16
|
import { ICompressionRuntimeOptions } from "../containerRuntime";
|
|
17
|
-
import { PendingStateManager } from "../pendingStateManager";
|
|
17
|
+
import { IPendingBatchMessage, PendingStateManager } from "../pendingStateManager";
|
|
18
18
|
import {
|
|
19
19
|
BatchManager,
|
|
20
20
|
BatchSequenceNumbers,
|
|
@@ -31,6 +31,7 @@ export interface IOutboxConfig {
|
|
|
31
31
|
// The maximum size of a batch that we can send over the wire.
|
|
32
32
|
readonly maxBatchSizeInBytes: number;
|
|
33
33
|
readonly disablePartialFlush: boolean;
|
|
34
|
+
readonly enableGroupedBatching: boolean;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export interface IOutboxParameters {
|
|
@@ -43,18 +44,40 @@ export interface IOutboxParameters {
|
|
|
43
44
|
readonly logger: ITelemetryLoggerExt;
|
|
44
45
|
readonly groupingManager: OpGroupingManager;
|
|
45
46
|
readonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;
|
|
47
|
+
readonly reSubmit: (message: IPendingBatchMessage) => void;
|
|
48
|
+
readonly opReentrancy: () => boolean;
|
|
49
|
+
readonly closeContainer: (error?: ICriticalContainerError) => void;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Temporarily increase the stack limit while executing the provided action.
|
|
54
|
+
* If a negative value is provided for `length`, no stack frames will be collected.
|
|
55
|
+
* If Infinity is provided, all frames will be collected.
|
|
56
|
+
*
|
|
57
|
+
* ADO:4663 - add this to the common packages.
|
|
58
|
+
*
|
|
59
|
+
* @param action - action which returns an error
|
|
60
|
+
* @param length - number of stack frames to collect, 50 if unspecified.
|
|
61
|
+
* @returns the result of the action provided
|
|
62
|
+
*/
|
|
63
|
+
export function getLongStack<T>(action: () => T, length: number = 50): T {
|
|
64
|
+
const errorObj = Error as any;
|
|
65
|
+
if (
|
|
66
|
+
(
|
|
67
|
+
Object.getOwnPropertyDescriptor(errorObj, "stackTraceLimit") ||
|
|
68
|
+
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), "stackTraceLimit") ||
|
|
69
|
+
{}
|
|
70
|
+
).writable !== true
|
|
71
|
+
) {
|
|
72
|
+
return action();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const originalStackTraceLimit = errorObj.stackTraceLimit;
|
|
50
76
|
try {
|
|
51
|
-
|
|
52
|
-
(Error as any).stackTraceLimit = 50;
|
|
53
|
-
const result = action();
|
|
54
|
-
(Error as any).stackTraceLimit = originalStackTraceLimit;
|
|
55
|
-
return result;
|
|
56
|
-
} catch (error) {
|
|
77
|
+
errorObj.stackTraceLimit = length;
|
|
57
78
|
return action();
|
|
79
|
+
} finally {
|
|
80
|
+
errorObj.stackTraceLimit = originalStackTraceLimit;
|
|
58
81
|
}
|
|
59
82
|
}
|
|
60
83
|
|
|
@@ -62,7 +85,10 @@ export class Outbox {
|
|
|
62
85
|
private readonly mc: MonitoringContext;
|
|
63
86
|
private readonly attachFlowBatch: BatchManager;
|
|
64
87
|
private readonly mainBatch: BatchManager;
|
|
88
|
+
private readonly blobAttachBatch: BatchManager;
|
|
65
89
|
private readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;
|
|
90
|
+
private batchRebasesToReport = 5;
|
|
91
|
+
private rebasing = false;
|
|
66
92
|
|
|
67
93
|
/**
|
|
68
94
|
* Track the number of ops which were detected to have a mismatched
|
|
@@ -84,10 +110,15 @@ export class Outbox {
|
|
|
84
110
|
|
|
85
111
|
this.attachFlowBatch = new BatchManager({ hardLimit, softLimit });
|
|
86
112
|
this.mainBatch = new BatchManager({ hardLimit });
|
|
113
|
+
this.blobAttachBatch = new BatchManager({ hardLimit });
|
|
87
114
|
}
|
|
88
115
|
|
|
89
116
|
public get isEmpty(): boolean {
|
|
90
|
-
return
|
|
117
|
+
return (
|
|
118
|
+
this.attachFlowBatch.length === 0 &&
|
|
119
|
+
this.mainBatch.length === 0 &&
|
|
120
|
+
this.blobAttachBatch.length === 0
|
|
121
|
+
);
|
|
91
122
|
}
|
|
92
123
|
|
|
93
124
|
/**
|
|
@@ -99,9 +130,11 @@ export class Outbox {
|
|
|
99
130
|
private maybeFlushPartialBatch() {
|
|
100
131
|
const mainBatchSeqNums = this.mainBatch.sequenceNumbers;
|
|
101
132
|
const attachFlowBatchSeqNums = this.attachFlowBatch.sequenceNumbers;
|
|
133
|
+
const blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;
|
|
102
134
|
assert(
|
|
103
135
|
this.params.config.disablePartialFlush ||
|
|
104
|
-
sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums)
|
|
136
|
+
(sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums) &&
|
|
137
|
+
sequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums)),
|
|
105
138
|
0x58d /* Reference sequence numbers from both batches must be in sync */,
|
|
106
139
|
);
|
|
107
140
|
|
|
@@ -109,7 +142,8 @@ export class Outbox {
|
|
|
109
142
|
|
|
110
143
|
if (
|
|
111
144
|
sequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&
|
|
112
|
-
sequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers)
|
|
145
|
+
sequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers) &&
|
|
146
|
+
sequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers)
|
|
113
147
|
) {
|
|
114
148
|
// The reference sequence numbers are stable, there is nothing to do
|
|
115
149
|
return;
|
|
@@ -124,6 +158,8 @@ export class Outbox {
|
|
|
124
158
|
mainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,
|
|
125
159
|
attachReferenceSequenceNumber: attachFlowBatchSeqNums.referenceSequenceNumber,
|
|
126
160
|
attachClientSequenceNumber: attachFlowBatchSeqNums.clientSequenceNumber,
|
|
161
|
+
blobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,
|
|
162
|
+
blobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,
|
|
127
163
|
currentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,
|
|
128
164
|
currentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,
|
|
129
165
|
},
|
|
@@ -132,26 +168,14 @@ export class Outbox {
|
|
|
132
168
|
}
|
|
133
169
|
|
|
134
170
|
if (!this.params.config.disablePartialFlush) {
|
|
135
|
-
this.
|
|
171
|
+
this.flushAll();
|
|
136
172
|
}
|
|
137
173
|
}
|
|
138
174
|
|
|
139
175
|
public submit(message: BatchMessage) {
|
|
140
176
|
this.maybeFlushPartialBatch();
|
|
141
177
|
|
|
142
|
-
|
|
143
|
-
!this.mainBatch.push(
|
|
144
|
-
message,
|
|
145
|
-
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
146
|
-
)
|
|
147
|
-
) {
|
|
148
|
-
throw new GenericError("BatchTooLarge", /* error */ undefined, {
|
|
149
|
-
opSize: message.contents?.length ?? 0,
|
|
150
|
-
batchSize: this.mainBatch.contentSizeInBytes,
|
|
151
|
-
count: this.mainBatch.length,
|
|
152
|
-
limit: this.mainBatch.options.hardLimit,
|
|
153
|
-
});
|
|
154
|
-
}
|
|
178
|
+
this.addMessageToBatchManager(this.mainBatch, message);
|
|
155
179
|
}
|
|
156
180
|
|
|
157
181
|
public submitAttach(message: BatchMessage) {
|
|
@@ -160,26 +184,16 @@ export class Outbox {
|
|
|
160
184
|
if (
|
|
161
185
|
!this.attachFlowBatch.push(
|
|
162
186
|
message,
|
|
187
|
+
this.isContextReentrant(),
|
|
163
188
|
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
164
189
|
)
|
|
165
190
|
) {
|
|
166
191
|
// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
|
|
167
192
|
// when queue is not empty.
|
|
168
193
|
// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
|
|
169
|
-
this.flushInternal(this.attachFlowBatch
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
message,
|
|
173
|
-
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
174
|
-
)
|
|
175
|
-
) {
|
|
176
|
-
throw new GenericError("BatchTooLarge", /* error */ undefined, {
|
|
177
|
-
opSize: message.contents?.length ?? 0,
|
|
178
|
-
batchSize: this.attachFlowBatch.contentSizeInBytes,
|
|
179
|
-
count: this.attachFlowBatch.length,
|
|
180
|
-
limit: this.attachFlowBatch.options.hardLimit,
|
|
181
|
-
});
|
|
182
|
-
}
|
|
194
|
+
this.flushInternal(this.attachFlowBatch);
|
|
195
|
+
|
|
196
|
+
this.addMessageToBatchManager(this.attachFlowBatch, message);
|
|
183
197
|
}
|
|
184
198
|
|
|
185
199
|
// If compression is enabled, we will always successfully receive
|
|
@@ -191,23 +205,122 @@ export class Outbox {
|
|
|
191
205
|
this.attachFlowBatch.contentSizeInBytes >=
|
|
192
206
|
this.params.config.compressionOptions.minimumBatchSizeInBytes
|
|
193
207
|
) {
|
|
194
|
-
this.flushInternal(this.attachFlowBatch
|
|
208
|
+
this.flushInternal(this.attachFlowBatch);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public submitBlobAttach(message: BatchMessage) {
|
|
213
|
+
this.maybeFlushPartialBatch();
|
|
214
|
+
|
|
215
|
+
this.addMessageToBatchManager(this.blobAttachBatch, message);
|
|
216
|
+
|
|
217
|
+
// If compression is enabled, we will always successfully receive
|
|
218
|
+
// blobAttach ops and compress then send them at the next JS turn, regardless
|
|
219
|
+
// of the overall size of the accumulated ops in the batch.
|
|
220
|
+
// However, it is more efficient to flush these ops faster, preferably
|
|
221
|
+
// after they reach a size which would benefit from compression.
|
|
222
|
+
if (
|
|
223
|
+
this.blobAttachBatch.contentSizeInBytes >=
|
|
224
|
+
this.params.config.compressionOptions.minimumBatchSizeInBytes
|
|
225
|
+
) {
|
|
226
|
+
this.flushInternal(this.blobAttachBatch);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
|
|
231
|
+
if (
|
|
232
|
+
!batchManager.push(
|
|
233
|
+
message,
|
|
234
|
+
this.isContextReentrant(),
|
|
235
|
+
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
236
|
+
)
|
|
237
|
+
) {
|
|
238
|
+
throw new GenericError("BatchTooLarge", /* error */ undefined, {
|
|
239
|
+
opSize: message.contents?.length ?? 0,
|
|
240
|
+
batchSize: batchManager.contentSizeInBytes,
|
|
241
|
+
count: batchManager.length,
|
|
242
|
+
limit: batchManager.options.hardLimit,
|
|
243
|
+
});
|
|
195
244
|
}
|
|
196
245
|
}
|
|
197
246
|
|
|
198
247
|
public flush() {
|
|
199
|
-
|
|
200
|
-
|
|
248
|
+
if (this.isContextReentrant()) {
|
|
249
|
+
const error = new UsageError("Flushing is not supported inside DDS event handlers");
|
|
250
|
+
this.params.closeContainer(error);
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
this.flushAll();
|
|
201
255
|
}
|
|
202
256
|
|
|
203
|
-
private
|
|
204
|
-
|
|
257
|
+
private flushAll() {
|
|
258
|
+
this.flushInternal(this.attachFlowBatch);
|
|
259
|
+
this.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);
|
|
260
|
+
this.flushInternal(this.mainBatch);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private flushInternal(batchManager: BatchManager, disableGroupedBatching: boolean = false) {
|
|
264
|
+
if (batchManager.empty) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const rawBatch = batchManager.popBatch();
|
|
269
|
+
if (rawBatch.hasReentrantOps === true && this.params.config.enableGroupedBatching) {
|
|
270
|
+
assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
|
|
271
|
+
// If a batch contains reentrant ops (ops created as a result from processing another op)
|
|
272
|
+
// it needs to be rebased so that we can ensure consistent reference sequence numbers
|
|
273
|
+
// and eventual consistency at the DDS level.
|
|
274
|
+
this.rebase(rawBatch, batchManager);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const processedBatch = this.compressBatch(rawBatch, disableGroupedBatching);
|
|
205
279
|
this.sendBatch(processedBatch);
|
|
206
280
|
|
|
207
281
|
this.persistBatch(rawBatch.content);
|
|
208
282
|
}
|
|
209
283
|
|
|
210
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Rebases a batch. All the ops in the batch are resubmitted to the runtime and
|
|
286
|
+
* they will end up back in the same batch manager they were flushed from and subsequently flushed.
|
|
287
|
+
*
|
|
288
|
+
* @param rawBatch - the batch to be rebased
|
|
289
|
+
*/
|
|
290
|
+
private rebase(rawBatch: IBatch, batchManager: BatchManager) {
|
|
291
|
+
assert(!this.rebasing, 0x6fb /* Reentrancy */);
|
|
292
|
+
|
|
293
|
+
this.rebasing = true;
|
|
294
|
+
for (const message of rawBatch.content) {
|
|
295
|
+
this.params.reSubmit({
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
297
|
+
content: message.contents!,
|
|
298
|
+
localOpMetadata: message.localOpMetadata,
|
|
299
|
+
opMetadata: message.metadata,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (this.batchRebasesToReport > 0) {
|
|
304
|
+
this.mc.logger.sendTelemetryEvent(
|
|
305
|
+
{
|
|
306
|
+
eventName: "BatchRebase",
|
|
307
|
+
length: rawBatch.content.length,
|
|
308
|
+
referenceSequenceNumber: rawBatch.referenceSequenceNumber,
|
|
309
|
+
},
|
|
310
|
+
new UsageError("BatchRebase"),
|
|
311
|
+
);
|
|
312
|
+
this.batchRebasesToReport--;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
this.flushInternal(batchManager);
|
|
316
|
+
this.rebasing = false;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
private isContextReentrant(): boolean {
|
|
320
|
+
return this.params.opReentrancy() && !this.rebasing;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private compressBatch(batch: IBatch, disableGroupedBatching: boolean): IBatch {
|
|
211
324
|
if (
|
|
212
325
|
batch.content.length === 0 ||
|
|
213
326
|
this.params.config.compressionOptions === undefined ||
|
|
@@ -216,11 +329,11 @@ export class Outbox {
|
|
|
216
329
|
this.params.containerContext.submitBatchFn === undefined
|
|
217
330
|
) {
|
|
218
331
|
// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
|
|
219
|
-
return this.params.groupingManager.groupBatch(batch);
|
|
332
|
+
return disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch);
|
|
220
333
|
}
|
|
221
334
|
|
|
222
335
|
const compressedBatch = this.params.compressor.compressBatch(
|
|
223
|
-
this.params.groupingManager.groupBatch(batch),
|
|
336
|
+
disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch),
|
|
224
337
|
);
|
|
225
338
|
|
|
226
339
|
if (this.params.splitter.isBatchChunkingEnabled) {
|
|
@@ -322,6 +435,7 @@ export class Outbox {
|
|
|
322
435
|
return {
|
|
323
436
|
mainBatch: this.mainBatch.checkpoint(),
|
|
324
437
|
attachFlowBatch: this.attachFlowBatch.checkpoint(),
|
|
438
|
+
blobAttachBatch: this.blobAttachBatch.checkpoint(),
|
|
325
439
|
};
|
|
326
440
|
}
|
|
327
441
|
}
|
|
@@ -120,7 +120,11 @@ export function unpackRuntimeMessage(message: ISequencedDocumentMessage): boolea
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// legacy op format?
|
|
123
|
-
if
|
|
123
|
+
// TODO: Unsure if this is a real format we should be concerned with. There doesn't appear to be anything prepared to handle the address member.
|
|
124
|
+
if (
|
|
125
|
+
(message.contents as { address?: unknown }).address !== undefined &&
|
|
126
|
+
(message.contents as { type?: unknown }).type === undefined
|
|
127
|
+
) {
|
|
124
128
|
message.type = ContainerMessageType.FluidDataStoreOp;
|
|
125
129
|
} else {
|
|
126
130
|
// new format
|
package/src/packageVersion.ts
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { IDisposable } from "@fluidframework/common-definitions";
|
|
7
|
-
import { assert
|
|
7
|
+
import { assert } from "@fluidframework/common-utils";
|
|
8
8
|
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
9
9
|
import { DataProcessingError } from "@fluidframework/container-utils";
|
|
10
|
+
import { Lazy } from "@fluidframework/core-utils";
|
|
10
11
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
11
12
|
import Deque from "double-ended-queue";
|
|
12
13
|
import { ContainerMessageType } from "./containerRuntime";
|
|
13
14
|
import { pkgVersion } from "./packageVersion";
|
|
15
|
+
import { IBatchMetadata } from "./metadata";
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* ! TODO: Remove this interface in "2.0.0-internal.7.0.0" once we only read IPendingMessageNew
|
|
@@ -50,17 +52,19 @@ export interface IPendingLocalState {
|
|
|
50
52
|
pendingStates: IPendingState[];
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
export interface IPendingBatchMessage {
|
|
56
|
+
content: string;
|
|
57
|
+
localOpMetadata: unknown;
|
|
58
|
+
opMetadata: Record<string, unknown> | undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
export interface IRuntimeStateHandler {
|
|
54
62
|
connected(): boolean;
|
|
55
63
|
clientId(): string | undefined;
|
|
56
64
|
close(error?: ICriticalContainerError): void;
|
|
57
65
|
applyStashedOp(content: string): Promise<unknown>;
|
|
58
|
-
reSubmit(
|
|
59
|
-
|
|
60
|
-
localOpMetadata: unknown,
|
|
61
|
-
opMetadata: Record<string, unknown> | undefined,
|
|
62
|
-
): void;
|
|
63
|
-
orderSequentially(callback: () => void): void;
|
|
66
|
+
reSubmit(message: IPendingBatchMessage): void;
|
|
67
|
+
reSubmitBatch(batch: IPendingBatchMessage[]): void;
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
/**
|
|
@@ -207,9 +211,13 @@ export class PendingStateManager implements IDisposable {
|
|
|
207
211
|
}
|
|
208
212
|
}
|
|
209
213
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
214
|
+
try {
|
|
215
|
+
// applyStashedOp will cause the DDS to behave as if it has sent the op but not actually send it
|
|
216
|
+
const localOpMetadata = await this.stateHandler.applyStashedOp(nextMessage.content);
|
|
217
|
+
nextMessage.localOpMetadata = localOpMetadata;
|
|
218
|
+
} catch (error) {
|
|
219
|
+
throw DataProcessingError.wrapIfUnrecognized(error, "applyStashedOp", nextMessage);
|
|
220
|
+
}
|
|
213
221
|
|
|
214
222
|
// then we push onto pendingMessages which will cause PendingStateManager to resubmit when we connect
|
|
215
223
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
@@ -262,7 +270,7 @@ export class PendingStateManager implements IDisposable {
|
|
|
262
270
|
*/
|
|
263
271
|
private maybeProcessBatchBegin(message: ISequencedDocumentMessage) {
|
|
264
272
|
// This message is the first in a batch if the "batch" property on the metadata is set to true
|
|
265
|
-
if (message.metadata?.batch) {
|
|
273
|
+
if ((message.metadata as IBatchMetadata | undefined)?.batch) {
|
|
266
274
|
// We should not already be processing a batch and there should be no pending batch begin message.
|
|
267
275
|
assert(
|
|
268
276
|
!this.isProcessingBatch && this.pendingBatchBeginMessage === undefined,
|
|
@@ -290,10 +298,12 @@ export class PendingStateManager implements IDisposable {
|
|
|
290
298
|
0x16d /* "There is no pending batch begin message" */,
|
|
291
299
|
);
|
|
292
300
|
|
|
293
|
-
const batchEndMetadata = message.metadata?.batch;
|
|
301
|
+
const batchEndMetadata = (message.metadata as IBatchMetadata | undefined)?.batch;
|
|
294
302
|
if (this.pendingMessages.isEmpty() || batchEndMetadata === false) {
|
|
295
303
|
// Get the batch begin metadata from the first message in the batch.
|
|
296
|
-
const batchBeginMetadata =
|
|
304
|
+
const batchBeginMetadata = (
|
|
305
|
+
this.pendingBatchBeginMessage.metadata as IBatchMetadata | undefined
|
|
306
|
+
)?.batch;
|
|
297
307
|
|
|
298
308
|
// There could be just a single message in the batch. If so, it should not have any batch metadata. If there
|
|
299
309
|
// are multiple messages in the batch, verify that we got the correct batch begin and end metadata.
|
|
@@ -311,7 +321,10 @@ export class PendingStateManager implements IDisposable {
|
|
|
311
321
|
message,
|
|
312
322
|
{
|
|
313
323
|
runtimeVersion: pkgVersion,
|
|
314
|
-
batchClientId:
|
|
324
|
+
batchClientId:
|
|
325
|
+
this.pendingBatchBeginMessage.clientId === null
|
|
326
|
+
? "null"
|
|
327
|
+
: this.pendingBatchBeginMessage.clientId,
|
|
315
328
|
clientId: this.stateHandler.clientId(),
|
|
316
329
|
hasBatchStart: batchBeginMetadata === true,
|
|
317
330
|
hasBatchEnd: batchEndMetadata === false,
|
|
@@ -379,35 +392,37 @@ export class PendingStateManager implements IDisposable {
|
|
|
379
392
|
0x554 /* Last pending message cannot be a batch begin */,
|
|
380
393
|
);
|
|
381
394
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
assert(pendingMessagesCount > 0, 0x555 /* No batch end found */);
|
|
395
|
-
|
|
396
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
397
|
-
pendingMessage = this.pendingMessages.shift()!;
|
|
398
|
-
pendingMessagesCount--;
|
|
399
|
-
assert(
|
|
400
|
-
pendingMessage.opMetadata?.batch !== true,
|
|
401
|
-
0x556 /* Batch start needs a corresponding batch end */,
|
|
402
|
-
);
|
|
395
|
+
const batch: IPendingBatchMessage[] = [];
|
|
396
|
+
|
|
397
|
+
// check is >= because batch end may be last pending message
|
|
398
|
+
while (pendingMessagesCount >= 0) {
|
|
399
|
+
batch.push({
|
|
400
|
+
content: pendingMessage.content,
|
|
401
|
+
localOpMetadata: pendingMessage.localOpMetadata,
|
|
402
|
+
opMetadata: pendingMessage.opMetadata,
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
if (pendingMessage.opMetadata?.batch === false) {
|
|
406
|
+
break;
|
|
403
407
|
}
|
|
404
|
-
|
|
408
|
+
assert(pendingMessagesCount > 0, 0x555 /* No batch end found */);
|
|
409
|
+
|
|
410
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
411
|
+
pendingMessage = this.pendingMessages.shift()!;
|
|
412
|
+
pendingMessagesCount--;
|
|
413
|
+
assert(
|
|
414
|
+
pendingMessage.opMetadata?.batch !== true,
|
|
415
|
+
0x556 /* Batch start needs a corresponding batch end */,
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
this.stateHandler.reSubmitBatch(batch);
|
|
405
420
|
} else {
|
|
406
|
-
this.stateHandler.reSubmit(
|
|
407
|
-
pendingMessage.content,
|
|
408
|
-
pendingMessage.localOpMetadata,
|
|
409
|
-
pendingMessage.opMetadata,
|
|
410
|
-
);
|
|
421
|
+
this.stateHandler.reSubmit({
|
|
422
|
+
content: pendingMessage.content,
|
|
423
|
+
localOpMetadata: pendingMessage.localOpMetadata,
|
|
424
|
+
opMetadata: pendingMessage.opMetadata,
|
|
425
|
+
});
|
|
411
426
|
}
|
|
412
427
|
}
|
|
413
428
|
}
|
package/src/scheduleManager.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "@fluidframework/container-utils";
|
|
16
16
|
import { DeltaScheduler } from "./deltaScheduler";
|
|
17
17
|
import { pkgVersion } from "./packageVersion";
|
|
18
|
+
import { IBatchMetadata } from "./metadata";
|
|
18
19
|
|
|
19
20
|
type IRuntimeMessageMetadata =
|
|
20
21
|
| undefined
|
|
@@ -61,7 +62,9 @@ export class ScheduleManager {
|
|
|
61
62
|
this.deltaScheduler.batchBegin(message);
|
|
62
63
|
|
|
63
64
|
const batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;
|
|
64
|
-
this
|
|
65
|
+
// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
67
|
+
this.batchClientId = batch ? (message.clientId as string) : undefined;
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
|
|
@@ -127,7 +130,9 @@ class ScheduleManagerCore {
|
|
|
127
130
|
|
|
128
131
|
// Set the batch flag to false on the last message to indicate the end of the send batch
|
|
129
132
|
const lastMessage = messages[messages.length - 1];
|
|
130
|
-
|
|
133
|
+
// TODO: It's not clear if this shallow clone is required, as opposed to just setting "batch" to false.
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
135
|
+
lastMessage.metadata = { ...(lastMessage.metadata as any), batch: false };
|
|
131
136
|
});
|
|
132
137
|
|
|
133
138
|
// Listen for updates and peek at the inbound
|
|
@@ -185,7 +190,7 @@ class ScheduleManagerCore {
|
|
|
185
190
|
{
|
|
186
191
|
type: message.type,
|
|
187
192
|
contentType: typeof message.contents,
|
|
188
|
-
batch: message.metadata?.batch,
|
|
193
|
+
batch: (message.metadata as IBatchMetadata | undefined)?.batch,
|
|
189
194
|
compression: message.compression,
|
|
190
195
|
pauseSeqNum: this.pauseSequenceNumber,
|
|
191
196
|
},
|
|
@@ -263,7 +268,8 @@ class ScheduleManagerCore {
|
|
|
263
268
|
message,
|
|
264
269
|
{
|
|
265
270
|
runtimeVersion: pkgVersion,
|
|
266
|
-
batchClientId:
|
|
271
|
+
batchClientId:
|
|
272
|
+
this.currentBatchClientId === null ? "null" : this.currentBatchClientId,
|
|
267
273
|
pauseSequenceNumber: this.pauseSequenceNumber,
|
|
268
274
|
localBatch: this.currentBatchClientId === this.getClientId(),
|
|
269
275
|
messageType: message.type,
|
|
@@ -297,7 +303,8 @@ class ScheduleManagerCore {
|
|
|
297
303
|
) {
|
|
298
304
|
throw new DataCorruptionError("OpBatchIncomplete", {
|
|
299
305
|
runtimeVersion: pkgVersion,
|
|
300
|
-
batchClientId:
|
|
306
|
+
batchClientId:
|
|
307
|
+
this.currentBatchClientId === null ? "null" : this.currentBatchClientId,
|
|
301
308
|
pauseSequenceNumber: this.pauseSequenceNumber,
|
|
302
309
|
localBatch: this.currentBatchClientId === this.getClientId(),
|
|
303
310
|
localMessage: message.clientId === this.getClientId(),
|
|
@@ -321,7 +328,9 @@ class ScheduleManagerCore {
|
|
|
321
328
|
0x29f /* "we should be processing ops when there is no active batch" */,
|
|
322
329
|
);
|
|
323
330
|
this.pauseSequenceNumber = message.sequenceNumber;
|
|
324
|
-
this
|
|
331
|
+
// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
|
|
332
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
333
|
+
this.currentBatchClientId = message.clientId as string;
|
|
325
334
|
// Start of the batch
|
|
326
335
|
// Only pause processing if queue has no other ops!
|
|
327
336
|
// If there are any other ops in the queue, processing will be stopped when they are processed!
|
package/src/summary/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ITelemetryErrorEvent } from "@fluidframework/
|
|
6
|
+
import { ITelemetryErrorEvent } from "@fluidframework/core-interfaces";
|
|
7
7
|
import {
|
|
8
8
|
ISummarizerNode,
|
|
9
9
|
ISummarizerNodeConfig,
|
|
@@ -243,9 +243,9 @@ export class SummarizerNode implements IRootSummarizerNode {
|
|
|
243
243
|
private wasSummarizeMissed(parentSkipRecursion: boolean): boolean {
|
|
244
244
|
assert(
|
|
245
245
|
this.wipSummaryLogger !== undefined,
|
|
246
|
-
|
|
246
|
+
0x6fc /* wipSummaryLogger should have been set in startSummary or ctor */,
|
|
247
247
|
);
|
|
248
|
-
assert(this.wipReferenceSequenceNumber !== undefined,
|
|
248
|
+
assert(this.wipReferenceSequenceNumber !== undefined, 0x6fd /* Not tracking a summary */);
|
|
249
249
|
|
|
250
250
|
// If the parent node skipped recursion, it did not call summarize on this node. So, summarize was not missed
|
|
251
251
|
// but was intentionally not called.
|
|
@@ -335,7 +335,7 @@ export class SummarizerNode implements IRootSummarizerNode {
|
|
|
335
335
|
|
|
336
336
|
// If localPathsToUse is undefined, it means summarize didn't run for this node and in that case the validate
|
|
337
337
|
// step should have failed.
|
|
338
|
-
assert(localPathsToUse !== undefined,
|
|
338
|
+
assert(localPathsToUse !== undefined, 0x6fe /* summarize didn't run for node */);
|
|
339
339
|
const summary = new SummaryNode({
|
|
340
340
|
...localPathsToUse,
|
|
341
341
|
referenceSequenceNumber: this.wipReferenceSequenceNumber,
|
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
LoggingError,
|
|
9
9
|
TelemetryDataTag,
|
|
10
10
|
} from "@fluidframework/telemetry-utils";
|
|
11
|
-
import { assert
|
|
11
|
+
import { assert } from "@fluidframework/common-utils";
|
|
12
|
+
import { LazyPromise } from "@fluidframework/core-utils";
|
|
12
13
|
import { ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
13
14
|
import {
|
|
14
15
|
CreateChildSummarizerNodeParam,
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IEvent, IEventProvider
|
|
6
|
+
import { IEvent, IEventProvider } from "@fluidframework/common-definitions";
|
|
7
|
+
import { ITelemetryProperties } from "@fluidframework/core-interfaces";
|
|
7
8
|
import { ITelemetryLoggerExt, ITelemetryLoggerPropertyBag } from "@fluidframework/telemetry-utils";
|
|
8
9
|
import { ContainerWarning, IDeltaManager } from "@fluidframework/container-definitions";
|
|
9
10
|
import {
|