mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
core: introduce tx index progress cache
This commit is contained in:
parent
c8c8d6c403
commit
f389711da5
1 changed files with 24 additions and 4 deletions
|
|
@ -19,6 +19,7 @@ package core
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
|
@ -220,6 +221,9 @@ func (indexer *txIndexer) loop(chain *BlockChain) {
|
||||||
done chan struct{} // Non-nil if background routine is active
|
done chan struct{} // Non-nil if background routine is active
|
||||||
head = indexer.resolveHead() // The latest announced chain head
|
head = indexer.resolveHead() // The latest announced chain head
|
||||||
|
|
||||||
|
prog *TxIndexProgress // Cached tx indexing progress
|
||||||
|
progTime time.Time // Timestamp the progress was made
|
||||||
|
|
||||||
headCh = make(chan ChainHeadEvent)
|
headCh = make(chan ChainHeadEvent)
|
||||||
sub = chain.SubscribeChainHeadEvent(headCh)
|
sub = chain.SubscribeChainHeadEvent(headCh)
|
||||||
)
|
)
|
||||||
|
|
@ -248,7 +252,23 @@ func (indexer *txIndexer) loop(chain *BlockChain) {
|
||||||
stop = nil
|
stop = nil
|
||||||
done = nil
|
done = nil
|
||||||
case ch := <-indexer.progress:
|
case ch := <-indexer.progress:
|
||||||
ch <- indexer.report(head)
|
// Serve the indexing progress query using the cached result first.
|
||||||
|
// If the cached value is too old, fall back to querying real-time progress.
|
||||||
|
//
|
||||||
|
// A slight delay (up to 8 seconds) is acceptable. Once all transactions
|
||||||
|
// are fully indexed, the cached result is correct regardless of its age.
|
||||||
|
//
|
||||||
|
// It's a workaround for the potential performance reported by
|
||||||
|
// https://github.com/ethereum/go-ethereum/issues/31732 in which the single
|
||||||
|
// `rawdb.ReadTxIndexTail(indexer.db)` is super slow due to unknown database
|
||||||
|
// status and blocks all the subsequent indexing query requests.
|
||||||
|
if prog != nil && time.Since(progTime) < time.Second*8 {
|
||||||
|
ch <- *prog
|
||||||
|
} else {
|
||||||
|
prog = indexer.report(head)
|
||||||
|
progTime = time.Now()
|
||||||
|
ch <- *prog
|
||||||
|
}
|
||||||
case ch := <-indexer.term:
|
case ch := <-indexer.term:
|
||||||
if stop != nil {
|
if stop != nil {
|
||||||
close(stop)
|
close(stop)
|
||||||
|
|
@ -264,11 +284,11 @@ func (indexer *txIndexer) loop(chain *BlockChain) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// report returns the tx indexing progress.
|
// report returns the tx indexing progress.
|
||||||
func (indexer *txIndexer) report(head uint64) TxIndexProgress {
|
func (indexer *txIndexer) report(head uint64) *TxIndexProgress {
|
||||||
// Special case if the head is even below the cutoff,
|
// Special case if the head is even below the cutoff,
|
||||||
// nothing to index.
|
// nothing to index.
|
||||||
if head < indexer.cutoff {
|
if head < indexer.cutoff {
|
||||||
return TxIndexProgress{
|
return &TxIndexProgress{
|
||||||
Indexed: 0,
|
Indexed: 0,
|
||||||
Remaining: 0,
|
Remaining: 0,
|
||||||
}
|
}
|
||||||
|
|
@ -294,7 +314,7 @@ func (indexer *txIndexer) report(head uint64) TxIndexProgress {
|
||||||
if indexed < total {
|
if indexed < total {
|
||||||
remaining = total - indexed
|
remaining = total - indexed
|
||||||
}
|
}
|
||||||
return TxIndexProgress{
|
return &TxIndexProgress{
|
||||||
Indexed: indexed,
|
Indexed: indexed,
|
||||||
Remaining: remaining,
|
Remaining: remaining,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue