@fluidframework/container-runtime 2.0.0-internal.1.2.0.93071 → 2.0.0-internal.1.2.1
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/dist/batchManager.d.ts +7 -2
- package/dist/batchManager.d.ts.map +1 -1
- package/dist/batchManager.js +19 -17
- package/dist/batchManager.js.map +1 -1
- package/dist/batchTracker.d.ts +1 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +1 -2
- package/dist/batchTracker.js.map +1 -1
- package/dist/containerRuntime.d.ts +10 -5
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +87 -63
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +14 -5
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +19 -11
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +6 -2
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +7 -9
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaScheduler.d.ts +6 -4
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +6 -4
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/garbageCollection.d.ts +41 -12
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +176 -98
- package/dist/garbageCollection.js.map +1 -1
- package/dist/gcSweepReadyUsageDetection.d.ts +53 -0
- package/dist/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/dist/gcSweepReadyUsageDetection.js +135 -0
- package/dist/gcSweepReadyUsageDetection.js.map +1 -0
- package/dist/orderedClientElection.d.ts +28 -10
- package/dist/orderedClientElection.d.ts.map +1 -1
- package/dist/orderedClientElection.js +14 -4
- package/dist/orderedClientElection.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +4 -2
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +6 -3
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +21 -13
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summarizerTypes.d.ts +13 -6
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryCollection.d.ts.map +1 -1
- package/dist/summaryCollection.js +3 -6
- package/dist/summaryCollection.js.map +1 -1
- package/dist/summaryManager.d.ts +2 -2
- package/dist/summaryManager.js +2 -2
- package/dist/summaryManager.js.map +1 -1
- package/lib/batchManager.d.ts +7 -2
- package/lib/batchManager.d.ts.map +1 -1
- package/lib/batchManager.js +19 -17
- package/lib/batchManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +1 -2
- package/lib/batchTracker.js.map +1 -1
- package/lib/containerRuntime.d.ts +10 -5
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +87 -63
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +14 -5
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +20 -12
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +6 -2
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +7 -9
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaScheduler.d.ts +6 -4
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +6 -4
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/garbageCollection.d.ts +41 -12
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +175 -97
- package/lib/garbageCollection.js.map +1 -1
- package/lib/gcSweepReadyUsageDetection.d.ts +53 -0
- package/lib/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/lib/gcSweepReadyUsageDetection.js +130 -0
- package/lib/gcSweepReadyUsageDetection.js.map +1 -0
- package/lib/orderedClientElection.d.ts +28 -10
- package/lib/orderedClientElection.d.ts.map +1 -1
- package/lib/orderedClientElection.js +14 -4
- package/lib/orderedClientElection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +4 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +6 -3
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +22 -14
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summarizerTypes.d.ts +13 -6
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryCollection.d.ts.map +1 -1
- package/lib/summaryCollection.js +3 -6
- package/lib/summaryCollection.js.map +1 -1
- package/lib/summaryManager.d.ts +2 -2
- package/lib/summaryManager.js +2 -2
- package/lib/summaryManager.js.map +1 -1
- package/package.json +19 -16
- package/src/batchManager.ts +22 -19
- package/src/batchTracker.ts +1 -2
- package/src/containerRuntime.ts +118 -80
- package/src/dataStoreContext.ts +20 -10
- package/src/dataStores.ts +7 -8
- package/src/deltaScheduler.ts +6 -4
- package/src/garbageCollection.ts +224 -134
- package/src/gcSweepReadyUsageDetection.ts +147 -0
- package/src/orderedClientElection.ts +31 -10
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +4 -2
- package/src/scheduleManager.ts +30 -10
- package/src/summarizerTypes.ts +14 -6
- package/src/summaryCollection.ts +3 -5
- package/src/summaryManager.ts +2 -2
package/lib/containerRuntime.js
CHANGED
|
@@ -101,9 +101,12 @@ export function isRuntimeMessage(message) {
|
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
103
|
* Unpacks runtime messages
|
|
104
|
-
*
|
|
104
|
+
*
|
|
105
|
+
* @remarks This API makes no promises regarding backward-compatability. This is internal API.
|
|
105
106
|
* @param message - message (as it observed in storage / service)
|
|
106
107
|
* @returns unpacked runtime message
|
|
108
|
+
*
|
|
109
|
+
* @internal
|
|
107
110
|
*/
|
|
108
111
|
export function unpackRuntimeMessage(message) {
|
|
109
112
|
if (message.type === MessageType.Operation) {
|
|
@@ -179,7 +182,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
179
182
|
signalTimestamp: 0,
|
|
180
183
|
trackingSignalSequenceNumber: undefined,
|
|
181
184
|
};
|
|
182
|
-
|
|
185
|
+
// Provide lower soft limit - we want to have some number of ops to get efficiency in compression & bandwidth usage,
|
|
186
|
+
// but at the same time we want to send these ops sooner, to reduce overall latency of processing a batch.
|
|
187
|
+
// So there is some ballance here, that depends on compression algorithm and its efficiency working with smaller
|
|
188
|
+
// payloads. That number represents final (compressed) bits (once compression is implemented).
|
|
189
|
+
this.pendingAttachBatch = new BatchManager(64 * 1024);
|
|
190
|
+
this.pendingBatch = new BatchManager();
|
|
183
191
|
this.summarizeOnDemand = (...args) => {
|
|
184
192
|
if (this.clientDetails.type === summarizerClientType) {
|
|
185
193
|
return this.summarizer.summarizeOnDemand(...args);
|
|
@@ -237,6 +245,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
237
245
|
getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
|
|
238
246
|
getLastSummaryTimestampMs: () => { var _a; return (_a = this.messageAtLastSummary) === null || _a === void 0 ? void 0 : _a.timestamp; },
|
|
239
247
|
readAndParseBlob: async (id) => readAndParse(this.storage, id),
|
|
248
|
+
getContainerDiagnosticId: () => this.context.id,
|
|
249
|
+
activeConnection: () => this.deltaManager.active,
|
|
240
250
|
});
|
|
241
251
|
const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
|
|
242
252
|
this.summarizerNode = createRootSummarizerNodeWithGC(ChildLogger.create(this.logger, "SummarizerNode"),
|
|
@@ -264,7 +274,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
264
274
|
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId, localId });
|
|
265
275
|
}
|
|
266
276
|
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs);
|
|
267
|
-
this.scheduleManager = new ScheduleManager(context.deltaManager, this, ChildLogger.create(this.logger, "ScheduleManager"));
|
|
277
|
+
this.scheduleManager = new ScheduleManager(context.deltaManager, this, () => this.clientId, ChildLogger.create(this.logger, "ScheduleManager"));
|
|
268
278
|
this.deltaSender = this.deltaManager;
|
|
269
279
|
this.pendingStateManager = new PendingStateManager({
|
|
270
280
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
@@ -500,6 +510,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
500
510
|
return (_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.electedClientId;
|
|
501
511
|
}
|
|
502
512
|
get disposed() { return this._disposed; }
|
|
513
|
+
get emptyBatch() {
|
|
514
|
+
return this.pendingBatch.empty && this.pendingAttachBatch.empty;
|
|
515
|
+
}
|
|
503
516
|
get summarizer() {
|
|
504
517
|
assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
|
|
505
518
|
return this._summarizer;
|
|
@@ -531,12 +544,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
531
544
|
if (this.runtimeOptions.summaryOptions.summarizerClientElection === true) {
|
|
532
545
|
return true;
|
|
533
546
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
else {
|
|
538
|
-
return false;
|
|
539
|
-
}
|
|
547
|
+
return this.summaryConfiguration.state !== "disabled"
|
|
548
|
+
? this.summaryConfiguration.summarizerClientElection === true
|
|
549
|
+
: false;
|
|
540
550
|
}
|
|
541
551
|
getMaxOpsSinceLastSummary() {
|
|
542
552
|
// back-compat: maxOpsSinceLastSummary was moved from ISummaryRuntimeOptions
|
|
@@ -544,12 +554,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
544
554
|
if (this.runtimeOptions.summaryOptions.maxOpsSinceLastSummary !== undefined) {
|
|
545
555
|
return this.runtimeOptions.summaryOptions.maxOpsSinceLastSummary;
|
|
546
556
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
else {
|
|
551
|
-
return 0;
|
|
552
|
-
}
|
|
557
|
+
return this.summaryConfiguration.state !== "disabled"
|
|
558
|
+
? this.summaryConfiguration.maxOpsSinceLastSummary
|
|
559
|
+
: 0;
|
|
553
560
|
}
|
|
554
561
|
getInitialSummarizerDelayMs() {
|
|
555
562
|
// back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
|
|
@@ -557,12 +564,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
557
564
|
if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
|
|
558
565
|
return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
|
|
559
566
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
else {
|
|
564
|
-
return 0;
|
|
565
|
-
}
|
|
567
|
+
return this.summaryConfiguration.state !== "disabled"
|
|
568
|
+
? this.summaryConfiguration.initialSummarizerDelayMs
|
|
569
|
+
: 0;
|
|
566
570
|
}
|
|
567
571
|
dispose(error) {
|
|
568
572
|
var _a;
|
|
@@ -636,16 +640,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
636
640
|
}
|
|
637
641
|
if (id === BlobManager.basePath && requestParser.isLeaf(2)) {
|
|
638
642
|
const blob = await this.blobManager.getBlob(requestParser.pathParts[1]);
|
|
639
|
-
|
|
640
|
-
|
|
643
|
+
return blob
|
|
644
|
+
? {
|
|
641
645
|
status: 200,
|
|
642
646
|
mimeType: "fluid/object",
|
|
643
647
|
value: blob,
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
else {
|
|
647
|
-
return create404Response(request);
|
|
648
|
-
}
|
|
648
|
+
} : create404Response(request);
|
|
649
649
|
}
|
|
650
650
|
else if (requestParser.pathParts.length > 0) {
|
|
651
651
|
const dataStore = await this.getDataStoreFromRequest(id, request);
|
|
@@ -851,7 +851,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
851
851
|
this._perfSignalData.trackingSignalSequenceNumber = undefined;
|
|
852
852
|
}
|
|
853
853
|
else {
|
|
854
|
-
assert(this.attachState === AttachState.Attached,
|
|
854
|
+
assert(this.attachState === AttachState.Attached, 0x3cd /* Connection is possible only if container exists in storage */);
|
|
855
855
|
}
|
|
856
856
|
// Fail while disconnected
|
|
857
857
|
if (reconnection) {
|
|
@@ -871,6 +871,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
871
871
|
this.replayPendingStates();
|
|
872
872
|
}
|
|
873
873
|
this.dataStores.setConnectionState(connected, clientId);
|
|
874
|
+
this.garbageCollector.setConnectionState(connected, clientId);
|
|
874
875
|
raiseConnectedEvent(this.mc.logger, this, connected, clientId);
|
|
875
876
|
}
|
|
876
877
|
process(messageArg, local) {
|
|
@@ -928,7 +929,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
928
929
|
case ContainerMessageType.Rejoin:
|
|
929
930
|
break;
|
|
930
931
|
default:
|
|
931
|
-
assert(!runtimeMessage,
|
|
932
|
+
assert(!runtimeMessage, 0x3ce /* Runtime message of unknown type */);
|
|
932
933
|
}
|
|
933
934
|
// For back-compat, notify only about runtime messages for now.
|
|
934
935
|
if (runtimeMessage) {
|
|
@@ -1027,9 +1028,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1027
1028
|
}
|
|
1028
1029
|
flush() {
|
|
1029
1030
|
assert(this._orderSequentiallyCalls === 0, 0x24c /* "Cannot call `flush()` from `orderSequentially`'s callback" */);
|
|
1030
|
-
|
|
1031
|
-
this.flushBatch(
|
|
1032
|
-
assert(this.
|
|
1031
|
+
this.flushBatch(this.pendingAttachBatch.popBatch());
|
|
1032
|
+
this.flushBatch(this.pendingBatch.popBatch());
|
|
1033
|
+
assert(this.emptyBatch, 0x3cf /* reentrancy */);
|
|
1033
1034
|
}
|
|
1034
1035
|
flushBatch(batch) {
|
|
1035
1036
|
const length = batch.length;
|
|
@@ -1069,7 +1070,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1069
1070
|
}
|
|
1070
1071
|
// Convert from clientSequenceNumber of last message in the batch to clientSequenceNumber of first message.
|
|
1071
1072
|
clientSequenceNumber -= batch.length - 1;
|
|
1072
|
-
assert(clientSequenceNumber >= 0,
|
|
1073
|
+
assert(clientSequenceNumber >= 0, 0x3d0 /* clientSequenceNumber can't be negative */);
|
|
1073
1074
|
}
|
|
1074
1075
|
// Let the PendingStateManager know that a message was submitted.
|
|
1075
1076
|
// In future, need to shift toward keeping batch as a whole!
|
|
@@ -1102,7 +1103,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1102
1103
|
trackOrderSequentiallyCalls(callback) {
|
|
1103
1104
|
let checkpoint;
|
|
1104
1105
|
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
1105
|
-
|
|
1106
|
+
// Note: we are not touching this.pendingAttachBatch here, for two reasons:
|
|
1107
|
+
// 1. It would not help, as we flush attach ops as they become available.
|
|
1108
|
+
// 2. There is no way to undo process of data store creation.
|
|
1109
|
+
checkpoint = this.pendingBatch.checkpoint();
|
|
1106
1110
|
}
|
|
1107
1111
|
try {
|
|
1108
1112
|
this._orderSequentiallyCalls++;
|
|
@@ -1389,7 +1393,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1389
1393
|
}
|
|
1390
1394
|
/**
|
|
1391
1395
|
* Runs garbage collection and updates the reference / used state of the nodes in the container.
|
|
1392
|
-
* @returns the statistics of the garbage collection run.
|
|
1396
|
+
* @returns the statistics of the garbage collection run; undefined if GC did not run.
|
|
1393
1397
|
*/
|
|
1394
1398
|
async collectGarbage(options) {
|
|
1395
1399
|
return this.garbageCollector.collectGarbage(options);
|
|
@@ -1420,7 +1424,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1420
1424
|
const summaryNumberLogger = ChildLogger.create(summaryLogger, undefined, {
|
|
1421
1425
|
all: { summaryNumber },
|
|
1422
1426
|
});
|
|
1423
|
-
assert(this.
|
|
1427
|
+
assert(this.emptyBatch, 0x3d1 /* Can't trigger summary in the middle of a batch */);
|
|
1424
1428
|
let latestSnapshotVersionId;
|
|
1425
1429
|
if (refreshLatestAck) {
|
|
1426
1430
|
const latestSnapshotInfo = await this.refreshLatestSummaryAckFromServer(ChildLogger.create(summaryNumberLogger, undefined, { all: { safeSummary: true } }));
|
|
@@ -1495,7 +1499,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1495
1499
|
const forcedFullTree = this.garbageCollector.summaryStateNeedsReset;
|
|
1496
1500
|
try {
|
|
1497
1501
|
summarizeResult = await this.summarize({
|
|
1498
|
-
fullTree: fullTree
|
|
1502
|
+
fullTree: fullTree !== null && fullTree !== void 0 ? fullTree : forcedFullTree,
|
|
1499
1503
|
trackState: true,
|
|
1500
1504
|
summaryLogger: summaryNumberLogger,
|
|
1501
1505
|
runGC: this.garbageCollector.shouldRunGC,
|
|
@@ -1633,15 +1637,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1633
1637
|
}
|
|
1634
1638
|
}
|
|
1635
1639
|
hasPendingMessages() {
|
|
1636
|
-
return this.pendingStateManager.hasPendingMessages() || !this.
|
|
1640
|
+
return this.pendingStateManager.hasPendingMessages() || !this.emptyBatch;
|
|
1637
1641
|
}
|
|
1638
1642
|
updateDocumentDirtyState(dirty) {
|
|
1639
1643
|
if (this.attachState !== AttachState.Attached) {
|
|
1640
|
-
assert(dirty,
|
|
1644
|
+
assert(dirty, 0x3d2 /* Non-attached container is dirty */);
|
|
1641
1645
|
}
|
|
1642
1646
|
else {
|
|
1643
1647
|
// Other way is not true = see this.isContainerMessageDirtyable()
|
|
1644
|
-
assert(!dirty || this.hasPendingMessages(),
|
|
1648
|
+
assert(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
|
|
1645
1649
|
}
|
|
1646
1650
|
if (this.dirtyContainer === dirty) {
|
|
1647
1651
|
return;
|
|
@@ -1698,31 +1702,54 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1698
1702
|
// failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
|
|
1699
1703
|
// these issues.
|
|
1700
1704
|
// Cons:
|
|
1701
|
-
// With large batches, relay service may throttle clients. Clients may disconnect while throttled.
|
|
1705
|
+
// 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
|
|
1702
1706
|
// This change creates new possibility of a lot of newly created data stores never being referenced
|
|
1703
1707
|
// because client died before it had a change to submit the rest of the ops. This will create more
|
|
1704
1708
|
// garbage that needs to be collected leveraging GC (Garbage Collection) feature.
|
|
1709
|
+
// 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
|
|
1710
|
+
// today as rollback can't undo creation of data store. To some extent not sending them is a bigger
|
|
1711
|
+
// issue than sending.
|
|
1705
1712
|
// Please note that this does not change file format, so it can be disabled in the future if this
|
|
1706
1713
|
// optimization no longer makes sense (for example, batch compression may make it less appealing).
|
|
1707
|
-
if (
|
|
1714
|
+
if (type === ContainerMessageType.Attach &&
|
|
1708
1715
|
this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder") !== true) {
|
|
1709
|
-
this.
|
|
1716
|
+
if (!this.pendingAttachBatch.push(message)) {
|
|
1717
|
+
// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
|
|
1718
|
+
// when queue is not empty.
|
|
1719
|
+
// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
|
|
1720
|
+
this.flushBatch(this.pendingAttachBatch.popBatch());
|
|
1721
|
+
if (!this.pendingAttachBatch.push(message)) {
|
|
1722
|
+
throw new GenericError("BatchTooLarge",
|
|
1723
|
+
/* error */ undefined, {
|
|
1724
|
+
opSize: message.contents.length,
|
|
1725
|
+
count: this.pendingAttachBatch.length,
|
|
1726
|
+
limit: this.pendingAttachBatch.limit,
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1710
1730
|
}
|
|
1711
1731
|
else {
|
|
1712
|
-
this.
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
// Queue a microtask to detect the end of the turn and force a flush.
|
|
1719
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1720
|
-
Promise.resolve().then(() => {
|
|
1721
|
-
this.flushTrigger = false;
|
|
1722
|
-
this.flush();
|
|
1732
|
+
if (!this.pendingBatch.push(message)) {
|
|
1733
|
+
throw new GenericError("BatchTooLarge",
|
|
1734
|
+
/* error */ undefined, {
|
|
1735
|
+
opSize: message.contents.length,
|
|
1736
|
+
count: this.pendingBatch.length,
|
|
1737
|
+
limit: this.pendingBatch.limit,
|
|
1723
1738
|
});
|
|
1724
1739
|
}
|
|
1725
1740
|
}
|
|
1741
|
+
if (this._flushMode !== FlushMode.TurnBased) {
|
|
1742
|
+
this.flush();
|
|
1743
|
+
}
|
|
1744
|
+
else if (!this.flushTrigger) {
|
|
1745
|
+
this.flushTrigger = true;
|
|
1746
|
+
// Queue a microtask to detect the end of the turn and force a flush.
|
|
1747
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1748
|
+
Promise.resolve().then(() => {
|
|
1749
|
+
this.flushTrigger = false;
|
|
1750
|
+
this.flush();
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1726
1753
|
}
|
|
1727
1754
|
catch (error) {
|
|
1728
1755
|
this.closeFn(error);
|
|
@@ -1736,14 +1763,11 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1736
1763
|
this.verifyNotClosed();
|
|
1737
1764
|
assert(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
|
|
1738
1765
|
// System message should not be sent in the middle of the batch.
|
|
1739
|
-
assert(this.
|
|
1766
|
+
assert(this.emptyBatch, 0x3d4 /* System op in the middle of a batch */);
|
|
1740
1767
|
// back-compat: ADO #1385: Make this call unconditional in the future
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
else {
|
|
1745
|
-
return this.context.submitFn(MessageType.Summarize, contents, false); // batch
|
|
1746
|
-
}
|
|
1768
|
+
return this.context.submitSummaryFn !== undefined
|
|
1769
|
+
? this.context.submitSummaryFn(contents)
|
|
1770
|
+
: this.context.submitFn(MessageType.Summarize, contents, false);
|
|
1747
1771
|
}
|
|
1748
1772
|
/**
|
|
1749
1773
|
* Throw an error if the runtime is closed. Methods that are expected to potentially
|
|
@@ -1923,7 +1947,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1923
1947
|
// don't have any more saved ops
|
|
1924
1948
|
await this.pendingStateManager.applyStashedOpsAt();
|
|
1925
1949
|
// If it's not the case, we should take it into account when calculating dirty state.
|
|
1926
|
-
assert(this.context.attachState === AttachState.Attached,
|
|
1950
|
+
assert(this.context.attachState === AttachState.Attached, 0x3d5 /* this function is called for attached containers only */);
|
|
1927
1951
|
if (!this.hasPendingMessages()) {
|
|
1928
1952
|
this.updateDocumentDirtyState(false);
|
|
1929
1953
|
}
|