@fluidframework/container-runtime 2.91.0 → 2.93.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.
Files changed (140) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +1 -1
  3. package/api-report/container-runtime.legacy.beta.api.md +2 -0
  4. package/container-runtime.test-files.tar +0 -0
  5. package/dist/containerCompatibility.d.ts +1 -1
  6. package/dist/containerCompatibility.d.ts.map +1 -1
  7. package/dist/containerCompatibility.js.map +1 -1
  8. package/dist/containerRuntime.d.ts +38 -11
  9. package/dist/containerRuntime.d.ts.map +1 -1
  10. package/dist/containerRuntime.js +118 -86
  11. package/dist/containerRuntime.js.map +1 -1
  12. package/dist/gc/garbageCollection.d.ts +1 -0
  13. package/dist/gc/garbageCollection.d.ts.map +1 -1
  14. package/dist/gc/garbageCollection.js +3 -8
  15. package/dist/gc/garbageCollection.js.map +1 -1
  16. package/dist/gc/gcDefinitions.d.ts +4 -0
  17. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  18. package/dist/gc/gcDefinitions.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/legacy.d.ts +1 -1
  24. package/dist/opLifecycle/batchManager.d.ts +3 -9
  25. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  26. package/dist/opLifecycle/batchManager.js +5 -3
  27. package/dist/opLifecycle/batchManager.js.map +1 -1
  28. package/dist/opLifecycle/index.d.ts +1 -1
  29. package/dist/opLifecycle/index.d.ts.map +1 -1
  30. package/dist/opLifecycle/index.js +2 -1
  31. package/dist/opLifecycle/index.js.map +1 -1
  32. package/dist/opLifecycle/opGroupingManager.d.ts +6 -0
  33. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  34. package/dist/opLifecycle/opGroupingManager.js +11 -2
  35. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  36. package/dist/opLifecycle/opSerialization.d.ts +3 -1
  37. package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
  38. package/dist/opLifecycle/opSerialization.js +11 -9
  39. package/dist/opLifecycle/opSerialization.js.map +1 -1
  40. package/dist/opLifecycle/outbox.d.ts +8 -11
  41. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  42. package/dist/opLifecycle/outbox.js +42 -66
  43. package/dist/opLifecycle/outbox.js.map +1 -1
  44. package/dist/packageVersion.d.ts +1 -1
  45. package/dist/packageVersion.js +1 -1
  46. package/dist/packageVersion.js.map +1 -1
  47. package/dist/pendingStateManager.d.ts +8 -9
  48. package/dist/pendingStateManager.d.ts.map +1 -1
  49. package/dist/pendingStateManager.js +24 -22
  50. package/dist/pendingStateManager.js.map +1 -1
  51. package/dist/public.d.ts +1 -1
  52. package/dist/runtimeLayerCompatState.d.ts +2 -2
  53. package/dist/summary/documentSchema.d.ts +9 -3
  54. package/dist/summary/documentSchema.d.ts.map +1 -1
  55. package/dist/summary/documentSchema.js +19 -3
  56. package/dist/summary/documentSchema.js.map +1 -1
  57. package/dist/summary/orderedClientElection.js +2 -2
  58. package/dist/summary/orderedClientElection.js.map +1 -1
  59. package/dist/summary/summaryManager.d.ts +1 -0
  60. package/dist/summary/summaryManager.d.ts.map +1 -1
  61. package/dist/summary/summaryManager.js +9 -0
  62. package/dist/summary/summaryManager.js.map +1 -1
  63. package/eslint.config.mts +1 -1
  64. package/internal.d.ts +1 -1
  65. package/legacy.d.ts +1 -1
  66. package/lib/containerCompatibility.d.ts +1 -1
  67. package/lib/containerCompatibility.d.ts.map +1 -1
  68. package/lib/containerCompatibility.js.map +1 -1
  69. package/lib/containerRuntime.d.ts +38 -11
  70. package/lib/containerRuntime.d.ts.map +1 -1
  71. package/lib/containerRuntime.js +118 -87
  72. package/lib/containerRuntime.js.map +1 -1
  73. package/lib/gc/garbageCollection.d.ts +1 -0
  74. package/lib/gc/garbageCollection.d.ts.map +1 -1
  75. package/lib/gc/garbageCollection.js +3 -8
  76. package/lib/gc/garbageCollection.js.map +1 -1
  77. package/lib/gc/gcDefinitions.d.ts +4 -0
  78. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  79. package/lib/gc/gcDefinitions.js.map +1 -1
  80. package/lib/index.d.ts +1 -1
  81. package/lib/index.d.ts.map +1 -1
  82. package/lib/index.js +1 -1
  83. package/lib/index.js.map +1 -1
  84. package/lib/legacy.d.ts +1 -1
  85. package/lib/opLifecycle/batchManager.d.ts +3 -9
  86. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  87. package/lib/opLifecycle/batchManager.js +5 -3
  88. package/lib/opLifecycle/batchManager.js.map +1 -1
  89. package/lib/opLifecycle/index.d.ts +1 -1
  90. package/lib/opLifecycle/index.d.ts.map +1 -1
  91. package/lib/opLifecycle/index.js +1 -1
  92. package/lib/opLifecycle/index.js.map +1 -1
  93. package/lib/opLifecycle/opGroupingManager.d.ts +6 -0
  94. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  95. package/lib/opLifecycle/opGroupingManager.js +10 -1
  96. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  97. package/lib/opLifecycle/opSerialization.d.ts +3 -1
  98. package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
  99. package/lib/opLifecycle/opSerialization.js +11 -9
  100. package/lib/opLifecycle/opSerialization.js.map +1 -1
  101. package/lib/opLifecycle/outbox.d.ts +8 -11
  102. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  103. package/lib/opLifecycle/outbox.js +43 -67
  104. package/lib/opLifecycle/outbox.js.map +1 -1
  105. package/lib/packageVersion.d.ts +1 -1
  106. package/lib/packageVersion.js +1 -1
  107. package/lib/packageVersion.js.map +1 -1
  108. package/lib/pendingStateManager.d.ts +8 -9
  109. package/lib/pendingStateManager.d.ts.map +1 -1
  110. package/lib/pendingStateManager.js +24 -22
  111. package/lib/pendingStateManager.js.map +1 -1
  112. package/lib/public.d.ts +1 -1
  113. package/lib/runtimeLayerCompatState.d.ts +2 -2
  114. package/lib/summary/documentSchema.d.ts +9 -3
  115. package/lib/summary/documentSchema.d.ts.map +1 -1
  116. package/lib/summary/documentSchema.js +19 -3
  117. package/lib/summary/documentSchema.js.map +1 -1
  118. package/lib/summary/orderedClientElection.js +2 -2
  119. package/lib/summary/orderedClientElection.js.map +1 -1
  120. package/lib/summary/summaryManager.d.ts +1 -0
  121. package/lib/summary/summaryManager.d.ts.map +1 -1
  122. package/lib/summary/summaryManager.js +9 -0
  123. package/lib/summary/summaryManager.js.map +1 -1
  124. package/lib/tsdoc-metadata.json +1 -1
  125. package/package.json +27 -28
  126. package/src/containerCompatibility.ts +2 -0
  127. package/src/containerRuntime.ts +163 -106
  128. package/src/gc/garbageCollection.ts +4 -9
  129. package/src/gc/gcDefinitions.ts +4 -0
  130. package/src/index.ts +1 -0
  131. package/src/opLifecycle/batchManager.ts +6 -13
  132. package/src/opLifecycle/index.ts +1 -0
  133. package/src/opLifecycle/opGroupingManager.ts +11 -1
  134. package/src/opLifecycle/opSerialization.ts +14 -12
  135. package/src/opLifecycle/outbox.ts +53 -86
  136. package/src/packageVersion.ts +1 -1
  137. package/src/pendingStateManager.ts +31 -33
  138. package/src/summary/documentSchema.ts +25 -2
  139. package/src/summary/orderedClientElection.ts +2 -2
  140. package/src/summary/summaryManager.ts +11 -0
