code: func (s *UtxoScanner) batchManager() {
  	defer close(s.shutdown)
  
  	for {
  		s.cv.L.Lock()
  		// Re-queue previously skipped requests for next batch.
  		for _, request := range s.nextBatch {
  			heap.Push(&s.pq, request)
  		}
  		s.nextBatch = nil
  
  		// Wait for the queue to be non-empty.
  		for s.pq.IsEmpty() {
  			s.cv.Wait()
  
  			select {
  			case <-s.quit:
  				s.cv.L.Unlock()
  				return
  			default:
  			}
  		}
  
  		req := s.pq.Peek()
  		s.cv.L.Unlock()
  
  		// Break out now before starting a scan if a shutdown was
  		// requested.
  		select {
  		case <-s.quit:
  			return
  		default:
  		}
  
  		// Initiate a scan, starting from the birth height of the
  		// least-height request currently in the queue.
  		err := s.scanFromHeight(req.BirthHeight)
  		if err != nil {
  			log.Errorf("utxo scan failed: %v", err)
  		}
  	}
  }
docs: // batchManager is responsible for scheduling batches of UTXOs to scan. Any
  // incoming requests whose start height has already been passed will be added to
  // the next batch, which gets scheduled after the current batch finishes.
  //
  // NOTE: This method MUST be spawned as a goroutine.