@@ -12,6 +12,7 @@ import (
12
12
"github.com/ipfs/go-datastore"
13
13
"github.com/ipfs/go-datastore/namespace"
14
14
logging "github.com/ipfs/go-log/v2"
15
+ "go.uber.org/zap/zapcore"
15
16
16
17
"github.com/celestiaorg/go-header"
17
18
)
@@ -58,6 +59,7 @@ type Store[H header.Header[H]] struct {
58
59
pending * batch [H ]
59
60
// syncCh is a channel used to synchronize writes
60
61
syncCh chan chan struct {}
62
+ cancel context.CancelFunc
61
63
62
64
onDeleteMu sync.Mutex
63
65
onDelete []func (context.Context , uint64 ) error
@@ -132,7 +134,9 @@ func (s *Store[H]) Start(ctx context.Context) error {
132
134
return err
133
135
}
134
136
135
- go s .flushLoop ()
137
+ ctx , cancel := context .WithCancel (context .Background ())
138
+ s .cancel = cancel
139
+ go s .flushLoop (ctx )
136
140
return nil
137
141
}
138
142
@@ -430,9 +434,8 @@ func (s *Store[H]) Append(ctx context.Context, headers ...H) error {
430
434
// This way writes are controlled and manageable from one place allowing
431
435
// (1) Appends not to be blocked on long disk IO writes and underlying DB compactions
432
436
// (2) Batching header writes
433
- func (s * Store [H ]) flushLoop () {
437
+ func (s * Store [H ]) flushLoop (ctx context. Context ) {
434
438
defer close (s .writesDn )
435
- ctx := context .Background ()
436
439
437
440
flush := func (headers []H ) {
438
441
s .ensureInit (headers )
@@ -608,37 +611,72 @@ func (s *Store[H]) recedeTail(ctx context.Context) {
608
611
func (s * Store [H ]) nextHead (ctx context.Context ) (head H , changed bool ) {
609
612
head , err := s .Head (ctx )
610
613
if err != nil {
611
- log .Errorw ("cannot load head" , "err" , err )
614
+ log .Errorw ("cannot load head while advancing " , "err" , err )
612
615
return head , false
613
616
}
614
617
615
- for {
618
+ for ctx . Err () == nil {
616
619
h , err := s .getByHeight (ctx , head .Height ()+ 1 )
617
620
if err != nil {
621
+ log .Debugw ("next head error" , "current" , head .Height (), "err" , err )
618
622
return head , changed
619
623
}
624
+
625
+ if ! changed && log .Level () == zapcore .DebugLevel {
626
+ now := time .Now ()
627
+ log .Debugw ("advancing head" , "start_height" , head .Height ())
628
+ defer func () {
629
+ log .Debugw (
630
+ "finished advancing head" ,
631
+ "end_height" ,
632
+ head .Height (),
633
+ "took(s)" ,
634
+ time .Since (now ),
635
+ )
636
+ }()
637
+ }
638
+
620
639
head = h
621
640
changed = true
622
641
}
642
+
643
+ return head , changed
623
644
}
624
645
625
646
// nextTail finds the new contiguous Tail by iterating the current Tail down until the older height Tail is found.
626
647
// Returns true if the older one was found.
627
648
func (s * Store [H ]) nextTail (ctx context.Context ) (tail H , changed bool ) {
628
649
tail , err := s .Tail (ctx )
629
650
if err != nil {
630
- log .Errorw ("cannot load tail" , "err" , err )
651
+ log .Errorw ("cannot load tail while receding " , "err" , err )
631
652
return tail , false
632
653
}
633
654
634
- for {
655
+ for ctx . Err () == nil {
635
656
h , err := s .getByHeight (ctx , tail .Height ()- 1 )
636
657
if err != nil {
637
658
return tail , changed
638
659
}
660
+
661
+ if ! changed && log .Level () == zapcore .DebugLevel {
662
+ now := time .Now ()
663
+ log .Debugw ("receding tail" , "start_height" , tail .Height ())
664
+ defer func () {
665
+ log .Debugw (
666
+ "finished receding tail" ,
667
+ "end_height" ,
668
+ tail .Height (),
669
+ "took(s)" ,
670
+ time .Since (now ),
671
+ )
672
+ }()
673
+ }
674
+
639
675
tail = h
640
676
changed = true
641
677
}
678
+
679
+ return tail , changed
642
680
}
643
681
644
682
func (s * Store [H ]) loadHeadAndTail (ctx context.Context ) error {
0 commit comments