@@ -55,7 +55,7 @@ function localBatchToOutboundBatch({ staged: _staged, // Peel this off the incom
55
55
  // It will be set to true, but the batch was not actually staged.
56
56
  // Shallow copy each message as we switch types
57
57
  const outboundMessages = localBatch.messages.map(({ runtimeOp, ...message }) => ({
58
- contents: (0, opSerialization_js_1.serializeOp)(runtimeOp),
58
+ contents: (0, opSerialization_js_1.serializeOp)(runtimeOp).content,
59
59
  ...message,
60
60
  }));
61
61
  const contentSizeInBytes = outboundMessages.reduce((acc, message) => acc + (message.contents?.length ?? 0), 0);
@@ -111,15 +111,11 @@ class Outbox {
111
111
  this.maxMismatchedOpsToReport = 3;
112
112
  this.mismatchedOpsReported = 0;
113
113
  this.logger = (0, internal_2.createChildLogger)({ logger: params.logger, namespace: "Outbox" });
114
- this.mainBatch = new batchManager_js_1.BatchManager({ canRebase: true });
115
- this.blobAttachBatch = new batchManager_js_1.BatchManager({ canRebase: true });
116
- this.idAllocationBatch = new batchManager_js_1.BatchManager({
117
- canRebase: false,
118
- ignoreBatchId: true,
119
- });
114
+ this.mainBatch = new batchManager_js_1.BatchManager({ disableGroupedBatching: false });
115
+ this.blobAttachBatch = new batchManager_js_1.BatchManager({ disableGroupedBatching: true });
120
116
  }
121
117
  get messageCount() {
122
- return this.mainBatch.length + this.blobAttachBatch.length + this.idAllocationBatch.length;
118
+ return this.mainBatch.length + this.blobAttachBatch.length;
123
119
  }
124
120
  get mainBatchMessageCount() {
125
121
  return this.mainBatch.length;
@@ -127,16 +123,11 @@ class Outbox {
127
123
  get blobAttachBatchMessageCount() {
128
124
  return this.blobAttachBatch.length;
129
125
  }
130
- get idAllocationBatchMessageCount() {
131
- return this.idAllocationBatch.length;
132
- }
133
126
  get isEmpty() {
134
127
  return this.messageCount === 0;
135
128
  }
136
129
  containsUserChanges() {
137
- return (this.mainBatch.containsUserChanges() || this.blobAttachBatch.containsUserChanges()
138
- // ID Allocation ops are not user changes
139
- );
130
+ return this.mainBatch.containsUserChanges() || this.blobAttachBatch.containsUserChanges();
140
131
  }
141
132
  /**
142
133
  * Detect whether batching has been interrupted by an incoming message being processed. In this case,
@@ -149,16 +140,13 @@ class Outbox {
149
140
  * last message processed by the ContainerRuntime. In the absence of op reentrancy, this
150
141
  * pair will remain stable during a single JS turn during which the batch is being built up.
151
142
  */
152
- maybeFlushPartialBatch() {
143
+ outboxSequenceNumberCoherencyCheck() {
153
144
  const mainBatchSeqNums = this.mainBatch.sequenceNumbers;
154
145
  const blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;
155
- const idAllocSeqNums = this.idAllocationBatch.sequenceNumbers;
156
- (0, internal_1.assert)((0, batchManager_js_1.sequenceNumbersMatch)(mainBatchSeqNums, blobAttachSeqNums) &&
157
- (0, batchManager_js_1.sequenceNumbersMatch)(mainBatchSeqNums, idAllocSeqNums), 0x58d /* Reference sequence numbers from both batches must be in sync */);
146
+ (0, internal_1.assert)((0, batchManager_js_1.sequenceNumbersMatch)(mainBatchSeqNums, blobAttachSeqNums), 0x58d /* Reference sequence numbers from both batches must be in sync */);
158
147
  const currentSequenceNumbers = this.params.getCurrentSequenceNumbers();
159
148
  if ((0, batchManager_js_1.sequenceNumbersMatch)(mainBatchSeqNums, currentSequenceNumbers) &&
160
- (0, batchManager_js_1.sequenceNumbersMatch)(blobAttachSeqNums, currentSequenceNumbers) &&
161
- (0, batchManager_js_1.sequenceNumbersMatch)(idAllocSeqNums, currentSequenceNumbers)) {
149
+ (0, batchManager_js_1.sequenceNumbersMatch)(blobAttachSeqNums, currentSequenceNumbers)) {
162
150
  // The reference sequence numbers are stable, there is nothing to do
163
151
  return;
164
152
  }
@@ -170,9 +158,7 @@ class Outbox {
170
158
  if (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {
171
159
  this.logger.sendTelemetryEvent({
172
160
  // Only log error if this is truly unexpected
173
- category: expectedDueToReentrancy || this.params.config.flushPartialBatches
174
- ? "generic"
175
- : "error",
161
+ category: expectedDueToReentrancy ? "generic" : "error",
176
162
  eventName: "ReferenceSequenceNumberMismatch",
177
163
  details: {
178
164
  expectedDueToReentrancy,
@@ -185,11 +171,6 @@ class Outbox {
185
171
  },
186
172
  }, errorWrapper.value);
187
173
  }
188
- // If we're configured to flush partial batches, do that now and return (don't throw)
189
- if (this.params.config.flushPartialBatches) {
190
- this.flushAll();
191
- return;
192
- }
193
174
  // If we are in a reentrant context, we know this can happen without causing any harm.
194
175
  if (expectedDueToReentrancy) {
195
176
  return;
@@ -197,17 +178,13 @@ class Outbox {
197
178
  throw errorWrapper.value;
198
179
  }
199
180
  submit(message) {
200
- this.maybeFlushPartialBatch();
181
+ this.outboxSequenceNumberCoherencyCheck();
201
182
  this.addMessageToBatchManager(this.mainBatch, message);
202
183
  }
203
184
  submitBlobAttach(message) {
204
- this.maybeFlushPartialBatch();
185
+ this.outboxSequenceNumberCoherencyCheck();
205
186
  this.addMessageToBatchManager(this.blobAttachBatch, message);
206
187
  }
207
- submitIdAllocation(message) {
208
- this.maybeFlushPartialBatch();
209
- this.addMessageToBatchManager(this.idAllocationBatch, message);
210
- }
211
188
  addMessageToBatchManager(batchManager, message) {
212
189
  batchManager.push(message, this.isContextReentrant(), this.params.getCurrentSequenceNumbers().clientSequenceNumber);
213
190
  }
@@ -220,17 +197,18 @@ class Outbox {
220
197
  */
221
198
  flush(resubmitInfo) {
222
199
  // We have nothing to flush if all batchManagers are empty, and we we're not needing to resubmit an empty batch placeholder
223
- if (this.idAllocationBatch.empty &&
224
- this.blobAttachBatch.empty &&
200
+ if (this.blobAttachBatch.empty &&
225
201
  this.mainBatch.empty &&
226
202
  resubmitInfo?.batchId === undefined) {
203
+ // Note that it's possible that there are unfinalized ranges in the ID Compressor,
204
+ // but there's no urgency to flush those if they're not referenced in any messages.
227
205
  return;
228
206
  }
229
207
  (0, internal_1.assert)(!this.isContextReentrant(), 0xb7b /* Flushing must not happen while incoming changes are being processed */);
230
208
  this.flushAll(resubmitInfo);
231
209
  }
232
210
  flushAll(resubmitInfo) {
233
- const allBatchesEmpty = this.idAllocationBatch.empty && this.blobAttachBatch.empty && this.mainBatch.empty;
211
+ const allBatchesEmpty = this.blobAttachBatch.empty && this.mainBatch.empty;
234
212
  if (allBatchesEmpty) {
235
213
  // If we're resubmitting with a batchId and all batches are empty, we need to flush an empty batch.
236
214
  // Note that we currently resubmit one batch at a time, so on resubmit, 1 of the 2 batches will *always* be empty.
@@ -242,22 +220,8 @@ class Outbox {
242
220
  }
243
221
  return;
244
222
  }
245
- // Don't use resubmittingBatchId for idAllocationBatch.
246
- // ID Allocation messages are not directly resubmitted so don't pass the resubmitInfo
247
- this.flushInternal({
248
- batchManager: this.idAllocationBatch,
249
- // Note: For now, we will never stage ID Allocation messages.
250
- // They won't contain personal info and no harm in extra allocations in case of discarding the staged changes
251
- });
252
- this.flushInternal({
253
- batchManager: this.blobAttachBatch,
254
- disableGroupedBatching: true,
255
- resubmitInfo,
256
- });
257
- this.flushInternal({
258
- batchManager: this.mainBatch,
259
- resubmitInfo,
260
- });
223
+ this.flushInternal(this.blobAttachBatch, resubmitInfo);
224
+ this.flushInternal(this.mainBatch, resubmitInfo);
261
225
  }
262
226
  flushEmptyBatch(resubmittingBatchId, resubmittingStagedBatch) {
263
227
  const referenceSequenceNumber = this.params.getCurrentSequenceNumbers().referenceSequenceNumber;
@@ -271,20 +235,20 @@ class Outbox {
271
235
  this.params.pendingStateManager.onFlushEmptyBatch(placeholderMessage, clientSequenceNumber, resubmittingStagedBatch);
272
236
  return;
273
237
  }
274
- flushInternal(params) {
275
- const { batchManager, disableGroupedBatching = false, resubmitInfo } = params;
238
+ flushInternal(batchManager, resubmitInfo) {
276
239
  if (batchManager.empty) {
277
240
  return;
278
241
  }
279
- const rawBatch = batchManager.popBatch(resubmitInfo?.batchId);
242
+ let rawBatch = batchManager.popBatch();
280
243
  // On resubmit we use the original batch's staged state, so these should match as well.
281
244
  const staged = rawBatch.staged === true;
282
245
  (0, internal_1.assert)(resubmitInfo === undefined || resubmitInfo.staged === staged, 0xba3 /* Mismatch in staged state tracking */);
283
- const groupingEnabled = !disableGroupedBatching && this.params.groupingManager.groupedBatchingEnabled();
284
- if (batchManager.options.canRebase &&
285
- rawBatch.hasReentrantOps === true &&
286
- groupingEnabled) {
246
+ const groupingEnabled = !batchManager.options.disableGroupedBatching &&
247
+ this.params.groupingManager.groupedBatchingEnabled();
248
+ if (rawBatch.hasReentrantOps === true) {
249
+ (0, internal_1.assert)(resubmitInfo === undefined, 0xcf2 /* Re-submitting a batch with reentrant ops is not supported */);
287
250
  (0, internal_1.assert)(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
251
+ // Rebase the current batch (resubmit the ops one-by-one) and then reinvoke flushInternal.
288
252
  // If a batch contains reentrant ops (ops created as a result from processing another op)
289
253
  // it needs to be rebased so that we can ensure consistent reference sequence numbers
290
254
  // and eventual consistency at the DDS level.
@@ -294,16 +258,30 @@ class Outbox {
294
258
  this.rebase(rawBatch, batchManager);
295
259
  return;
296
260
  }
297
- let clientSequenceNumber;
298
261
  // Did we disconnect? (i.e. is shouldSend false?)
299
262
  // If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
300
263
  // Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
301
- if (this.params.shouldSend() && !staged) {
264
+ const shouldSendNow = this.params.shouldSend() && !staged;
265
+ let clientSequenceNumber;
266
+ if (shouldSendNow) {
267
+ // Generate ID Allocation op just-in-time, after rebase (if any), and before addBatchMetadata,
268
+ // so that the prepended idAllocMsg is correctly marked as the first op in the batch.
269
+ // This ensures the refSeq is correct (matching the rest of the batch) and that
270
+ // ID ranges aren't lost during rebase (since reSubmit drops IdAllocation ops).
271
+ // Only generate for non-staged batches — ID alloc ops are always non-staged.
272
+ const idAllocMsg = this.params.generateIdAllocationOp();
273
+ if (idAllocMsg !== undefined) {
274
+ rawBatch = { ...rawBatch, messages: [idAllocMsg, ...rawBatch.messages] };
275
+ }
276
+ (0, batchManager_js_1.addBatchMetadata)(rawBatch, resubmitInfo?.batchId);
302
277
  const virtualizedBatch = this.virtualizeBatch(rawBatch, groupingEnabled);
303
278
  clientSequenceNumber = this.sendBatch(virtualizedBatch);
304
279
  (0, internal_1.assert)(clientSequenceNumber === undefined || clientSequenceNumber >= 0, 0x9d2 /* unexpected negative clientSequenceNumber (empty batch should yield undefined) */);
305
280
  }
306
- this.params.pendingStateManager.onFlushBatch(rawBatch.messages, clientSequenceNumber, staged, batchManager.options.ignoreBatchId);
281
+ else {
282
+ (0, batchManager_js_1.addBatchMetadata)(rawBatch, resubmitInfo?.batchId);
283
+ }
284
+ this.params.pendingStateManager.onFlushBatch(rawBatch.messages, clientSequenceNumber, staged);
307
285
  }
308
286
  /**
309
287
  * Rebases a batch. All the ops in the batch are resubmitted to the runtime and
@@ -313,7 +291,6 @@ class Outbox {
313
291
  */
314
292
  rebase(rawBatch, batchManager) {
315
293
  (0, internal_1.assert)(!this.rebasing, 0x6fb /* Reentrancy */);
316
- (0, internal_1.assert)(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);
317
294
  this.rebasing = true;
318
295
  const squash = false;
319
296
  for (const message of rawBatch.messages) {
@@ -331,7 +308,7 @@ class Outbox {
331
308
  }, new internal_2.UsageError("BatchRebase"));
332
309
  this.batchRebasesToReport--;
333
310
  }
334
- this.flushInternal({ batchManager });
311
+ this.flushInternal(batchManager);
335
312
  this.rebasing = false;
336
313
  }
337
314
  isContextReentrant() {
@@ -444,7 +421,6 @@ class Outbox {
444
421
  const mainBatch = this.mainBatch.checkpoint();
445
422
  return {
446
423
  mainBatch,
447
- idAllocationBatch: this.idAllocationBatch.checkpoint(),
448
424
  blobAttachBatch: this.blobAttachBatch.checkpoint(),
449
425
  };
450
426
  }
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/opLifecycle/outbox.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IBatchMessage } from \"@fluidframework/container-definitions/internal\";\nimport type {\n\tITelemetryBaseLogger,\n\tITelemetryBaseProperties,\n} from \"@fluidframework/core-interfaces\";\nimport { assert, Lazy } from \"@fluidframework/core-utils/internal\";\nimport {\n\tDataProcessingError,\n\tUsageError,\n\tcreateChildLogger,\n\ttype IFluidErrorBase,\n\ttype ITelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { ICompressionRuntimeOptions } from \"../compressionDefinitions.js\";\nimport type {\n\tPendingMessageResubmitData,\n\tPendingStateManager,\n} from \"../pendingStateManager.js\";\n\nimport {\n\tBatchManager,\n\ttype BatchSequenceNumbers,\n\tsequenceNumbersMatch,\n\ttype BatchId,\n} from \"./batchManager.js\";\nimport type {\n\tLocalBatchMessage,\n\tIBatchCheckpoint,\n\tOutboundBatchMessage,\n\tOutboundSingletonBatch,\n\tLocalBatch,\n\tOutboundBatch,\n} from \"./definitions.js\";\nimport type { OpCompressor } from \"./opCompressor.js\";\nimport type { OpGroupingManager } from \"./opGroupingManager.js\";\nimport { serializeOp } from \"./opSerialization.js\";\nimport type { OpSplitter } from \"./opSplitter.js\";\n\nexport interface IOutboxConfig {\n\treadonly compressionOptions: ICompressionRuntimeOptions;\n\t/**\n\t * The maximum size of a batch that we can send over the wire.\n\t */\n\treadonly maxBatchSizeInBytes: number;\n\t/**\n\t * If true, maybeFlushPartialBatch will flush the batch if the reference sequence number changed\n\t * since the batch started. Otherwise, it will throw in this case (apart from reentrancy which is handled elsewhere).\n\t * Once the new throw-based flow is proved in a production environment, this option will be removed.\n\t */\n\treadonly flushPartialBatches: boolean;\n}\n\nexport interface IOutboxParameters {\n\treadonly shouldSend: () => boolean;\n\treadonly pendingStateManager: PendingStateManager;\n\treadonly submitBatchFn:\n\t\t| ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)\n\t\t| undefined;\n\treadonly legacySendBatchFn: (batch: OutboundBatch) => number;\n\treadonly config: IOutboxConfig;\n\treadonly compressor: OpCompressor;\n\treadonly splitter: OpSplitter;\n\treadonly logger: ITelemetryBaseLogger;\n\treadonly groupingManager: OpGroupingManager;\n\treadonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;\n\treadonly reSubmit: (message: PendingMessageResubmitData, squash: boolean) => void;\n\treadonly opReentrancy: () => boolean;\n}\n\n/**\n * Info needed to correctly resubmit a batch\n */\nexport interface BatchResubmitInfo {\n\t/**\n\t * If defined, indicates the Batch ID of the batch being resubmitted.\n\t * This must be preserved on the new batch about to be submitted so they can be correlated/deduped in case both are sent.\n\t */\n\tbatchId?: string;\n\t/**\n\t * Indicates whether or not this batch is \"staged\", meaning it should not be sent to the ordering service yet\n\t * This is important on resubmit because we may be in Staging Mode for new changes,\n\t * but resubmitting a non-staged change from before entering Staging Mode\n\t */\n\tstaged: boolean;\n}\n\n/**\n * Temporarily increase the stack limit while executing the provided action.\n * If a negative value is provided for `length`, no stack frames will be collected.\n * If Infinity is provided, all frames will be collected.\n *\n * ADO:4663 - add this to the common packages.\n *\n * @param action - action which returns an error\n * @param length - number of stack frames to collect, 50 if unspecified.\n * @returns the result of the action provided\n */\nexport function getLongStack<T>(action: () => T, length: number = 50): T {\n\t// TODO: better typing here\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment\n\tconst errorObj = Error as any;\n\tif (\n\t\t/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */\n\t\t// ?? is not logically equivalent when the first clause returns false.\n\t\t(\n\t\t\tObject.getOwnPropertyDescriptor(errorObj, \"stackTraceLimit\") ||\n\t\t\tObject.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), \"stackTraceLimit\")\n\t\t)?.writable !== true\n\t\t/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */\n\t) {\n\t\treturn action();\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\tconst originalStackTraceLimit = errorObj.stackTraceLimit;\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\terrorObj.stackTraceLimit = length;\n\t\treturn action();\n\t} finally {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\t\terrorObj.stackTraceLimit = originalStackTraceLimit;\n\t}\n}\n\n/**\n * Convert from local batch to outbound batch, including computing contentSizeInBytes.\n */\nexport function localBatchToOutboundBatch({\n\tstaged: _staged, // Peel this off the incoming batch, it's irrelevant (see Note below)\n\t...localBatch\n}: LocalBatch): OutboundBatch {\n\t// Note: the staged property might be misleading here, in case a pre-staging batch is resubmitted during staging mode.\n\t// It will be set to true, but the batch was not actually staged.\n\n\t// Shallow copy each message as we switch types\n\tconst outboundMessages = localBatch.messages.map<OutboundBatchMessage>(\n\t\t({ runtimeOp, ...message }) => ({\n\t\t\tcontents: serializeOp(runtimeOp),\n\t\t\t...message,\n\t\t}),\n\t);\n\tconst contentSizeInBytes = outboundMessages.reduce(\n\t\t(acc, message) => acc + (message.contents?.length ?? 0),\n\t\t0,\n\t);\n\n\t// Shallow copy the local batch, updating the messages to be outbound messages and adding contentSizeInBytes\n\tconst outboundBatch: OutboundBatch = {\n\t\t...localBatch,\n\t\tmessages: outboundMessages,\n\t\tcontentSizeInBytes,\n\t};\n\n\treturn outboundBatch;\n}\n\n/**\n * Estimated size of the stringification overhead for an op accumulated\n * from runtime to loader to the service.\n */\nconst opOverhead = 200;\n\n/**\n * Estimates the real size in bytes on the socket for a given batch. It assumes that\n * the envelope size (and the size of an empty op) is 200 bytes, taking into account\n * extra overhead from stringification.\n *\n * @remarks\n * Also content will be stringified, and that adds a lot of overhead due to a lot of escape characters.\n * Not taking it into account, as compression work should help there - compressed payload will be\n * initially stored as base64, and that requires only 2 extra escape characters.\n *\n * @param batch - the batch to inspect\n * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire\n */\nexport const estimateSocketSize = (batch: OutboundBatch): number => {\n\treturn batch.contentSizeInBytes + opOverhead * batch.messages.length;\n};\n\n/**\n * The Outbox collects messages submitted by the ContainerRuntime into a batch,\n * and then flushes the batch when requested.\n *\n * @remarks There are actually multiple independent batches (some are for a specific message type),\n * to support slight variation in semantics for each batch (e.g. support for rebasing or grouping).\n */\nexport class Outbox {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\tprivate readonly mainBatch: BatchManager;\n\tprivate readonly blobAttachBatch: BatchManager;\n\tprivate readonly idAllocationBatch: BatchManager;\n\tprivate batchRebasesToReport = 5;\n\tprivate rebasing = false;\n\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 3;\n\tprivate mismatchedOpsReported = 0;\n\n\tconstructor(private readonly params: IOutboxParameters) {\n\t\tthis.logger = createChildLogger({ logger: params.logger, namespace: \"Outbox\" });\n\n\t\tthis.mainBatch = new BatchManager({ canRebase: true });\n\t\tthis.blobAttachBatch = new BatchManager({ canRebase: true });\n\t\tthis.idAllocationBatch = new BatchManager({\n\t\t\tcanRebase: false,\n\t\t\tignoreBatchId: true,\n\t\t});\n\t}\n\n\tpublic get messageCount(): number {\n\t\treturn this.mainBatch.length + this.blobAttachBatch.length + this.idAllocationBatch.length;\n\t}\n\n\tpublic get mainBatchMessageCount(): number {\n\t\treturn this.mainBatch.length;\n\t}\n\n\tpublic get blobAttachBatchMessageCount(): number {\n\t\treturn this.blobAttachBatch.length;\n\t}\n\n\tpublic get idAllocationBatchMessageCount(): number {\n\t\treturn this.idAllocationBatch.length;\n\t}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.messageCount === 0;\n\t}\n\n\tpublic containsUserChanges(): boolean {\n\t\treturn (\n\t\t\tthis.mainBatch.containsUserChanges() || this.blobAttachBatch.containsUserChanges()\n\t\t\t// ID Allocation ops are not user changes\n\t\t);\n\t}\n\n\t/**\n\t * Detect whether batching has been interrupted by an incoming message being processed. In this case,\n\t * we will flush the accumulated messages to account for that (if allowed) and create a new batch with the new\n\t * message as the first message. If flushing partial batch is not enabled, we will throw (except for reentrant ops).\n\t * This would indicate we expected this case to be precluded by logic elsewhere.\n\t *\n\t * @remarks To detect batch interruption, we compare both the reference sequence number\n\t * (i.e. last message processed by DeltaManager) and the client sequence number of the\n\t * last message processed by the ContainerRuntime. In the absence of op reentrancy, this\n\t * pair will remain stable during a single JS turn during which the batch is being built up.\n\t */\n\tprivate maybeFlushPartialBatch(): void {\n\t\tconst mainBatchSeqNums = this.mainBatch.sequenceNumbers;\n\t\tconst blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;\n\t\tconst idAllocSeqNums = this.idAllocationBatch.sequenceNumbers;\n\t\tassert(\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums) &&\n\t\t\t\tsequenceNumbersMatch(mainBatchSeqNums, idAllocSeqNums),\n\t\t\t0x58d /* Reference sequence numbers from both batches must be in sync */,\n\t\t);\n\n\t\tconst currentSequenceNumbers = this.params.getCurrentSequenceNumbers();\n\n\t\tif (\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(idAllocSeqNums, currentSequenceNumbers)\n\t\t) {\n\t\t\t// The reference sequence numbers are stable, there is nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\t// Reference and/or Client sequence number will be advancing while processing this batch,\n\t\t// so we can't use this check to detect wrongdoing. But we will still log via telemetry.\n\t\t// This is rare, and the reentrancy will be handled during Flush.\n\t\tconst expectedDueToReentrancy = this.isContextReentrant();\n\n\t\tconst errorWrapper = new Lazy(() =>\n\t\t\tgetLongStack(() =>\n\t\t\t\tDataProcessingError.create(\n\t\t\t\t\t\"Sequence numbers advanced as if ops were processed while a batch is accumulating\",\n\t\t\t\t\t\"outboxSequenceNumberCoherencyCheck\",\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\t// Only log error if this is truly unexpected\n\t\t\t\t\tcategory:\n\t\t\t\t\t\texpectedDueToReentrancy || this.params.config.flushPartialBatches\n\t\t\t\t\t\t\t? \"generic\"\n\t\t\t\t\t\t\t: \"error\",\n\t\t\t\t\teventName: \"ReferenceSequenceNumberMismatch\",\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\texpectedDueToReentrancy,\n\t\t\t\t\t\tmainReferenceSequenceNumber: mainBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\t\tmainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\t\tblobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,\n\t\t\t\t\t\tblobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,\n\t\t\t\t\t\tcurrentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,\n\t\t\t\t\t\tcurrentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\terrorWrapper.value,\n\t\t\t);\n\t\t}\n\n\t\t// If we're configured to flush partial batches, do that now and return (don't throw)\n\t\tif (this.params.config.flushPartialBatches) {\n\t\t\tthis.flushAll();\n\t\t\treturn;\n\t\t}\n\n\t\t// If we are in a reentrant context, we know this can happen without causing any harm.\n\t\tif (expectedDueToReentrancy) {\n\t\t\treturn;\n\t\t}\n\n\t\tthrow errorWrapper.value;\n\t}\n\n\tpublic submit(message: LocalBatchMessage): void {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.mainBatch, message);\n\t}\n\n\tpublic submitBlobAttach(message: LocalBatchMessage): void {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.blobAttachBatch, message);\n\t}\n\n\tpublic submitIdAllocation(message: LocalBatchMessage): void {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.idAllocationBatch, message);\n\t}\n\n\tprivate addMessageToBatchManager(\n\t\tbatchManager: BatchManager,\n\t\tmessage: LocalBatchMessage,\n\t): void {\n\t\tbatchManager.push(\n\t\t\tmessage,\n\t\t\tthis.isContextReentrant(),\n\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t);\n\t}\n\n\t/**\n\t * Flush all the batches to the ordering service.\n\t * This method is expected to be called at the end of a batch.\n\t *\n\t * @throws If called from a reentrant context, or if the batch being flushed is too large.\n\t * @param resubmitInfo - Key information when flushing a resubmitted batch. Undefined means this is not resubmit.\n\t */\n\tpublic flush(resubmitInfo?: BatchResubmitInfo): void {\n\t\t// We have nothing to flush if all batchManagers are empty, and we we're not needing to resubmit an empty batch placeholder\n\t\tif (\n\t\t\tthis.idAllocationBatch.empty &&\n\t\t\tthis.blobAttachBatch.empty &&\n\t\t\tthis.mainBatch.empty &&\n\t\t\tresubmitInfo?.batchId === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\t!this.isContextReentrant(),\n\t\t\t0xb7b /* Flushing must not happen while incoming changes are being processed */,\n\t\t);\n\t\tthis.flushAll(resubmitInfo);\n\t}\n\n\tprivate flushAll(resubmitInfo?: BatchResubmitInfo): void {\n\t\tconst allBatchesEmpty =\n\t\t\tthis.idAllocationBatch.empty && this.blobAttachBatch.empty && this.mainBatch.empty;\n\t\tif (allBatchesEmpty) {\n\t\t\t// If we're resubmitting with a batchId and all batches are empty, we need to flush an empty batch.\n\t\t\t// Note that we currently resubmit one batch at a time, so on resubmit, 1 of the 2 batches will *always* be empty.\n\t\t\t// It's theoretically possible that we don't *need* to resubmit this empty batch, and in those cases, it'll safely be ignored\n\t\t\t// by the rest of the system, including remote clients.\n\t\t\t// In some cases we *must* resubmit the empty batch (to match up with a non-empty version tracked locally by a container fork), so we do it always.\n\t\t\tif (resubmitInfo?.batchId !== undefined) {\n\t\t\t\tthis.flushEmptyBatch(resubmitInfo.batchId, resubmitInfo.staged);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Don't use resubmittingBatchId for idAllocationBatch.\n\t\t// ID Allocation messages are not directly resubmitted so don't pass the resubmitInfo\n\t\tthis.flushInternal({\n\t\t\tbatchManager: this.idAllocationBatch,\n\t\t\t// Note: For now, we will never stage ID Allocation messages.\n\t\t\t// They won't contain personal info and no harm in extra allocations in case of discarding the staged changes\n\t\t});\n\t\tthis.flushInternal({\n\t\t\tbatchManager: this.blobAttachBatch,\n\t\t\tdisableGroupedBatching: true,\n\t\t\tresubmitInfo,\n\t\t});\n\t\tthis.flushInternal({\n\t\t\tbatchManager: this.mainBatch,\n\t\t\tresubmitInfo,\n\t\t});\n\t}\n\n\tprivate flushEmptyBatch(\n\t\tresubmittingBatchId: BatchId,\n\t\tresubmittingStagedBatch: boolean,\n\t): void {\n\t\tconst referenceSequenceNumber =\n\t\t\tthis.params.getCurrentSequenceNumbers().referenceSequenceNumber;\n\t\tassert(\n\t\t\treferenceSequenceNumber !== undefined,\n\t\t\t0xa01 /* reference sequence number should be defined */,\n\t\t);\n\t\tconst { outboundBatch, placeholderMessage } =\n\t\t\tthis.params.groupingManager.createEmptyGroupedBatch(\n\t\t\t\tresubmittingBatchId,\n\t\t\t\treferenceSequenceNumber,\n\t\t\t);\n\t\tlet clientSequenceNumber: number | undefined;\n\t\tif (this.params.shouldSend() && !resubmittingStagedBatch) {\n\t\t\tclientSequenceNumber = this.sendBatch(outboundBatch);\n\t\t}\n\n\t\t// Push the empty batch placeholder to the PendingStateManager\n\t\tthis.params.pendingStateManager.onFlushEmptyBatch(\n\t\t\tplaceholderMessage,\n\t\t\tclientSequenceNumber,\n\t\t\tresubmittingStagedBatch,\n\t\t);\n\t\treturn;\n\t}\n\n\tprivate flushInternal(params: {\n\t\tbatchManager: BatchManager;\n\t\tdisableGroupedBatching?: boolean;\n\t\tresubmitInfo?: BatchResubmitInfo; // undefined if not resubmitting\n\t}): void {\n\t\tconst { batchManager, disableGroupedBatching = false, resubmitInfo } = params;\n\t\tif (batchManager.empty) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst rawBatch = batchManager.popBatch(resubmitInfo?.batchId);\n\n\t\t// On resubmit we use the original batch's staged state, so these should match as well.\n\t\tconst staged = rawBatch.staged === true;\n\t\tassert(\n\t\t\tresubmitInfo === undefined || resubmitInfo.staged === staged,\n\t\t\t0xba3 /* Mismatch in staged state tracking */,\n\t\t);\n\n\t\tconst groupingEnabled =\n\t\t\t!disableGroupedBatching && this.params.groupingManager.groupedBatchingEnabled();\n\t\tif (\n\t\t\tbatchManager.options.canRebase &&\n\t\t\trawBatch.hasReentrantOps === true &&\n\t\t\tgroupingEnabled\n\t\t) {\n\t\t\tassert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);\n\t\t\t// If a batch contains reentrant ops (ops created as a result from processing another op)\n\t\t\t// it needs to be rebased so that we can ensure consistent reference sequence numbers\n\t\t\t// and eventual consistency at the DDS level.\n\t\t\t// Note: Since this is happening in the same turn the ops were originally created with,\n\t\t\t// and they haven't gone to PendingStateManager yet, we can just let them respect\n\t\t\t// ContainerRuntime.inStagingMode. So we do not plumb local 'staged' variable through here.\n\t\t\tthis.rebase(rawBatch, batchManager);\n\t\t\treturn;\n\t\t}\n\n\t\tlet clientSequenceNumber: number | undefined;\n\t\t// Did we disconnect? (i.e. is shouldSend false?)\n\t\t// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.\n\t\t// Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.\n\t\tif (this.params.shouldSend() && !staged) {\n\t\t\tconst virtualizedBatch = this.virtualizeBatch(rawBatch, groupingEnabled);\n\n\t\t\tclientSequenceNumber = this.sendBatch(virtualizedBatch);\n\t\t\tassert(\n\t\t\t\tclientSequenceNumber === undefined || clientSequenceNumber >= 0,\n\t\t\t\t0x9d2 /* unexpected negative clientSequenceNumber (empty batch should yield undefined) */,\n\t\t\t);\n\t\t}\n\n\t\tthis.params.pendingStateManager.onFlushBatch(\n\t\t\trawBatch.messages,\n\t\t\tclientSequenceNumber,\n\t\t\tstaged,\n\t\t\tbatchManager.options.ignoreBatchId,\n\t\t);\n\t}\n\n\t/**\n\t * Rebases a batch. All the ops in the batch are resubmitted to the runtime and\n\t * they will end up back in the same batch manager they were flushed from and subsequently flushed.\n\t *\n\t * @param rawBatch - the batch to be rebased\n\t */\n\tprivate rebase(rawBatch: LocalBatch, batchManager: BatchManager): void {\n\t\tassert(!this.rebasing, 0x6fb /* Reentrancy */);\n\t\tassert(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);\n\n\t\tthis.rebasing = true;\n\t\tconst squash = false;\n\t\tfor (const message of rawBatch.messages) {\n\t\t\tthis.params.reSubmit(\n\t\t\t\t{\n\t\t\t\t\truntimeOp: message.runtimeOp,\n\t\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\t\topMetadata: message.metadata,\n\t\t\t\t},\n\t\t\t\tsquash,\n\t\t\t);\n\t\t}\n\n\t\tif (this.batchRebasesToReport > 0) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"BatchRebase\",\n\t\t\t\t\tlength: rawBatch.messages.length,\n\t\t\t\t\treferenceSequenceNumber: rawBatch.referenceSequenceNumber,\n\t\t\t\t},\n\t\t\t\tnew UsageError(\"BatchRebase\"),\n\t\t\t);\n\t\t\tthis.batchRebasesToReport--;\n\t\t}\n\n\t\tthis.flushInternal({ batchManager });\n\t\tthis.rebasing = false;\n\t}\n\n\tprivate isContextReentrant(): boolean {\n\t\treturn this.params.opReentrancy() && !this.rebasing;\n\t}\n\n\t/**\n\t * As necessary and enabled, groups / compresses / chunks the given batch.\n\t *\n\t * @remarks If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.\n\t *\n\t * @param localBatch - Local Batch to be virtualized - i.e. transformed into an Outbound Batch\n\t * @param groupingEnabled - If true, Grouped batching is enabled.\n\t * @returns One of the following:\n\t * - (A) The original batch (Based on what's enabled)\n\t * - (B) A grouped batch (it's a singleton batch)\n\t * - (C) A compressed singleton batch\n\t * - (D) A singleton batch containing the last chunk.\n\t */\n\tprivate virtualizeBatch(localBatch: LocalBatch, groupingEnabled: boolean): OutboundBatch {\n\t\t// Shallow copy the local batch, updating the messages to be outbound messages\n\t\tconst originalBatch = localBatchToOutboundBatch(localBatch);\n\n\t\tconst originalOrGroupedBatch = groupingEnabled\n\t\t\t? this.params.groupingManager.groupBatch(originalBatch)\n\t\t\t: originalBatch;\n\n\t\tif (originalOrGroupedBatch.messages.length !== 1) {\n\t\t\t// Compression requires a single message, so return early otherwise.\n\t\t\treturn originalOrGroupedBatch;\n\t\t}\n\n\t\t// Regardless of whether we grouped or not, we now have a batch with a single message.\n\t\t// Now proceed to compress/chunk it if necessary.\n\t\tconst singletonBatch = originalOrGroupedBatch as OutboundSingletonBatch;\n\n\t\tif (\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes >\n\t\t\t\tsingletonBatch.contentSizeInBytes ||\n\t\t\tthis.params.submitBatchFn === undefined\n\t\t) {\n\t\t\t// Nothing to do if compression is disabled, unnecessary or unsupported.\n\t\t\treturn singletonBatch;\n\t\t}\n\n\t\tconst compressedBatch = this.params.compressor.compressBatch(singletonBatch);\n\n\t\tif (this.params.splitter.isBatchChunkingEnabled) {\n\t\t\treturn compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes\n\t\t\t\t? compressedBatch\n\t\t\t\t: this.params.splitter.splitSingletonBatchMessage(compressedBatch);\n\t\t}\n\n\t\t// We want to distinguish this \"BatchTooLarge\" case from the generic \"BatchTooLarge\" case in sendBatch\n\t\tif (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow this.makeBatchTooLargeError(compressedBatch, \"CompressionInsufficient\", {\n\t\t\t\tuncompressedSizeInBytes: singletonBatch.contentSizeInBytes,\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Sends the batch object to the container context to be sent over the wire.\n\t *\n\t * @param batch - batch to be sent\n\t * @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent\n\t */\n\tprivate sendBatch(batch: OutboundBatch): number | undefined {\n\t\tconst length = batch.messages.length;\n\t\tif (length === 0) {\n\t\t\treturn undefined; // Nothing submitted\n\t\t}\n\n\t\tconst socketSize = estimateSocketSize(batch);\n\t\tif (socketSize >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow this.makeBatchTooLargeError(batch, \"CannotSend\");\n\t\t}\n\n\t\tlet clientSequenceNumber: number;\n\t\tif (this.params.submitBatchFn === undefined) {\n\t\t\t// Legacy path - supporting old loader versions. Can be removed only when LTS moves above\n\t\t\t// version that has support for batches (submitBatchFn)\n\t\t\tassert(\n\t\t\t\tbatch.messages[0].compression === undefined,\n\t\t\t\t0x5a6 /* Compression should not have happened if the loader does not support it */,\n\t\t\t);\n\n\t\t\tclientSequenceNumber = this.params.legacySendBatchFn(batch);\n\t\t} else {\n\t\t\tassert(batch.referenceSequenceNumber !== undefined, 0x58e /* Batch must not be empty */);\n\t\t\tclientSequenceNumber = this.params.submitBatchFn(\n\t\t\t\tbatch.messages.map<IBatchMessage>((message) => ({\n\t\t\t\t\tcontents: message.contents,\n\t\t\t\t\tmetadata: message.metadata,\n\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t\t})),\n\t\t\t\tbatch.referenceSequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\t// Convert from clientSequenceNumber of last message in the batch to clientSequenceNumber of first message.\n\t\tclientSequenceNumber -= length - 1;\n\t\tassert(clientSequenceNumber >= 0, 0x3d0 /* clientSequenceNumber can't be negative */);\n\t\treturn clientSequenceNumber;\n\t}\n\n\tprivate makeBatchTooLargeError(\n\t\tbatch: OutboundBatch,\n\t\tcodepath: string,\n\t\tmoreDetails?: ITelemetryBaseProperties,\n\t): IFluidErrorBase {\n\t\treturn DataProcessingError.create(\n\t\t\t\"BatchTooLarge\",\n\t\t\tcodepath,\n\t\t\t/* sequencedMessage */ undefined,\n\t\t\t{\n\t\t\t\terrorDetails: {\n\t\t\t\t\topCount: batch.messages.length,\n\t\t\t\t\tcontentSizeInBytes: batch.contentSizeInBytes,\n\t\t\t\t\tsocketSize: estimateSocketSize(batch),\n\t\t\t\t\tmaxBatchSizeInBytes: this.params.config.maxBatchSizeInBytes,\n\t\t\t\t\tgroupedBatchingEnabled: this.params.groupingManager.groupedBatchingEnabled(),\n\t\t\t\t\tcompressionOptions: JSON.stringify(this.params.config.compressionOptions),\n\t\t\t\t\tchunkingEnabled: this.params.splitter.isBatchChunkingEnabled,\n\t\t\t\t\tchunkSizeInBytes: this.params.splitter.chunkSizeInBytes,\n\t\t\t\t\t...moreDetails,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.\n\t */\n\tpublic getBatchCheckpoints(): {\n\t\tmainBatch: IBatchCheckpoint;\n\t\tidAllocationBatch: IBatchCheckpoint;\n\t\tblobAttachBatch: IBatchCheckpoint;\n\t} {\n\t\t// This variable is declared with a specific type so that we have a standard import of the IBatchCheckpoint type.\n\t\t// When the type is inferred, the generated .d.ts uses a dynamic import which doesn't resolve.\n\t\tconst mainBatch: IBatchCheckpoint = this.mainBatch.checkpoint();\n\t\treturn {\n\t\t\tmainBatch,\n\t\t\tidAllocationBatch: this.idAllocationBatch.checkpoint(),\n\t\t\tblobAttachBatch: this.blobAttachBatch.checkpoint(),\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/opLifecycle/outbox.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IBatchMessage } from \"@fluidframework/container-definitions/internal\";\nimport type {\n\tITelemetryBaseLogger,\n\tITelemetryBaseProperties,\n} from \"@fluidframework/core-interfaces\";\nimport { assert, Lazy } from \"@fluidframework/core-utils/internal\";\nimport {\n\tDataProcessingError,\n\tUsageError,\n\tcreateChildLogger,\n\ttype IFluidErrorBase,\n\ttype ITelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { ICompressionRuntimeOptions } from \"../compressionDefinitions.js\";\nimport type {\n\tPendingMessageResubmitData,\n\tPendingStateManager,\n} from \"../pendingStateManager.js\";\n\nimport {\n\tBatchManager,\n\ttype BatchSequenceNumbers,\n\tsequenceNumbersMatch,\n\ttype BatchId,\n\taddBatchMetadata,\n} from \"./batchManager.js\";\nimport type {\n\tLocalBatchMessage,\n\tIBatchCheckpoint,\n\tOutboundBatchMessage,\n\tOutboundSingletonBatch,\n\tLocalBatch,\n\tOutboundBatch,\n} from \"./definitions.js\";\nimport type { OpCompressor } from \"./opCompressor.js\";\nimport type { OpGroupingManager } from \"./opGroupingManager.js\";\nimport { serializeOp } from \"./opSerialization.js\";\nimport type { OpSplitter } from \"./opSplitter.js\";\n\nexport interface IOutboxConfig {\n\treadonly compressionOptions: ICompressionRuntimeOptions;\n\t/**\n\t * The maximum size of a batch that we can send over the wire.\n\t */\n\treadonly maxBatchSizeInBytes: number;\n}\n\nexport interface IOutboxParameters {\n\treadonly shouldSend: () => boolean;\n\treadonly pendingStateManager: PendingStateManager;\n\treadonly submitBatchFn:\n\t\t| ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)\n\t\t| undefined;\n\treadonly legacySendBatchFn: (batch: OutboundBatch) => number;\n\treadonly config: IOutboxConfig;\n\treadonly compressor: OpCompressor;\n\treadonly splitter: OpSplitter;\n\treadonly logger: ITelemetryBaseLogger;\n\treadonly groupingManager: OpGroupingManager;\n\treadonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;\n\treadonly reSubmit: (message: PendingMessageResubmitData, squash: boolean) => void;\n\treadonly opReentrancy: () => boolean;\n\t/**\n\t * JIT callback to generate an ID allocation op at flush time.\n\t * Called after rebase (if any), so the returned message has the correct refSeq.\n\t *\n\t * @returns A LocalBatchMessage for the ID allocation op, or undefined if no IDs need allocating.\n\t */\n\treadonly generateIdAllocationOp: () => LocalBatchMessage | undefined;\n}\n\n/**\n * Info needed to correctly resubmit a batch\n */\nexport interface BatchResubmitInfo {\n\t/**\n\t * If defined, indicates the Batch ID of the batch being resubmitted.\n\t * This must be preserved on the new batch about to be submitted so they can be correlated/deduped in case both are sent.\n\t */\n\tbatchId?: string;\n\t/**\n\t * Indicates whether or not this batch is \"staged\", meaning it should not be sent to the ordering service yet\n\t * This is important on resubmit because we may be in Staging Mode for new changes,\n\t * but resubmitting a non-staged change from before entering Staging Mode\n\t */\n\tstaged: boolean;\n}\n\n/**\n * Temporarily increase the stack limit while executing the provided action.\n * If a negative value is provided for `length`, no stack frames will be collected.\n * If Infinity is provided, all frames will be collected.\n *\n * ADO:4663 - add this to the common packages.\n *\n * @param action - action which returns an error\n * @param length - number of stack frames to collect, 50 if unspecified.\n * @returns the result of the action provided\n */\nexport function getLongStack<T>(action: () => T, length: number = 50): T {\n\t// TODO: better typing here\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment\n\tconst errorObj = Error as any;\n\tif (\n\t\t/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */\n\t\t// ?? is not logically equivalent when the first clause returns false.\n\t\t(\n\t\t\tObject.getOwnPropertyDescriptor(errorObj, \"stackTraceLimit\") ||\n\t\t\tObject.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), \"stackTraceLimit\")\n\t\t)?.writable !== true\n\t\t/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */\n\t) {\n\t\treturn action();\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\tconst originalStackTraceLimit = errorObj.stackTraceLimit;\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\terrorObj.stackTraceLimit = length;\n\t\treturn action();\n\t} finally {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment\n\t\terrorObj.stackTraceLimit = originalStackTraceLimit;\n\t}\n}\n\n/**\n * Convert from local batch to outbound batch, including computing contentSizeInBytes.\n */\nexport function localBatchToOutboundBatch({\n\tstaged: _staged, // Peel this off the incoming batch, it's irrelevant (see Note below)\n\t...localBatch\n}: LocalBatch): OutboundBatch {\n\t// Note: the staged property might be misleading here, in case a pre-staging batch is resubmitted during staging mode.\n\t// It will be set to true, but the batch was not actually staged.\n\n\t// Shallow copy each message as we switch types\n\tconst outboundMessages = localBatch.messages.map<OutboundBatchMessage>(\n\t\t({ runtimeOp, ...message }) => ({\n\t\t\tcontents: serializeOp(runtimeOp).content,\n\t\t\t...message,\n\t\t}),\n\t);\n\tconst contentSizeInBytes = outboundMessages.reduce(\n\t\t(acc, message) => acc + (message.contents?.length ?? 0),\n\t\t0,\n\t);\n\n\t// Shallow copy the local batch, updating the messages to be outbound messages and adding contentSizeInBytes\n\tconst outboundBatch: OutboundBatch = {\n\t\t...localBatch,\n\t\tmessages: outboundMessages,\n\t\tcontentSizeInBytes,\n\t};\n\n\treturn outboundBatch;\n}\n\n/**\n * Estimated size of the stringification overhead for an op accumulated\n * from runtime to loader to the service.\n */\nconst opOverhead = 200;\n\n/**\n * Estimates the real size in bytes on the socket for a given batch. It assumes that\n * the envelope size (and the size of an empty op) is 200 bytes, taking into account\n * extra overhead from stringification.\n *\n * @remarks\n * Also content will be stringified, and that adds a lot of overhead due to a lot of escape characters.\n * Not taking it into account, as compression work should help there - compressed payload will be\n * initially stored as base64, and that requires only 2 extra escape characters.\n *\n * @param batch - the batch to inspect\n * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire\n */\nexport const estimateSocketSize = (batch: OutboundBatch): number => {\n\treturn batch.contentSizeInBytes + opOverhead * batch.messages.length;\n};\n\n/**\n * The Outbox collects messages submitted by the ContainerRuntime into a batch,\n * and then flushes the batch when requested.\n *\n * @remarks There are actually multiple independent batches (some are for a specific message type),\n * to support slight variation in semantics for each batch (e.g. support for rebasing or grouping).\n */\nexport class Outbox {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\tprivate readonly mainBatch: BatchManager;\n\tprivate readonly blobAttachBatch: BatchManager;\n\tprivate batchRebasesToReport = 5;\n\tprivate rebasing = false;\n\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 3;\n\tprivate mismatchedOpsReported = 0;\n\n\tconstructor(private readonly params: IOutboxParameters) {\n\t\tthis.logger = createChildLogger({ logger: params.logger, namespace: \"Outbox\" });\n\n\t\tthis.mainBatch = new BatchManager({ disableGroupedBatching: false });\n\t\tthis.blobAttachBatch = new BatchManager({ disableGroupedBatching: true });\n\t}\n\n\tpublic get messageCount(): number {\n\t\treturn this.mainBatch.length + this.blobAttachBatch.length;\n\t}\n\n\tpublic get mainBatchMessageCount(): number {\n\t\treturn this.mainBatch.length;\n\t}\n\n\tpublic get blobAttachBatchMessageCount(): number {\n\t\treturn this.blobAttachBatch.length;\n\t}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.messageCount === 0;\n\t}\n\n\tpublic containsUserChanges(): boolean {\n\t\treturn this.mainBatch.containsUserChanges() || this.blobAttachBatch.containsUserChanges();\n\t}\n\n\t/**\n\t * Detect whether batching has been interrupted by an incoming message being processed. In this case,\n\t * we will flush the accumulated messages to account for that (if allowed) and create a new batch with the new\n\t * message as the first message. If flushing partial batch is not enabled, we will throw (except for reentrant ops).\n\t * This would indicate we expected this case to be precluded by logic elsewhere.\n\t *\n\t * @remarks To detect batch interruption, we compare both the reference sequence number\n\t * (i.e. last message processed by DeltaManager) and the client sequence number of the\n\t * last message processed by the ContainerRuntime. In the absence of op reentrancy, this\n\t * pair will remain stable during a single JS turn during which the batch is being built up.\n\t */\n\tprivate outboxSequenceNumberCoherencyCheck(): void {\n\t\tconst mainBatchSeqNums = this.mainBatch.sequenceNumbers;\n\t\tconst blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;\n\t\tassert(\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums),\n\t\t\t0x58d /* Reference sequence numbers from both batches must be in sync */,\n\t\t);\n\n\t\tconst currentSequenceNumbers = this.params.getCurrentSequenceNumbers();\n\n\t\tif (\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers)\n\t\t) {\n\t\t\t// The reference sequence numbers are stable, there is nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\t// Reference and/or Client sequence number will be advancing while processing this batch,\n\t\t// so we can't use this check to detect wrongdoing. But we will still log via telemetry.\n\t\t// This is rare, and the reentrancy will be handled during Flush.\n\t\tconst expectedDueToReentrancy = this.isContextReentrant();\n\n\t\tconst errorWrapper = new Lazy(() =>\n\t\t\tgetLongStack(() =>\n\t\t\t\tDataProcessingError.create(\n\t\t\t\t\t\"Sequence numbers advanced as if ops were processed while a batch is accumulating\",\n\t\t\t\t\t\"outboxSequenceNumberCoherencyCheck\",\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\t// Only log error if this is truly unexpected\n\t\t\t\t\tcategory: expectedDueToReentrancy ? \"generic\" : \"error\",\n\t\t\t\t\teventName: \"ReferenceSequenceNumberMismatch\",\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\texpectedDueToReentrancy,\n\t\t\t\t\t\tmainReferenceSequenceNumber: mainBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\t\tmainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\t\tblobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,\n\t\t\t\t\t\tblobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,\n\t\t\t\t\t\tcurrentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,\n\t\t\t\t\t\tcurrentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\terrorWrapper.value,\n\t\t\t);\n\t\t}\n\n\t\t// If we are in a reentrant context, we know this can happen without causing any harm.\n\t\tif (expectedDueToReentrancy) {\n\t\t\treturn;\n\t\t}\n\n\t\tthrow errorWrapper.value;\n\t}\n\n\tpublic submit(message: LocalBatchMessage): void {\n\t\tthis.outboxSequenceNumberCoherencyCheck();\n\n\t\tthis.addMessageToBatchManager(this.mainBatch, message);\n\t}\n\n\tpublic submitBlobAttach(message: LocalBatchMessage): void {\n\t\tthis.outboxSequenceNumberCoherencyCheck();\n\n\t\tthis.addMessageToBatchManager(this.blobAttachBatch, message);\n\t}\n\n\tprivate addMessageToBatchManager(\n\t\tbatchManager: BatchManager,\n\t\tmessage: LocalBatchMessage,\n\t): void {\n\t\tbatchManager.push(\n\t\t\tmessage,\n\t\t\tthis.isContextReentrant(),\n\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t);\n\t}\n\n\t/**\n\t * Flush all the batches to the ordering service.\n\t * This method is expected to be called at the end of a batch.\n\t *\n\t * @throws If called from a reentrant context, or if the batch being flushed is too large.\n\t * @param resubmitInfo - Key information when flushing a resubmitted batch. Undefined means this is not resubmit.\n\t */\n\tpublic flush(resubmitInfo?: BatchResubmitInfo): void {\n\t\t// We have nothing to flush if all batchManagers are empty, and we we're not needing to resubmit an empty batch placeholder\n\t\tif (\n\t\t\tthis.blobAttachBatch.empty &&\n\t\t\tthis.mainBatch.empty &&\n\t\t\tresubmitInfo?.batchId === undefined\n\t\t) {\n\t\t\t// Note that it's possible that there are unfinalized ranges in the ID Compressor,\n\t\t\t// but there's no urgency to flush those if they're not referenced in any messages.\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\t!this.isContextReentrant(),\n\t\t\t0xb7b /* Flushing must not happen while incoming changes are being processed */,\n\t\t);\n\t\tthis.flushAll(resubmitInfo);\n\t}\n\n\tprivate flushAll(resubmitInfo?: BatchResubmitInfo): void {\n\t\tconst allBatchesEmpty = this.blobAttachBatch.empty && this.mainBatch.empty;\n\t\tif (allBatchesEmpty) {\n\t\t\t// If we're resubmitting with a batchId and all batches are empty, we need to flush an empty batch.\n\t\t\t// Note that we currently resubmit one batch at a time, so on resubmit, 1 of the 2 batches will *always* be empty.\n\t\t\t// It's theoretically possible that we don't *need* to resubmit this empty batch, and in those cases, it'll safely be ignored\n\t\t\t// by the rest of the system, including remote clients.\n\t\t\t// In some cases we *must* resubmit the empty batch (to match up with a non-empty version tracked locally by a container fork), so we do it always.\n\t\t\tif (resubmitInfo?.batchId !== undefined) {\n\t\t\t\tthis.flushEmptyBatch(resubmitInfo.batchId, resubmitInfo.staged);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.flushInternal(this.blobAttachBatch, resubmitInfo);\n\t\tthis.flushInternal(this.mainBatch, resubmitInfo);\n\t}\n\n\tprivate flushEmptyBatch(\n\t\tresubmittingBatchId: BatchId,\n\t\tresubmittingStagedBatch: boolean,\n\t): void {\n\t\tconst referenceSequenceNumber =\n\t\t\tthis.params.getCurrentSequenceNumbers().referenceSequenceNumber;\n\t\tassert(\n\t\t\treferenceSequenceNumber !== undefined,\n\t\t\t0xa01 /* reference sequence number should be defined */,\n\t\t);\n\t\tconst { outboundBatch, placeholderMessage } =\n\t\t\tthis.params.groupingManager.createEmptyGroupedBatch(\n\t\t\t\tresubmittingBatchId,\n\t\t\t\treferenceSequenceNumber,\n\t\t\t);\n\t\tlet clientSequenceNumber: number | undefined;\n\t\tif (this.params.shouldSend() && !resubmittingStagedBatch) {\n\t\t\tclientSequenceNumber = this.sendBatch(outboundBatch);\n\t\t}\n\n\t\t// Push the empty batch placeholder to the PendingStateManager\n\t\tthis.params.pendingStateManager.onFlushEmptyBatch(\n\t\t\tplaceholderMessage,\n\t\t\tclientSequenceNumber,\n\t\t\tresubmittingStagedBatch,\n\t\t);\n\t\treturn;\n\t}\n\n\tprivate flushInternal(\n\t\tbatchManager: BatchManager,\n\t\tresubmitInfo?: BatchResubmitInfo, // undefined if not resubmitting\n\t): void {\n\t\tif (batchManager.empty) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet rawBatch = batchManager.popBatch();\n\n\t\t// On resubmit we use the original batch's staged state, so these should match as well.\n\t\tconst staged = rawBatch.staged === true;\n\t\tassert(\n\t\t\tresubmitInfo === undefined || resubmitInfo.staged === staged,\n\t\t\t0xba3 /* Mismatch in staged state tracking */,\n\t\t);\n\n\t\tconst groupingEnabled =\n\t\t\t!batchManager.options.disableGroupedBatching &&\n\t\t\tthis.params.groupingManager.groupedBatchingEnabled();\n\t\tif (rawBatch.hasReentrantOps === true) {\n\t\t\tassert(\n\t\t\t\tresubmitInfo === undefined,\n\t\t\t\t0xcf2 /* Re-submitting a batch with reentrant ops is not supported */,\n\t\t\t);\n\t\t\tassert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);\n\t\t\t// Rebase the current batch (resubmit the ops one-by-one) and then reinvoke flushInternal.\n\t\t\t// If a batch contains reentrant ops (ops created as a result from processing another op)\n\t\t\t// it needs to be rebased so that we can ensure consistent reference sequence numbers\n\t\t\t// and eventual consistency at the DDS level.\n\t\t\t// Note: Since this is happening in the same turn the ops were originally created with,\n\t\t\t// and they haven't gone to PendingStateManager yet, we can just let them respect\n\t\t\t// ContainerRuntime.inStagingMode. So we do not plumb local 'staged' variable through here.\n\t\t\tthis.rebase(rawBatch, batchManager);\n\t\t\treturn;\n\t\t}\n\n\t\t// Did we disconnect? (i.e. is shouldSend false?)\n\t\t// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.\n\t\t// Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.\n\t\tconst shouldSendNow = this.params.shouldSend() && !staged;\n\t\tlet clientSequenceNumber: number | undefined;\n\t\tif (shouldSendNow) {\n\t\t\t// Generate ID Allocation op just-in-time, after rebase (if any), and before addBatchMetadata,\n\t\t\t// so that the prepended idAllocMsg is correctly marked as the first op in the batch.\n\t\t\t// This ensures the refSeq is correct (matching the rest of the batch) and that\n\t\t\t// ID ranges aren't lost during rebase (since reSubmit drops IdAllocation ops).\n\t\t\t// Only generate for non-staged batches — ID alloc ops are always non-staged.\n\t\t\tconst idAllocMsg = this.params.generateIdAllocationOp();\n\t\t\tif (idAllocMsg !== undefined) {\n\t\t\t\trawBatch = { ...rawBatch, messages: [idAllocMsg, ...rawBatch.messages] };\n\t\t\t}\n\t\t\taddBatchMetadata(rawBatch, resubmitInfo?.batchId);\n\t\t\tconst virtualizedBatch = this.virtualizeBatch(rawBatch, groupingEnabled);\n\n\t\t\tclientSequenceNumber = this.sendBatch(virtualizedBatch);\n\t\t\tassert(\n\t\t\t\tclientSequenceNumber === undefined || clientSequenceNumber >= 0,\n\t\t\t\t0x9d2 /* unexpected negative clientSequenceNumber (empty batch should yield undefined) */,\n\t\t\t);\n\t\t} else {\n\t\t\taddBatchMetadata(rawBatch, resubmitInfo?.batchId);\n\t\t}\n\n\t\tthis.params.pendingStateManager.onFlushBatch(\n\t\t\trawBatch.messages,\n\t\t\tclientSequenceNumber,\n\t\t\tstaged,\n\t\t);\n\t}\n\n\t/**\n\t * Rebases a batch. All the ops in the batch are resubmitted to the runtime and\n\t * they will end up back in the same batch manager they were flushed from and subsequently flushed.\n\t *\n\t * @param rawBatch - the batch to be rebased\n\t */\n\tprivate rebase(rawBatch: LocalBatch, batchManager: BatchManager): void {\n\t\tassert(!this.rebasing, 0x6fb /* Reentrancy */);\n\n\t\tthis.rebasing = true;\n\t\tconst squash = false;\n\t\tfor (const message of rawBatch.messages) {\n\t\t\tthis.params.reSubmit(\n\t\t\t\t{\n\t\t\t\t\truntimeOp: message.runtimeOp,\n\t\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\t\topMetadata: message.metadata,\n\t\t\t\t},\n\t\t\t\tsquash,\n\t\t\t);\n\t\t}\n\n\t\tif (this.batchRebasesToReport > 0) {\n\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"BatchRebase\",\n\t\t\t\t\tlength: rawBatch.messages.length,\n\t\t\t\t\treferenceSequenceNumber: rawBatch.referenceSequenceNumber,\n\t\t\t\t},\n\t\t\t\tnew UsageError(\"BatchRebase\"),\n\t\t\t);\n\t\t\tthis.batchRebasesToReport--;\n\t\t}\n\n\t\tthis.flushInternal(batchManager);\n\t\tthis.rebasing = false;\n\t}\n\n\tprivate isContextReentrant(): boolean {\n\t\treturn this.params.opReentrancy() && !this.rebasing;\n\t}\n\n\t/**\n\t * As necessary and enabled, groups / compresses / chunks the given batch.\n\t *\n\t * @remarks If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.\n\t *\n\t * @param localBatch - Local Batch to be virtualized - i.e. transformed into an Outbound Batch\n\t * @param groupingEnabled - If true, Grouped batching is enabled.\n\t * @returns One of the following:\n\t * - (A) The original batch (Based on what's enabled)\n\t * - (B) A grouped batch (it's a singleton batch)\n\t * - (C) A compressed singleton batch\n\t * - (D) A singleton batch containing the last chunk.\n\t */\n\tprivate virtualizeBatch(localBatch: LocalBatch, groupingEnabled: boolean): OutboundBatch {\n\t\t// Shallow copy the local batch, updating the messages to be outbound messages\n\t\tconst originalBatch = localBatchToOutboundBatch(localBatch);\n\n\t\tconst originalOrGroupedBatch = groupingEnabled\n\t\t\t? this.params.groupingManager.groupBatch(originalBatch)\n\t\t\t: originalBatch;\n\n\t\tif (originalOrGroupedBatch.messages.length !== 1) {\n\t\t\t// Compression requires a single message, so return early otherwise.\n\t\t\treturn originalOrGroupedBatch;\n\t\t}\n\n\t\t// Regardless of whether we grouped or not, we now have a batch with a single message.\n\t\t// Now proceed to compress/chunk it if necessary.\n\t\tconst singletonBatch = originalOrGroupedBatch as OutboundSingletonBatch;\n\n\t\tif (\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes >\n\t\t\t\tsingletonBatch.contentSizeInBytes ||\n\t\t\tthis.params.submitBatchFn === undefined\n\t\t) {\n\t\t\t// Nothing to do if compression is disabled, unnecessary or unsupported.\n\t\t\treturn singletonBatch;\n\t\t}\n\n\t\tconst compressedBatch = this.params.compressor.compressBatch(singletonBatch);\n\n\t\tif (this.params.splitter.isBatchChunkingEnabled) {\n\t\t\treturn compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes\n\t\t\t\t? compressedBatch\n\t\t\t\t: this.params.splitter.splitSingletonBatchMessage(compressedBatch);\n\t\t}\n\n\t\t// We want to distinguish this \"BatchTooLarge\" case from the generic \"BatchTooLarge\" case in sendBatch\n\t\tif (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow this.makeBatchTooLargeError(compressedBatch, \"CompressionInsufficient\", {\n\t\t\t\tuncompressedSizeInBytes: singletonBatch.contentSizeInBytes,\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Sends the batch object to the container context to be sent over the wire.\n\t *\n\t * @param batch - batch to be sent\n\t * @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent\n\t */\n\tprivate sendBatch(batch: OutboundBatch): number | undefined {\n\t\tconst length = batch.messages.length;\n\t\tif (length === 0) {\n\t\t\treturn undefined; // Nothing submitted\n\t\t}\n\n\t\tconst socketSize = estimateSocketSize(batch);\n\t\tif (socketSize >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow this.makeBatchTooLargeError(batch, \"CannotSend\");\n\t\t}\n\n\t\tlet clientSequenceNumber: number;\n\t\tif (this.params.submitBatchFn === undefined) {\n\t\t\t// Legacy path - supporting old loader versions. Can be removed only when LTS moves above\n\t\t\t// version that has support for batches (submitBatchFn)\n\t\t\tassert(\n\t\t\t\tbatch.messages[0].compression === undefined,\n\t\t\t\t0x5a6 /* Compression should not have happened if the loader does not support it */,\n\t\t\t);\n\n\t\t\tclientSequenceNumber = this.params.legacySendBatchFn(batch);\n\t\t} else {\n\t\t\tassert(batch.referenceSequenceNumber !== undefined, 0x58e /* Batch must not be empty */);\n\t\t\tclientSequenceNumber = this.params.submitBatchFn(\n\t\t\t\tbatch.messages.map<IBatchMessage>((message) => ({\n\t\t\t\t\tcontents: message.contents,\n\t\t\t\t\tmetadata: message.metadata,\n\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t\t})),\n\t\t\t\tbatch.referenceSequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\t// Convert from clientSequenceNumber of last message in the batch to clientSequenceNumber of first message.\n\t\tclientSequenceNumber -= length - 1;\n\t\tassert(clientSequenceNumber >= 0, 0x3d0 /* clientSequenceNumber can't be negative */);\n\t\treturn clientSequenceNumber;\n\t}\n\n\tprivate makeBatchTooLargeError(\n\t\tbatch: OutboundBatch,\n\t\tcodepath: string,\n\t\tmoreDetails?: ITelemetryBaseProperties,\n\t): IFluidErrorBase {\n\t\treturn DataProcessingError.create(\n\t\t\t\"BatchTooLarge\",\n\t\t\tcodepath,\n\t\t\t/* sequencedMessage */ undefined,\n\t\t\t{\n\t\t\t\terrorDetails: {\n\t\t\t\t\topCount: batch.messages.length,\n\t\t\t\t\tcontentSizeInBytes: batch.contentSizeInBytes,\n\t\t\t\t\tsocketSize: estimateSocketSize(batch),\n\t\t\t\t\tmaxBatchSizeInBytes: this.params.config.maxBatchSizeInBytes,\n\t\t\t\t\tgroupedBatchingEnabled: this.params.groupingManager.groupedBatchingEnabled(),\n\t\t\t\t\tcompressionOptions: JSON.stringify(this.params.config.compressionOptions),\n\t\t\t\t\tchunkingEnabled: this.params.splitter.isBatchChunkingEnabled,\n\t\t\t\t\tchunkSizeInBytes: this.params.splitter.chunkSizeInBytes,\n\t\t\t\t\t...moreDetails,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.\n\t */\n\tpublic getBatchCheckpoints(): {\n\t\tmainBatch: IBatchCheckpoint;\n\t\tblobAttachBatch: IBatchCheckpoint;\n\t} {\n\t\t// This variable is declared with a specific type so that we have a standard import of the IBatchCheckpoint type.\n\t\t// When the type is inferred, the generated .d.ts uses a dynamic import which doesn't resolve.\n\t\tconst mainBatch: IBatchCheckpoint = this.mainBatch.checkpoint();\n\t\treturn {\n\t\t\tmainBatch,\n\t\t\tblobAttachBatch: this.blobAttachBatch.checkpoint(),\n\t\t};\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-runtime";
8
- export declare const pkgVersion = "2.91.0";
8
+ export declare const pkgVersion = "2.93.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/container-runtime";
11
- exports.pkgVersion = "2.91.0";
11
+ exports.pkgVersion = "2.93.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.91.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.93.0\";\n"]}
@@ -56,10 +56,6 @@ export interface IPendingMessage {
56
56
  * length of the batch (how many runtime messages here)
57
57
  */
58
58
  length: number;
59
- /**
60
- * If true, don't compare batchID of incoming batches to this. e.g. ID Allocation Batch IDs should be ignored
61
- */
62
- ignoreBatchId?: boolean;
63
59
  /**
64
60
  * If true, this batch is staged and should not actually be submitted on replayPendingStates.
65
61
  */
@@ -158,7 +154,9 @@ export declare class PendingStateManager implements IDisposable {
158
154
  * @returns A boolean indicating whether there are messages or not.
159
155
  */
160
156
  hasPendingMessages(): boolean;
161
- getLocalState(snapshotSequenceNumber?: number): IPendingLocalState;
157
+ getLocalState(snapshotSequenceNumber?: number): {
158
+ pending: IPendingLocalState;
159
+ };
162
160
  private readonly logger;
163
161
  constructor(stateHandler: IRuntimeStateHandler, stashedLocalState: IPendingLocalState | undefined, logger: ITelemetryBaseLogger);
164
162
  get disposed(): boolean;
@@ -175,9 +173,8 @@ export declare class PendingStateManager implements IDisposable {
175
173
  * @param clientSequenceNumber - The CSN of the first message in the batch,
176
174
  * or undefined if the batch was not yet sent (e.g. by the time we flushed we lost the connection)
177
175
  * @param staged - Indicates whether batch is staged (not to be submitted while runtime is in Staging Mode)
178
- * @param ignoreBatchId - Whether to ignore the batchId in the batchStartInfo
179
176
  */
180
- onFlushBatch(batch: LocalBatchMessage[] | [LocalEmptyBatchPlaceholder], clientSequenceNumber: number | undefined, staged: boolean, ignoreBatchId?: boolean): void;
177
+ onFlushBatch(batch: LocalBatchMessage[] | [LocalEmptyBatchPlaceholder], clientSequenceNumber: number | undefined, staged: boolean): void;
181
178
  /**
182
179
  * Applies stashed ops at their reference sequence number so they are ready to be ACKed or resubmitted
183
180
  * @param seqNum - Sequence number at which to apply ops. Will apply all ops if seqNum is undefined.
@@ -229,14 +226,16 @@ export declare class PendingStateManager implements IDisposable {
229
226
  * Called when the Container's connection state changes. If the Container gets connected, it replays all the pending
230
227
  * states in its queue. This includes triggering resubmission of unacked ops.
231
228
  * ! Note: successfully resubmitting an op that has been successfully sequenced is not possible due to checks in the ConnectionStateHandler (Loader layer)
229
+ *
230
+ * @returns The unique batch infos for all batches that were replayed.
232
231
  */
233
- replayPendingStates(options?: ReplayPendingStateOptions): void;
232
+ replayPendingStates(options?: ReplayPendingStateOptions): IPendingMessage["batchInfo"][];
234
233
  /**
235
234
  * Pops all staged batches, invoking the callback on each constituent op in order (LIFO)
236
235
  */
237
236
  popStagedBatches(callback: (stagedMessage: IPendingMessage & {
238
237
  runtimeOp: LocalContainerRuntimeMessage;
239
- }) => void): void;
238
+ }) => void): IPendingMessage["batchInfo"][];
240
239
  }
241
240
  export {};
242
241
  //# sourceMappingURL=pendingStateManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pendingStateManager.d.ts","sourceRoot":"","sources":["../src/pendingStateManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pendingStateManager.d.ts","sourceRoot":"","sources":["../src/pendingStateManager.ts"],"names":[],"mappings":"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"}