@fluidframework/container-runtime 2.0.0-internal.7.2.1 → 2.0.0-internal.7.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 +4 -0
- package/README.md +1 -2
- package/dist/batchTracker.d.ts +1 -0
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +5 -11
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +26 -32
- package/dist/containerRuntime.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +4 -1
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +7 -2
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +8 -3
- 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 +20 -8
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +3 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/messageTypes.d.ts +3 -6
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/metadata.d.ts +6 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +10 -2
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +33 -4
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +23 -1
- 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 +0 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +1 -11
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -0
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/batchTracker.d.ts +1 -0
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +5 -11
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +26 -32
- package/lib/containerRuntime.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +5 -2
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +7 -2
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +7 -2
- 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 +21 -9
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/messageTypes.d.ts +3 -6
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/metadata.d.ts +6 -0
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +10 -2
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +33 -4
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +23 -1
- 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 +0 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +1 -11
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -0
- package/lib/scheduleManager.d.ts.map +1 -1
- package/package.json +25 -25
- package/src/connectionTelemetry.ts +1 -1
- package/src/containerRuntime.ts +41 -39
- package/src/gc/gcConfigs.ts +8 -2
- package/src/gc/gcDefinitions.ts +10 -2
- package/src/gc/gcTelemetry.ts +28 -17
- package/src/gc/index.ts +2 -0
- package/src/messageTypes.ts +2 -7
- package/src/metadata.ts +7 -0
- package/src/opLifecycle/opGroupingManager.ts +47 -3
- package/src/opLifecycle/outbox.ts +38 -2
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +2 -13
package/src/messageTypes.ts
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
IEnvelope,
|
|
9
9
|
InboundAttachMessage,
|
|
10
10
|
IAttachMessage,
|
|
11
|
-
IdCreationRangeWithStashedState,
|
|
12
11
|
IdCreationRange,
|
|
13
12
|
} from "@fluidframework/runtime-definitions";
|
|
14
13
|
import { IDataStoreAliasMessage } from "./dataStore";
|
|
@@ -116,13 +115,9 @@ export type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<
|
|
|
116
115
|
ContainerMessageType.Alias,
|
|
117
116
|
IDataStoreAliasMessage
|
|
118
117
|
>;
|
|
119
|
-
export type LocalContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
120
|
-
ContainerMessageType.IdAllocation,
|
|
121
|
-
IdCreationRangeWithStashedState
|
|
122
|
-
>;
|
|
123
118
|
export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
124
119
|
ContainerMessageType.IdAllocation,
|
|
125
|
-
IdCreationRange
|
|
120
|
+
IdCreationRange
|
|
126
121
|
>;
|
|
127
122
|
|
|
128
123
|
/**
|
|
@@ -163,7 +158,7 @@ export type LocalContainerRuntimeMessage =
|
|
|
163
158
|
| ContainerRuntimeBlobAttachMessage
|
|
164
159
|
| ContainerRuntimeRejoinMessage
|
|
165
160
|
| ContainerRuntimeAliasMessage
|
|
166
|
-
|
|
|
161
|
+
| ContainerRuntimeIdAllocationMessage
|
|
167
162
|
// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type
|
|
168
163
|
| UnknownContainerRuntimeMessage;
|
|
169
164
|
|
package/src/metadata.ts
CHANGED
|
@@ -17,3 +17,10 @@ export interface IBlobMetadata {
|
|
|
17
17
|
blobId?: string;
|
|
18
18
|
localId?: string;
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The IdCompressor needs to know if this is a replayed savedOp as those need to be skipped in stashed ops scenarios.
|
|
23
|
+
*/
|
|
24
|
+
export interface IIdAllocationMetadata {
|
|
25
|
+
savedOp?: boolean;
|
|
26
|
+
}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert } from "@fluidframework/core-utils";
|
|
7
7
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
8
|
+
import { createChildLogger } from "@fluidframework/telemetry-utils";
|
|
9
|
+
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
10
|
import { ContainerMessageType } from "../messageTypes";
|
|
9
11
|
import { IBatch } from "./definitions";
|
|
10
12
|
|
|
@@ -26,16 +28,38 @@ function isGroupContents(opContents: any): opContents is IGroupedBatchMessageCon
|
|
|
26
28
|
return opContents?.type === OpGroupingManager.groupedBatchOp;
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
export interface OpGroupingManagerConfig {
|
|
32
|
+
readonly groupedBatchingEnabled: boolean;
|
|
33
|
+
readonly opCountThreshold: number;
|
|
34
|
+
readonly reentrantBatchGroupingEnabled: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
29
37
|
export class OpGroupingManager {
|
|
30
38
|
static readonly groupedBatchOp = "groupedBatch";
|
|
39
|
+
private readonly logger;
|
|
31
40
|
|
|
32
|
-
constructor(
|
|
41
|
+
constructor(
|
|
42
|
+
private readonly config: OpGroupingManagerConfig,
|
|
43
|
+
logger: ITelemetryBaseLogger,
|
|
44
|
+
) {
|
|
45
|
+
this.logger = createChildLogger({ logger, namespace: "OpGroupingManager" });
|
|
46
|
+
}
|
|
33
47
|
|
|
34
48
|
public groupBatch(batch: IBatch): IBatch {
|
|
35
|
-
if (
|
|
49
|
+
if (!this.shouldGroup(batch)) {
|
|
36
50
|
return batch;
|
|
37
51
|
}
|
|
38
52
|
|
|
53
|
+
if (batch.content.length >= 1000) {
|
|
54
|
+
this.logger.sendTelemetryEvent({
|
|
55
|
+
eventName: "GroupLargeBatch",
|
|
56
|
+
length: batch.content.length,
|
|
57
|
+
threshold: this.config.opCountThreshold,
|
|
58
|
+
reentrant: batch.hasReentrantOps,
|
|
59
|
+
referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
39
63
|
for (const message of batch.content) {
|
|
40
64
|
if (message.metadata) {
|
|
41
65
|
const keys = Object.keys(message.metadata);
|
|
@@ -72,12 +96,21 @@ export class OpGroupingManager {
|
|
|
72
96
|
}
|
|
73
97
|
|
|
74
98
|
public ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {
|
|
99
|
+
let fakeCsn = 1;
|
|
75
100
|
if (!isGroupContents(op.contents)) {
|
|
101
|
+
// Align the worlds of what clientSequenceNumber represents when grouped batching is enabled
|
|
102
|
+
if (this.config.groupedBatchingEnabled) {
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
...op,
|
|
106
|
+
clientSequenceNumber: fakeCsn,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
}
|
|
76
110
|
return [op];
|
|
77
111
|
}
|
|
78
112
|
|
|
79
113
|
const messages = op.contents.contents;
|
|
80
|
-
let fakeCsn = 1;
|
|
81
114
|
return messages.map((subMessage) => ({
|
|
82
115
|
...op,
|
|
83
116
|
clientSequenceNumber: fakeCsn++,
|
|
@@ -86,4 +119,15 @@ export class OpGroupingManager {
|
|
|
86
119
|
compression: subMessage.compression,
|
|
87
120
|
}));
|
|
88
121
|
}
|
|
122
|
+
|
|
123
|
+
public shouldGroup(batch: IBatch): boolean {
|
|
124
|
+
return (
|
|
125
|
+
// Grouped batching must be enabled
|
|
126
|
+
this.config.groupedBatchingEnabled &&
|
|
127
|
+
// The number of ops in the batch must surpass the configured threshold
|
|
128
|
+
batch.content.length >= this.config.opCountThreshold &&
|
|
129
|
+
// Support for reentrant batches must be explicitly enabled
|
|
130
|
+
(this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
89
133
|
}
|
|
@@ -30,7 +30,6 @@ export interface IOutboxConfig {
|
|
|
30
30
|
// The maximum size of a batch that we can send over the wire.
|
|
31
31
|
readonly maxBatchSizeInBytes: number;
|
|
32
32
|
readonly disablePartialFlush: boolean;
|
|
33
|
-
readonly enableGroupedBatching: boolean;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
export interface IOutboxParameters {
|
|
@@ -90,6 +89,7 @@ export class Outbox {
|
|
|
90
89
|
private readonly attachFlowBatch: BatchManager;
|
|
91
90
|
private readonly mainBatch: BatchManager;
|
|
92
91
|
private readonly blobAttachBatch: BatchManager;
|
|
92
|
+
private readonly idAllocationBatch: BatchManager;
|
|
93
93
|
private readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;
|
|
94
94
|
private batchRebasesToReport = 5;
|
|
95
95
|
private rebasing = false;
|
|
@@ -115,6 +115,7 @@ export class Outbox {
|
|
|
115
115
|
this.attachFlowBatch = new BatchManager({ hardLimit, softLimit });
|
|
116
116
|
this.mainBatch = new BatchManager({ hardLimit });
|
|
117
117
|
this.blobAttachBatch = new BatchManager({ hardLimit });
|
|
118
|
+
this.idAllocationBatch = new BatchManager({ hardLimit });
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
public get messageCount(): number {
|
|
@@ -231,6 +232,37 @@ export class Outbox {
|
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
|
|
235
|
+
public submitIdAllocation(message: BatchMessage) {
|
|
236
|
+
this.maybeFlushPartialBatch();
|
|
237
|
+
|
|
238
|
+
if (
|
|
239
|
+
!this.idAllocationBatch.push(
|
|
240
|
+
message,
|
|
241
|
+
this.isContextReentrant(),
|
|
242
|
+
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
243
|
+
)
|
|
244
|
+
) {
|
|
245
|
+
// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
|
|
246
|
+
// when queue is not empty.
|
|
247
|
+
// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
|
|
248
|
+
this.flushInternal(this.idAllocationBatch);
|
|
249
|
+
|
|
250
|
+
this.addMessageToBatchManager(this.idAllocationBatch, message);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// If compression is enabled, we will always successfully receive
|
|
254
|
+
// attach ops and compress then send them at the next JS turn, regardless
|
|
255
|
+
// of the overall size of the accumulated ops in the batch.
|
|
256
|
+
// However, it is more efficient to flush these ops faster, preferably
|
|
257
|
+
// after they reach a size which would benefit from compression.
|
|
258
|
+
if (
|
|
259
|
+
this.idAllocationBatch.contentSizeInBytes >=
|
|
260
|
+
this.params.config.compressionOptions.minimumBatchSizeInBytes
|
|
261
|
+
) {
|
|
262
|
+
this.flushInternal(this.idAllocationBatch);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
234
266
|
private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
|
|
235
267
|
if (
|
|
236
268
|
!batchManager.push(
|
|
@@ -259,6 +291,7 @@ export class Outbox {
|
|
|
259
291
|
}
|
|
260
292
|
|
|
261
293
|
private flushAll() {
|
|
294
|
+
this.flushInternal(this.idAllocationBatch);
|
|
262
295
|
this.flushInternal(this.attachFlowBatch);
|
|
263
296
|
this.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);
|
|
264
297
|
this.flushInternal(this.mainBatch);
|
|
@@ -270,7 +303,10 @@ export class Outbox {
|
|
|
270
303
|
}
|
|
271
304
|
|
|
272
305
|
const rawBatch = batchManager.popBatch();
|
|
273
|
-
if (
|
|
306
|
+
if (
|
|
307
|
+
rawBatch.hasReentrantOps === true &&
|
|
308
|
+
this.params.groupingManager.shouldGroup(rawBatch)
|
|
309
|
+
) {
|
|
274
310
|
assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
|
|
275
311
|
// If a batch contains reentrant ops (ops created as a result from processing another op)
|
|
276
312
|
// it needs to be rebased so that we can ensure consistent reference sequence numbers
|
package/src/packageVersion.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
|
11
11
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
12
12
|
import { DataProcessingError, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { InboundSequencedContainerRuntimeMessage } from "./messageTypes";
|
|
15
15
|
import { pkgVersion } from "./packageVersion";
|
|
16
16
|
import { IBatchMetadata } from "./metadata";
|
|
17
17
|
|
|
@@ -21,7 +21,6 @@ import { IBatchMetadata } from "./metadata";
|
|
|
21
21
|
*/
|
|
22
22
|
export interface IPendingMessage {
|
|
23
23
|
type: "message";
|
|
24
|
-
clientSequenceNumber: number;
|
|
25
24
|
referenceSequenceNumber: number;
|
|
26
25
|
content: string;
|
|
27
26
|
localOpMetadata: unknown;
|
|
@@ -128,18 +127,9 @@ export class PendingStateManager implements IDisposable {
|
|
|
128
127
|
return {
|
|
129
128
|
pendingStates: [...this.savedOps, ...this.pendingMessages.toArray()].map(
|
|
130
129
|
(message) => {
|
|
131
|
-
let content = message.content;
|
|
132
|
-
const parsedContent = JSON.parse(content);
|
|
133
|
-
// IdAllocations need their localOpMetadata stashed in the contents
|
|
134
|
-
// of the op to correctly resume the session when processing stashed ops
|
|
135
|
-
if (parsedContent.type === ContainerMessageType.IdAllocation) {
|
|
136
|
-
parsedContent.contents.stashedState = message.localOpMetadata;
|
|
137
|
-
content = JSON.stringify(parsedContent);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
130
|
// delete localOpMetadata since it may not be serializable
|
|
141
131
|
// and will be regenerated by applyStashedOp()
|
|
142
|
-
return { ...message,
|
|
132
|
+
return { ...message, localOpMetadata: undefined };
|
|
143
133
|
},
|
|
144
134
|
),
|
|
145
135
|
};
|
|
@@ -176,7 +166,6 @@ export class PendingStateManager implements IDisposable {
|
|
|
176
166
|
) {
|
|
177
167
|
const pendingMessage: IPendingMessage = {
|
|
178
168
|
type: "message",
|
|
179
|
-
clientSequenceNumber: -1, // dummy value (not to be used anywhere)
|
|
180
169
|
referenceSequenceNumber,
|
|
181
170
|
content,
|
|
182
171
|
localOpMetadata,
|