Skip to content

Commit

Permalink
Merge pull request #2959 from gobitfly/NOBIDS/cache_validator_status_…
Browse files Browse the repository at this point in the history
…counts

fix(validators): cache validator state counts
  • Loading branch information
guybrush authored Sep 30, 2024
2 parents d31f503 + 4f22dcf commit ec286c7
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 33 deletions.
15 changes: 1 addition & 14 deletions handlers/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ import (
"github.com/gobitfly/eth2-beaconchain-explorer/utils"
)

type states struct {
Name string `db:"statename"`
Count uint64 `db:"statecount"`
}

// Validators returns the validators using a go template
func Validators(w http.ResponseWriter, r *http.Request) {
templateFiles := append(layoutTemplateFiles, "validators.html")
Expand All @@ -31,15 +26,7 @@ func Validators(w http.ResponseWriter, r *http.Request) {

validatorsPageData := types.ValidatorsPageData{}

var currentStateCounts []*states

qry := "SELECT status AS statename, COUNT(*) AS statecount FROM validators GROUP BY status"
err := db.ReaderDb.Select(&currentStateCounts, qry)
if err != nil {
utils.LogError(err, "error retrieving validators data", 0)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
currentStateCounts := services.LatestValidatorStateCounts()

for _, state := range currentStateCounts {
switch state.Name {
Expand Down
39 changes: 20 additions & 19 deletions services/monitoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,25 +249,26 @@ func startServicesMonitoringService() {
firstRun := true

servicesToCheck := map[string]time.Duration{
"eth1indexer": time.Minute * 15,
"slotVizUpdater": time.Minute * 15,
"slotUpdater": time.Minute * 15,
"latestProposedSlotUpdater": time.Minute * 15,
"epochUpdater": time.Minute * 15,
"rewardsExporter": time.Minute * 15,
"mempoolUpdater": time.Minute * 15,
"indexPageDataUpdater": time.Minute * 15,
"latestBlockUpdater": time.Minute * 15,
"headBlockRootHashUpdater": time.Minute * 15,
"notification-collector": time.Minute * 15,
"relaysUpdater": time.Minute * 15,
"ethstoreExporter": time.Minute * 60,
"statsUpdater": time.Minute * 30,
"poolsUpdater": time.Minute * 30,
"slotExporter": time.Minute * 15,
"statistics": time.Minute * 90,
"ethStoreStatistics": time.Minute * 15,
"lastExportedStatisticDay": time.Minute * 15,
"eth1indexer": time.Minute * 15,
"slotVizUpdater": time.Minute * 15,
"slotUpdater": time.Minute * 15,
"latestProposedSlotUpdater": time.Minute * 15,
"epochUpdater": time.Minute * 15,
"rewardsExporter": time.Minute * 15,
"mempoolUpdater": time.Minute * 15,
"indexPageDataUpdater": time.Minute * 15,
"latestBlockUpdater": time.Minute * 15,
"headBlockRootHashUpdater": time.Minute * 15,
"notification-collector": time.Minute * 15,
"relaysUpdater": time.Minute * 15,
"ethstoreExporter": time.Minute * 60,
"statsUpdater": time.Minute * 30,
"poolsUpdater": time.Minute * 30,
"slotExporter": time.Minute * 15,
"statistics": time.Minute * 90,
"ethStoreStatistics": time.Minute * 15,
"lastExportedStatisticDay": time.Minute * 15,
"validatorStateCountsUpdater": time.Minute * 15,
//"notification-sender", //exclude for now as the sender is only running on mainnet
}

Expand Down
45 changes: 45 additions & 0 deletions services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ func Init() {
ready.Add(1)
go latestExportedStatisticDayUpdater(ready)

ready.Add(1)
go validatorStateCountsUpdater(ready)

if utils.Config.RatelimitUpdater.Enabled {
go ratelimit.DBUpdater()
}
Expand Down Expand Up @@ -1766,3 +1769,45 @@ func LatestExportedStatisticDay() (uint64, error) {
}
return wanted, nil
}

func validatorStateCountsUpdater(wg *sync.WaitGroup) {
firstRun := true

for {
var currentStateCounts []types.ValidatorStateCountRow
qry := "SELECT status AS statename, COUNT(*) AS statecount FROM validators GROUP BY status"
err := db.ReaderDb.Select(&currentStateCounts, qry)

if err != nil {
logger.Errorf("error retrieving validator state counts from the database: %v", err)

if err.Error() == "sql: database is closed" {
logger.Fatalf("error retrieving validator state counts from the database: %v", err)
}
} else {
cacheKey := fmt.Sprintf("%d:frontend:validator_state_counts", utils.Config.Chain.ClConfig.DepositChainID)
err := cache.TieredCache.Set(cacheKey, currentStateCounts, utils.Day)
if err != nil {
logger.Errorf("error caching validator state counts: %v", err)
}
if firstRun {
logger.Info("initialized validator state counts updater")
wg.Done()
firstRun = false
}
}
ReportStatus("validatorStateCountsUpdater", "Running", nil)
time.Sleep(time.Minute)
}
}

func LatestValidatorStateCounts() []types.ValidatorStateCountRow {
wanted := []types.ValidatorStateCountRow{}
cacheKey := fmt.Sprintf("%d:frontend:validator_state_counts", utils.Config.Chain.ClConfig.DepositChainID)
if wanted, err := cache.TieredCache.GetWithLocalTimeout(cacheKey, time.Minute, wanted); err == nil {
return wanted.([]types.ValidatorStateCountRow)
} else {
logger.Errorf("error retrieving validator state count data from cache: %v", err)
}
return wanted
}
5 changes: 5 additions & 0 deletions types/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,8 @@ type SearchValidatorsByEth1Result []struct {
ValidatorIndices pq.Int64Array `db:"validatorindices" json:"validator_indices"`
Count uint64 `db:"count" json:"-"`
}

type ValidatorStateCountRow struct {
Name string `db:"statename"`
Count uint64 `db:"statecount"`
}

0 comments on commit ec286c7

Please sign in to comment.