@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.
Files changed (128) hide show
  1. package/dist/batchManager.d.ts +7 -2
  2. package/dist/batchManager.d.ts.map +1 -1
  3. package/dist/batchManager.js +19 -17
  4. package/dist/batchManager.js.map +1 -1
  5. package/dist/batchTracker.d.ts +1 -2
  6. package/dist/batchTracker.d.ts.map +1 -1
  7. package/dist/batchTracker.js +1 -2
  8. package/dist/batchTracker.js.map +1 -1
  9. package/dist/containerRuntime.d.ts +10 -5
  10. package/dist/containerRuntime.d.ts.map +1 -1
  11. package/dist/containerRuntime.js +87 -63
  12. package/dist/containerRuntime.js.map +1 -1
  13. package/dist/dataStoreContext.d.ts +14 -5
  14. package/dist/dataStoreContext.d.ts.map +1 -1
  15. package/dist/dataStoreContext.js +19 -11
  16. package/dist/dataStoreContext.js.map +1 -1
  17. package/dist/dataStores.d.ts +6 -2
  18. package/dist/dataStores.d.ts.map +1 -1
  19. package/dist/dataStores.js +7 -9
  20. package/dist/dataStores.js.map +1 -1
  21. package/dist/deltaScheduler.d.ts +6 -4
  22. package/dist/deltaScheduler.d.ts.map +1 -1
  23. package/dist/deltaScheduler.js +6 -4
  24. package/dist/deltaScheduler.js.map +1 -1
  25. package/dist/garbageCollection.d.ts +41 -12
  26. package/dist/garbageCollection.d.ts.map +1 -1
  27. package/dist/garbageCollection.js +176 -98
  28. package/dist/garbageCollection.js.map +1 -1
  29. package/dist/gcSweepReadyUsageDetection.d.ts +53 -0
  30. package/dist/gcSweepReadyUsageDetection.d.ts.map +1 -0
  31. package/dist/gcSweepReadyUsageDetection.js +135 -0
  32. package/dist/gcSweepReadyUsageDetection.js.map +1 -0
  33. package/dist/orderedClientElection.d.ts +28 -10
  34. package/dist/orderedClientElection.d.ts.map +1 -1
  35. package/dist/orderedClientElection.js +14 -4
  36. package/dist/orderedClientElection.js.map +1 -1
  37. package/dist/packageVersion.d.ts +1 -1
  38. package/dist/packageVersion.d.ts.map +1 -1
  39. package/dist/packageVersion.js +1 -1
  40. package/dist/packageVersion.js.map +1 -1
  41. package/dist/pendingStateManager.d.ts.map +1 -1
  42. package/dist/pendingStateManager.js +4 -2
  43. package/dist/pendingStateManager.js.map +1 -1
  44. package/dist/scheduleManager.d.ts +6 -3
  45. package/dist/scheduleManager.d.ts.map +1 -1
  46. package/dist/scheduleManager.js +21 -13
  47. package/dist/scheduleManager.js.map +1 -1
  48. package/dist/summarizerTypes.d.ts +13 -6
  49. package/dist/summarizerTypes.d.ts.map +1 -1
  50. package/dist/summarizerTypes.js.map +1 -1
  51. package/dist/summaryCollection.d.ts.map +1 -1
  52. package/dist/summaryCollection.js +3 -6
  53. package/dist/summaryCollection.js.map +1 -1
  54. package/dist/summaryManager.d.ts +2 -2
  55. package/dist/summaryManager.js +2 -2
  56. package/dist/summaryManager.js.map +1 -1
  57. package/lib/batchManager.d.ts +7 -2
  58. package/lib/batchManager.d.ts.map +1 -1
  59. package/lib/batchManager.js +19 -17
  60. package/lib/batchManager.js.map +1 -1
  61. package/lib/batchTracker.d.ts +1 -2
  62. package/lib/batchTracker.d.ts.map +1 -1
  63. package/lib/batchTracker.js +1 -2
  64. package/lib/batchTracker.js.map +1 -1
  65. package/lib/containerRuntime.d.ts +10 -5
  66. package/lib/containerRuntime.d.ts.map +1 -1
  67. package/lib/containerRuntime.js +87 -63
  68. package/lib/containerRuntime.js.map +1 -1
  69. package/lib/dataStoreContext.d.ts +14 -5
  70. package/lib/dataStoreContext.d.ts.map +1 -1
  71. package/lib/dataStoreContext.js +20 -12
  72. package/lib/dataStoreContext.js.map +1 -1
  73. package/lib/dataStores.d.ts +6 -2
  74. package/lib/dataStores.d.ts.map +1 -1
  75. package/lib/dataStores.js +7 -9
  76. package/lib/dataStores.js.map +1 -1
  77. package/lib/deltaScheduler.d.ts +6 -4
  78. package/lib/deltaScheduler.d.ts.map +1 -1
  79. package/lib/deltaScheduler.js +6 -4
  80. package/lib/deltaScheduler.js.map +1 -1
  81. package/lib/garbageCollection.d.ts +41 -12
  82. package/lib/garbageCollection.d.ts.map +1 -1
  83. package/lib/garbageCollection.js +175 -97
  84. package/lib/garbageCollection.js.map +1 -1
  85. package/lib/gcSweepReadyUsageDetection.d.ts +53 -0
  86. package/lib/gcSweepReadyUsageDetection.d.ts.map +1 -0
  87. package/lib/gcSweepReadyUsageDetection.js +130 -0
  88. package/lib/gcSweepReadyUsageDetection.js.map +1 -0
  89. package/lib/orderedClientElection.d.ts +28 -10
  90. package/lib/orderedClientElection.d.ts.map +1 -1
  91. package/lib/orderedClientElection.js +14 -4
  92. package/lib/orderedClientElection.js.map +1 -1
  93. package/lib/packageVersion.d.ts +1 -1
  94. package/lib/packageVersion.d.ts.map +1 -1
  95. package/lib/packageVersion.js +1 -1
  96. package/lib/packageVersion.js.map +1 -1
  97. package/lib/pendingStateManager.d.ts.map +1 -1
  98. package/lib/pendingStateManager.js +4 -2
  99. package/lib/pendingStateManager.js.map +1 -1
  100. package/lib/scheduleManager.d.ts +6 -3
  101. package/lib/scheduleManager.d.ts.map +1 -1
  102. package/lib/scheduleManager.js +22 -14
  103. package/lib/scheduleManager.js.map +1 -1
  104. package/lib/summarizerTypes.d.ts +13 -6
  105. package/lib/summarizerTypes.d.ts.map +1 -1
  106. package/lib/summarizerTypes.js.map +1 -1
  107. package/lib/summaryCollection.d.ts.map +1 -1
  108. package/lib/summaryCollection.js +3 -6
  109. package/lib/summaryCollection.js.map +1 -1
  110. package/lib/summaryManager.d.ts +2 -2
  111. package/lib/summaryManager.js +2 -2
  112. package/lib/summaryManager.js.map +1 -1
  113. package/package.json +19 -16
  114. package/src/batchManager.ts +22 -19
  115. package/src/batchTracker.ts +1 -2
  116. package/src/containerRuntime.ts +118 -80
  117. package/src/dataStoreContext.ts +20 -10
  118. package/src/dataStores.ts +7 -8
  119. package/src/deltaScheduler.ts +6 -4
  120. package/src/garbageCollection.ts +224 -134
  121. package/src/gcSweepReadyUsageDetection.ts +147 -0
  122. package/src/orderedClientElection.ts +31 -10
  123. package/src/packageVersion.ts +1 -1
  124. package/src/pendingStateManager.ts +4 -2
  125. package/src/scheduleManager.ts +30 -10
  126. package/src/summarizerTypes.ts +14 -6
  127. package/src/summaryCollection.ts +3 -5
  128. package/src/summaryManager.ts +2 -2
