@@ -140,10 +140,6 @@ func chooseSegmentEnd(from, to uint64, snapType snaptype.Enum, snCfg *snapcfg.Cf
140140type BlockRetire struct {
141141 maxScheduledBlock atomic.Uint64
142142 working atomic.Bool
143- merging atomic.Bool
144- mergeWg sync.WaitGroup
145- mergeMu sync.Mutex
146- mergeClosing bool
147143 lastRetireGapStart atomic.Uint64
148144
149145 // shared semaphore with AggregatorV3 to allow only one type of snapshot building at a time
@@ -334,7 +330,8 @@ func (br *BlockRetire) retireBlocks(
334330 }
335331 }
336332
337- return ok , nil
333+ merged , err := br .MergeBlocks (ctx , lvl , seeder )
334+ return ok || merged , err
338335}
339336
340337func (br * BlockRetire ) MergeBlocks (
@@ -439,18 +436,16 @@ func (br *BlockRetire) RetireBlocksInBackground(
439436 defer onDone ()
440437 defer br .working .Store (false )
441438
442- // Dump under the shared semaphore: the build phase is fast and is
443- // serialized against state-snapshot building to bound concurrent I/O.
444- err := func () error {
445- if br .snBuildAllowed != nil {
446- //we are inside own goroutine - it's fine to block here
447- if err := br .snBuildAllowed .Acquire (ctx , 1 ); err != nil {
448- return err
449- }
450- defer br .snBuildAllowed .Release (1 )
439+ if br .snBuildAllowed != nil {
440+ //we are inside own goroutine - it's fine to block here
441+ if err := br .snBuildAllowed .Acquire (ctx , 1 ); err != nil {
442+ br .logger .Warn ("[snapshots] retire blocks" , "err" , err )
443+ return
451444 }
452- return br .RetireBlocks (ctx , minBlockNum , maxBlockNum , lvl , seeder , onFinishRetire )
453- }()
445+ defer br .snBuildAllowed .Release (1 )
446+ }
447+
448+ err := br .RetireBlocks (ctx , minBlockNum , maxBlockNum , lvl , seeder , onFinishRetire )
454449 if errors .Is (err , heimdall .ErrHeimdallDataIsNotReady ) {
455450 br .borDataNotReadyBefore = time .Now ().Add (BorDataNotReadyTimeout )
456451 br .logger .Debug ("[snapshots] bor data is not ready to be retired" , "nextAttemptAt" , br .borDataNotReadyBefore )
@@ -464,54 +459,11 @@ func (br *BlockRetire) RetireBlocksInBackground(
464459 br .logger .Error ("[snapshots] retire blocks" , "err" , err )
465460 return
466461 }
467-
468- // Merge runs without the semaphore: it is slow and expensive, and
469- // holding the semaphore across it stalls state-snapshot collation/prune
470- // (which bounds chaindata size). Mirrors the aggregator's MergeLoop.
471- br .mergeBlocksInBackground (ctx , lvl , seeder )
472462 }()
473463
474464 return true
475465}
476466
477- // mergeBlocksInBackground runs block-snapshot merges off the shared build
478- // semaphore. At most one merge runs at a time; a request arriving while one is
479- // in flight is dropped and picked up by a later retire cycle.
480- func (br * BlockRetire ) mergeBlocksInBackground (ctx context.Context , lvl log.Lvl , seeder downloader.SeederClient ) {
481- br .mergeMu .Lock ()
482- defer br .mergeMu .Unlock ()
483- // Once WaitForMerges has begun draining we must not start (and Add) a new merge.
484- if br .mergeClosing {
485- return
486- }
487- if ! br .merging .CompareAndSwap (false , true ) {
488- return
489- }
490- br .mergeWg .Add (1 )
491- go func () {
492- defer br .mergeWg .Done ()
493- defer br .merging .Store (false )
494- if _ , err := br .MergeBlocks (ctx , lvl , seeder ); err != nil {
495- br .logger .Error ("[snapshots] merge blocks" , "err" , err )
496- }
497- }()
498- }
499-
500- // WaitForMerges prevents new background merges from starting and waits for any
501- // in-flight one to finish, or until ctx is done. Abandoning the wait is safe:
502- // the merge touches neither chainDB nor the open snapshots.
503- func (br * BlockRetire ) WaitForMerges (ctx context.Context ) {
504- br .mergeMu .Lock ()
505- br .mergeClosing = true
506- br .mergeMu .Unlock ()
507- done := make (chan struct {})
508- go func () { br .mergeWg .Wait (); close (done ) }()
509- select {
510- case <- done :
511- case <- ctx .Done ():
512- }
513- }
514-
515467func (br * BlockRetire ) RetireBlocks (
516468 ctx context.Context ,
517469 requestedMinBlockNum uint64 ,
0 commit comments