@@ -496,7 +496,16 @@ func (t *Table) dropPendingBlock(block *TableBlock) {
496
496
}
497
497
}
498
498
499
- func (t * Table ) writeBlock (block * TableBlock , nextTxn uint64 , skipPersist , snapshotDB bool ) {
499
+ func (t * Table ) writeBlock (
500
+ block * TableBlock , nextTxn uint64 , snapshotDB bool , opts ... RotateBlockOption ,
501
+ ) {
502
+ rbo := & rotateBlockOptions {}
503
+ for _ , o := range opts {
504
+ o (rbo )
505
+ }
506
+ if rbo .wg != nil {
507
+ defer rbo .wg .Done ()
508
+ }
500
509
level .Debug (t .logger ).Log ("msg" , "syncing block" , "ulid" , block .ulid , "size" , block .index .Size ())
501
510
block .pendingWritersWg .Wait ()
502
511
@@ -506,7 +515,7 @@ func (t *Table) writeBlock(block *TableBlock, nextTxn uint64, skipPersist, snaps
506
515
507
516
// Persist the block
508
517
var err error
509
- if ! skipPersist && block .index .Size () != 0 {
518
+ if ! rbo . skipPersist && block .index .Size () != 0 {
510
519
err = block .Persist ()
511
520
}
512
521
t .dropPendingBlock (block )
@@ -605,20 +614,51 @@ func (t *Table) writeBlock(block *TableBlock, nextTxn uint64, skipPersist, snaps
605
614
}
606
615
}
607
616
608
- func (t * Table ) RotateBlock (_ context.Context , block * TableBlock , skipPersist bool ) error {
617
+ type rotateBlockOptions struct {
618
+ skipPersist bool
619
+ wg * sync.WaitGroup
620
+ }
621
+
622
+ type RotateBlockOption func (* rotateBlockOptions )
623
+
624
+ // WithRotateBlockSkipPersist instructs the block rotation operation to not
625
+ // persist the block to object storage.
626
+ func WithRotateBlockSkipPersist () RotateBlockOption {
627
+ return func (o * rotateBlockOptions ) {
628
+ o .skipPersist = true
629
+ }
630
+ }
631
+
632
+ // WithRotateBlockWaitGroup provides a WaitGroup. The rotate block operation
633
+ // will call wg.Done once the block has been persisted. Otherwise, RotateBlock
634
+ // asynchronously persists the block.
635
+ func WithRotateBlockWaitGroup (wg * sync.WaitGroup ) RotateBlockOption {
636
+ return func (o * rotateBlockOptions ) {
637
+ o .wg = wg
638
+ }
639
+ }
640
+
641
+ func (t * Table ) RotateBlock (_ context.Context , block * TableBlock , opts ... RotateBlockOption ) error {
642
+ rbo := & rotateBlockOptions {}
643
+ for _ , o := range opts {
644
+ o (rbo )
645
+ }
609
646
t .mtx .Lock ()
610
647
defer t .mtx .Unlock ()
611
648
612
649
// Need to check that we haven't already rotated this block.
613
650
if t .active != block {
651
+ if rbo .wg != nil {
652
+ rbo .wg .Done ()
653
+ }
614
654
return nil
615
655
}
616
656
617
657
level .Debug (t .logger ).Log (
618
658
"msg" , "rotating block" ,
619
659
"ulid" , block .ulid ,
620
660
"size" , block .Size (),
621
- "skip_persist" , skipPersist ,
661
+ "skip_persist" , rbo . skipPersist ,
622
662
)
623
663
defer level .Debug (t .logger ).Log ("msg" , "done rotating block" , "ulid" , block .ulid )
624
664
@@ -637,7 +677,7 @@ func (t *Table) RotateBlock(_ context.Context, block *TableBlock, skipPersist bo
637
677
t .metrics .blockRotated .Inc ()
638
678
t .metrics .numParts .Set (float64 (0 ))
639
679
640
- if ! skipPersist {
680
+ if ! rbo . skipPersist {
641
681
// If skipping persist, this block rotation is simply a block discard,
642
682
// so no need to add this block to pending blocks. Some callers rely
643
683
// on the fact that blocks are not available for reads as soon as
@@ -647,7 +687,7 @@ func (t *Table) RotateBlock(_ context.Context, block *TableBlock, skipPersist bo
647
687
// We don't check t.db.columnStore.manualBlockRotation here because this is
648
688
// the entry point for users to trigger a manual block rotation and they
649
689
// will specify through skipPersist if they want the block to be persisted.
650
- go t .writeBlock (block , tx , skipPersist , true )
690
+ go t .writeBlock (block , tx , true , opts ... )
651
691
652
692
return nil
653
693
}
@@ -750,7 +790,7 @@ func (t *Table) appender(ctx context.Context) (*TableBlock, func(), error) {
750
790
// We need to rotate the block and the writer won't actually be used.
751
791
finish ()
752
792
753
- err = t .RotateBlock (ctx , block , false )
793
+ err = t .RotateBlock (ctx , block )
754
794
if err != nil {
755
795
return nil , nil , fmt .Errorf ("rotate block: %w" , err )
756
796
}
0 commit comments