@@ -70,6 +70,23 @@ export interface IOutboxParameters {
70
70
readonly opReentrancy : ( ) => boolean ;
71
71
}
72
72
73
+ /**
74
+ * Info needed to correctly resubmit a batch
75
+ */
76
+ export interface BatchResubmitInfo {
77
+ /**
78
+ * If defined, indicates the Batch ID of the batch being resubmitted.
79
+ * This must be preserved on the new batch about to be submitted so they can be correlated/deduped in case both are sent.
80
+ */
81
+ batchId ?: string ;
82
+ /**
83
+ * Indicates whether or not this batch is "staged", meaning it should not be sent to the ordering service yet
84
+ * This is important on resubmit because we may be in Staging Mode for new changes,
85
+ * but resubmitting a non-staged change from before entering Staging Mode
86
+ */
87
+ staged : boolean ;
88
+ }
89
+
73
90
/**
74
91
* Temporarily increase the stack limit while executing the provided action.
75
92
* If a negative value is provided for `length`, no stack frames will be collected.
@@ -335,37 +352,33 @@ export class Outbox {
335
352
* This method is expected to be called at the end of a batch.
336
353
*
337
354
* @throws If called from a reentrant context, or if the batch being flushed is too large.
338
- * @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
339
- * with the given Batch ID, which must be preserved
340
- * @param resubmittingStagedBatch - If defined, indicates this is a resubmission of a batch that is staged,
341
- * meaning it should not be sent to the ordering service yet.
355
+ * @param resubmitInfo - Key information when flushing a resubmitted batch. Undefined means this is not resubmit.
342
356
*/
343
- public flush ( resubmittingBatchId ?: BatchId , resubmittingStagedBatch ?: boolean ) : void {
357
+ public flush ( resubmitInfo ?: BatchResubmitInfo ) : void {
344
358
assert (
345
359
! this . isContextReentrant ( ) ,
346
360
0xb7b /* Flushing must not happen while incoming changes are being processed */ ,
347
361
) ;
348
-
349
- this . flushAll ( resubmittingBatchId , resubmittingStagedBatch ) ;
362
+ this . flushAll ( resubmitInfo ) ;
350
363
}
351
364
352
- private flushAll ( resubmittingBatchId ?: BatchId , resubmittingStagedBatch ?: boolean ) : void {
365
+ private flushAll ( resubmitInfo ?: BatchResubmitInfo ) : void {
353
366
const allBatchesEmpty =
354
367
this . idAllocationBatch . empty && this . blobAttachBatch . empty && this . mainBatch . empty ;
355
368
if ( allBatchesEmpty ) {
356
- // If we're resubmitting and all batches are empty, we need to flush an empty batch.
357
- // Note that we currently resubmit one batch at a time, so on resubmit, 2 of the 3 batches will *always* be empty.
369
+ // If we're resubmitting with a batchId and all batches are empty, we need to flush an empty batch.
370
+ // Note that we currently resubmit one batch at a time, so on resubmit, 1 of the 2 batches will *always* be empty.
358
371
// It's theoretically possible that we don't *need* to resubmit this empty batch, and in those cases, it'll safely be ignored
359
372
// by the rest of the system, including remote clients.
360
373
// 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.
361
- if ( resubmittingBatchId ) {
362
- this . flushEmptyBatch ( resubmittingBatchId , resubmittingStagedBatch === true ) ;
374
+ if ( resubmitInfo ?. batchId !== undefined ) {
375
+ this . flushEmptyBatch ( resubmitInfo . batchId , resubmitInfo . staged ) ;
363
376
}
364
377
return ;
365
378
}
366
379
367
380
// Don't use resubmittingBatchId for idAllocationBatch.
368
- // ID Allocation messages are not directly resubmitted so we don't want to reuse the batch ID.
381
+ // ID Allocation messages are not directly resubmitted so don't pass the resubmitInfo
369
382
this . flushInternal ( {
370
383
batchManager : this . idAllocationBatch ,
371
384
// Note: For now, we will never stage ID Allocation messages.
@@ -374,13 +387,11 @@ export class Outbox {
374
387
this . flushInternal ( {
375
388
batchManager : this . blobAttachBatch ,
376
389
disableGroupedBatching : true ,
377
- resubmittingBatchId,
378
- resubmittingStagedBatch,
390
+ resubmitInfo,
379
391
} ) ;
380
392
this . flushInternal ( {
381
393
batchManager : this . mainBatch ,
382
- resubmittingBatchId,
383
- resubmittingStagedBatch,
394
+ resubmitInfo,
384
395
} ) ;
385
396
}
386
397
@@ -416,25 +427,19 @@ export class Outbox {
416
427
private flushInternal ( params : {
417
428
batchManager : BatchManager ;
418
429
disableGroupedBatching ?: boolean ;
419
- resubmittingBatchId ?: BatchId ; // undefined if not resubmitting
420
- resubmittingStagedBatch ?: boolean ; // undefined if not resubmitting
430
+ resubmitInfo ?: BatchResubmitInfo ; // undefined if not resubmitting
421
431
} ) : void {
422
- const {
423
- batchManager,
424
- disableGroupedBatching = false ,
425
- resubmittingBatchId,
426
- resubmittingStagedBatch,
427
- } = params ;
432
+ const { batchManager, disableGroupedBatching = false , resubmitInfo } = params ;
428
433
if ( batchManager . empty ) {
429
434
return ;
430
435
}
431
436
432
- const rawBatch = batchManager . popBatch ( resubmittingBatchId ) ;
437
+ const rawBatch = batchManager . popBatch ( resubmitInfo ?. batchId ) ;
433
438
434
439
// When resubmitting, we respect the staged state of the original batch.
435
440
// In this case rawBatch.staged will match the state of inStagingMode when
436
441
// the resubmit occurred, which is not relevant.
437
- const staged = resubmittingStagedBatch ?? rawBatch . staged === true ;
442
+ const staged = resubmitInfo ?. staged ?? rawBatch . staged === true ;
438
443
439
444
const groupingEnabled =
440
445
! disableGroupedBatching && this . params . groupingManager . groupedBatchingEnabled ( ) ;
0 commit comments