Skip to content

Commit 77b6eb8

Browse files
committed
fix(api): improve perf for /api/v1/app/dashboard
1 parent 2054c64 commit 77b6eb8

File tree

3 files changed

+205
-120
lines changed

3 files changed

+205
-120
lines changed

handlers/api.go

+67-74
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,9 @@ Combined validator get, performance, attestation efficency, sync committee stati
849849
Not public documented
850850
*/
851851
func ApiDashboard(w http.ResponseWriter, r *http.Request) {
852+
obs := utils.NewTimingsObserver("ApiDashboard")
853+
defer obs.End(time.Second * 10)
854+
852855
w.Header().Set("Content-Type", "application/json")
853856

854857
j := json.NewEncoder(w)
@@ -895,128 +898,83 @@ func ApiDashboard(w http.ResponseWriter, r *http.Request) {
895898

896899
if len(queryIndices) > 0 {
897900
g.Go(func() error {
898-
start := time.Now()
901+
defer obs.Timer("getGeneralValidatorInfoForAppDashboard")()
899902
var err error
900903
validatorsData, err = getGeneralValidatorInfoForAppDashboard(queryIndices)
901-
elapsed := time.Since(start)
902-
if elapsed > 10*time.Second {
903-
logger.Warnf("getGeneralValidatorInfoForAppDashboard(%v) took longer than 10 sec", queryIndices)
904-
}
905904
return err
906905
})
907906

908907
g.Go(func() error {
909-
start := time.Now()
908+
defer obs.Timer("getValidatorEffectiveness")()
910909
var err error
911910
validatorEffectivenessData, err = getValidatorEffectiveness(epoch-1, queryIndices)
912-
elapsed := time.Since(start)
913-
if elapsed > 10*time.Second {
914-
logger.Warnf("getValidatorEffectiveness(%v, %v) took longer than 10 sec", epoch-1, queryIndices)
915-
}
916911
return err
917912
})
918913

919914
g.Go(func() error {
920-
start := time.Now()
915+
defer obs.Timer("getRocketpoolValidators")()
921916
var err error
922917
rocketpoolData, err = getRocketpoolValidators(queryIndices)
923-
elapsed := time.Since(start)
924-
if elapsed > 10*time.Second {
925-
logger.Warnf("getRocketpoolValidators(%v) took longer than 10 sec", queryIndices)
926-
}
927918
return err
928919
})
929920

930921
g.Go(func() error {
931-
start := time.Now()
922+
defer obs.Timer("getValidatorExecutionPerformance")()
932923
var err error
933924
executionPerformance, err = getValidatorExecutionPerformance(queryIndices)
934-
elapsed := time.Since(start)
935-
if elapsed > 10*time.Second {
936-
logger.Warnf("getValidatorExecutionPerformance(%v) took longer than 10 sec", queryIndices)
937-
}
938925
return err
939926
})
940927

941928
g.Go(func() error {
942-
start := time.Now()
929+
defer obs.Timer("getSyncCommitteeInfoForValidators")()
943930
var err error
944931
period := utils.SyncPeriodOfEpoch(epoch)
945932
currentSyncCommittee, err = getSyncCommitteeInfoForValidators(queryIndices, period)
946-
elapsed := time.Since(start)
947-
if elapsed > 10*time.Second {
948-
logger.Warnf("getSyncCommitteeInfoForValidators(%v, %v) took longer than 10 sec", queryIndices, period)
949-
}
950933
return err
951934
})
952935

953936
g.Go(func() error {
954-
start := time.Now()
937+
defer obs.Timer("getSyncCommitteeInfoForValidators+1")()
955938
var err error
956939
period := utils.SyncPeriodOfEpoch(epoch) + 1
957940
nextSyncCommittee, err = getSyncCommitteeInfoForValidators(queryIndices, period)
958-
elapsed := time.Since(start)
959-
if elapsed > 10*time.Second {
960-
logger.Warnf("SyncPeriodOfEpoch(%v) + 1 took longer than 10 sec", epoch)
961-
logger.Warnf("getSyncCommitteeInfoForValidators(%v, %v) took longer than 10 sec", queryIndices, period)
962-
}
963941
return err
964942
})
965943

966944
g.Go(func() error {
967-
start := time.Now()
945+
defer obs.Timer("getSyncCommitteeStatistics")()
968946
var err error
969947
syncCommitteeStats, err = getSyncCommitteeStatistics(queryIndices, epoch)
970-
elapsed := time.Since(start)
971-
if elapsed > 10*time.Second {
972-
logger.Warnf("getSyncCommitteeStatistics(%v, %v) took longer than 10 sec", queryIndices, epoch)
973-
}
974948
return err
975949
})
976950

977951
g.Go(func() error {
978-
start := time.Now()
952+
defer obs.Timer("getProposalLuckStats+1")()
979953
var err error
980954
proposalLuckStats, err = getProposalLuckStats(queryIndices)
981-
elapsed := time.Since(start)
982-
if elapsed > 10*time.Second {
983-
logger.Warnf("getProposalLuck(%v, %v) took longer than 10 sec", queryIndices, epoch)
984-
}
985955
return err
986956
})
987957
}
988958
}
989959

990960
g.Go(func() error {
991-
start := time.Now()
961+
defer obs.Timer("getEpoch-1")()
992962
var err error
993963
currentEpochData, err = getEpoch(int64(epoch) - 1)
994-
elapsed := time.Since(start)
995-
if elapsed > 10*time.Second {
996-
logger.Warnf("getEpoch(%v) took longer than 10 sec", int64(epoch)-1)
997-
}
998964
return err
999965
})
1000966

1001967
g.Go(func() error {
1002-
start := time.Now()
968+
defer obs.Timer("getEpoch-10")()
1003969
var err error
1004970
olderEpochData, err = getEpoch(int64(epoch) - 10)
1005-
elapsed := time.Since(start)
1006-
if elapsed > 10*time.Second {
1007-
logger.Warnf("getEpoch(%v) took longer than 10 sec", int64(epoch)-10)
1008-
}
1009971
return err
1010972
})
1011973

1012974
g.Go(func() error {
1013-
start := time.Now()
975+
defer obs.Timer("getRocketpoolStats")()
1014976
var err error
1015977
rocketpoolStats, err = getRocketpoolStats()
1016-
elapsed := time.Since(start)
1017-
if elapsed > 10*time.Second {
1018-
logger.Warnf("getRocketpoolStats() took longer than 10 sec")
1019-
}
1020978
return err
1021979
})
1022980

@@ -1074,6 +1032,9 @@ func getSyncCommitteeInfoForValidators(validators []uint64, period uint64) ([]in
10741032
}
10751033

10761034
func getSyncCommitteeStatistics(validators []uint64, epoch uint64) (*SyncCommitteesInfo, error) {
1035+
obs := utils.NewTimingsObserver("getSyncCommitteeStatistics")
1036+
defer obs.End(time.Second * 10)
1037+
10771038
if epoch < utils.Config.Chain.ClConfig.AltairForkEpoch {
10781039
// no sync committee duties before altair fork
10791040
return &SyncCommitteesInfo{}, nil
@@ -1084,12 +1045,31 @@ func getSyncCommitteeStatistics(validators []uint64, epoch uint64) (*SyncCommitt
10841045
return &SyncCommitteesInfo{}, nil
10851046
}
10861047

1087-
expectedSlots, err := getExpectedSyncCommitteeSlots(validators, epoch)
1088-
if err != nil {
1089-
return nil, err
1090-
}
1048+
g := errgroup.Group{}
1049+
1050+
var expectedSlots uint64
1051+
g.Go(func() error {
1052+
defer obs.Timer("getExpectedSyncCommitteeSlots")()
1053+
var err error
1054+
expectedSlots, err = getExpectedSyncCommitteeSlots(validators, epoch)
1055+
if err != nil {
1056+
return err
1057+
}
1058+
return nil
1059+
})
10911060

1092-
stats, err := getSyncCommitteeSlotsStatistics(validators, epoch)
1061+
var stats types.SyncCommitteesStats
1062+
g.Go(func() error {
1063+
defer obs.Timer("getSyncCommitteeSlotsStatistics")()
1064+
var err error
1065+
stats, err = getSyncCommitteeSlotsStatistics(validators, epoch)
1066+
if err != nil {
1067+
return err
1068+
}
1069+
return nil
1070+
})
1071+
1072+
err := g.Wait()
10931073
if err != nil {
10941074
return nil, err
10951075
}
@@ -1397,8 +1377,16 @@ func getRocketpoolValidators(queryIndices []uint64) ([]interface{}, error) {
13971377
}
13981378

13991379
func getGeneralValidatorInfoForAppDashboard(queryIndices []uint64) ([]interface{}, error) {
1400-
// we use MAX(validatorindex)+1 instead of COUNT(*) for querying the rank_count for performance-reasons
1401-
rows, err := db.ReaderDb.Query(`
1380+
obs := utils.NewTimingsObserver("getGeneralValidatorInfoForAppDashboard")
1381+
defer obs.End(time.Second * 10)
1382+
1383+
g := new(errgroup.Group)
1384+
1385+
var data []interface{}
1386+
g.Go(func() error {
1387+
defer obs.Timer("getValidators")()
1388+
// we use MAX(validatorindex)+1 instead of COUNT(*) for querying the rank_count for performance-reasons
1389+
rows, err := db.ReaderDb.Query(`
14021390
WITH maxValidatorIndex AS (
14031391
SELECT MAX(validatorindex)+1 as total_count
14041392
FROM validator_performance
@@ -1427,20 +1415,21 @@ func getGeneralValidatorInfoForAppDashboard(queryIndices []uint64) ([]interface{
14271415
LEFT JOIN validator_names ON validator_names.publickey = validators.pubkey
14281416
WHERE validators.validatorindex = ANY($1)
14291417
ORDER BY validators.validatorindex`, pq.Array(queryIndices))
1430-
if err != nil {
1431-
return nil, fmt.Errorf("error querying validators: %w", err)
1432-
}
1433-
defer rows.Close()
1434-
1435-
data, err := utils.SqlRowsToJSON(rows)
1436-
if err != nil {
1437-
return nil, fmt.Errorf("error converting validators to json: %w", err)
1438-
}
1418+
if err != nil {
1419+
return fmt.Errorf("error querying validators: %w", err)
1420+
}
1421+
defer rows.Close()
14391422

1440-
g := new(errgroup.Group)
1423+
data, err = utils.SqlRowsToJSON(rows)
1424+
if err != nil {
1425+
return fmt.Errorf("error converting validators to json: %w", err)
1426+
}
1427+
return nil
1428+
})
14411429

14421430
var balances map[uint64][]*types.ValidatorBalance
14431431
g.Go(func() error {
1432+
defer obs.Timer("GetValidatorBalanceHistory")()
14441433
var err error
14451434
balances, err = db.BigtableClient.GetValidatorBalanceHistory(queryIndices, services.LatestEpoch(), services.LatestEpoch())
14461435
if err != nil {
@@ -1451,6 +1440,7 @@ func getGeneralValidatorInfoForAppDashboard(queryIndices []uint64) ([]interface{
14511440

14521441
var currentDayIncome map[uint64]int64
14531442
g.Go(func() error {
1443+
defer obs.Timer("GetCurrentDayClIncome")()
14541444
var err error
14551445
currentDayIncome, err = db.GetCurrentDayClIncome(queryIndices)
14561446
if err != nil {
@@ -1461,6 +1451,7 @@ func getGeneralValidatorInfoForAppDashboard(queryIndices []uint64) ([]interface{
14611451

14621452
var lastAttestationSlots map[uint64]uint64
14631453
g.Go(func() error {
1454+
defer obs.Timer("GetLastAttestationSlots")()
14641455
var err error
14651456
lastAttestationSlots, err = db.BigtableClient.GetLastAttestationSlots(queryIndices)
14661457
if err != nil {
@@ -1469,11 +1460,12 @@ func getGeneralValidatorInfoForAppDashboard(queryIndices []uint64) ([]interface{
14691460
return nil
14701461
})
14711462

1472-
err = g.Wait()
1463+
err := g.Wait()
14731464
if err != nil {
14741465
return nil, fmt.Errorf("error in validator errgroup: %w", err)
14751466
}
14761467

1468+
obsAggreate := obs.Timer("aggregate")
14771469
for _, entry := range data {
14781470
eMap, ok := entry.(map[string]interface{})
14791471
if !ok {
@@ -1505,6 +1497,7 @@ func getGeneralValidatorInfoForAppDashboard(queryIndices []uint64) ([]interface{
15051497
}
15061498
}
15071499
}
1500+
obsAggreate()
15081501

15091502
return data, nil
15101503
}

0 commit comments

Comments
 (0)