@@ -101,9 +101,12 @@ export function isRuntimeMessage(message) {
101
101
  }
102
102
  /**
103
103
  * Unpacks runtime messages
104
- * @internal - no promises RE back-compat - this is internal API.
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
- this.batchManager = new BatchManager();
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
- if (this.summaryConfiguration.state !== "disabled") {
535
- return this.summaryConfiguration.summarizerClientElection === true;
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
- if (this.summaryConfiguration.state !== "disabled") {
548
- return this.summaryConfiguration.maxOpsSinceLastSummary;
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
- if (this.summaryConfiguration.state !== "disabled") {
561
- return this.summaryConfiguration.initialSummarizerDelayMs;
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
- if (blob) {
640
- return {
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, "Connection is possible only if container exists in storage");
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, "Runtime message of unknown type");
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
- const batch = this.batchManager.popBatch();
1031
- this.flushBatch(batch);
1032
- assert(this.batchManager.empty, "reentrancy");
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, "clientSequenceNumber can't be negative");
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
- checkpoint = this.batchManager.checkpoint();
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.batchManager.empty, "Can't trigger summary in the middle of a batch");
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 || forcedFullTree,
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.batchManager.empty;
1640
+ return this.pendingStateManager.hasPendingMessages() || !this.emptyBatch;
1637
1641
  }
1638
1642
  updateDocumentDirtyState(dirty) {
1639
1643
  if (this.attachState !== AttachState.Attached) {
1640
- assert(dirty, "Non-attached container is 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(), "if doc is dirty, there has to be pending ops");
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 (this._flushMode === FlushMode.TurnBased && type === ContainerMessageType.Attach &&
1714
+ if (type === ContainerMessageType.Attach &&
1708
1715
  this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder") !== true) {
1709
- this.flushBatch([message]);
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.batchManager.push(message);
1713
- if (this._flushMode !== FlushMode.TurnBased) {
1714
- this.flush();
1715
- }
1716
- else if (!this.flushTrigger) {
1717
- this.flushTrigger = true;
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.batchManager.empty, "System op in the middle of a batch");
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
- if (this.context.submitSummaryFn !== undefined) {
1742
- return this.context.submitSummaryFn(contents);
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, "this function is called for attached containers only");
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
  }