Skip to content

Commit 85db2d7

Browse files
committed
Optimize peers fetching
1 parent fdc65b5 commit 85db2d7

File tree

1 file changed

+68
-82
lines changed

1 file changed

+68
-82
lines changed

pkg/http/server.go

Lines changed: 68 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package http
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"net/http"
67
"os"
78
"sort"
@@ -696,60 +697,8 @@ func InitServer(log *logrus.Logger, db *gorm.DB, statsService *service.StatsServ
696697
// Get all unique peers
697698
peerMap := make(map[string]*PeerStat)
698699

699-
// Collect peers from messages table
700-
type PeerInfo struct {
701-
Peer string
702-
Count int64
703-
FirstSeen string
704-
LastSeen string
705-
}
706-
var messagePeers []PeerInfo
707-
if err := db.Table("messages").
708-
Select("peer, COUNT(*) as count, MIN(received_at) as first_seen, MAX(received_at) as last_seen").
709-
Where("peer != ''").
710-
Group("peer").
711-
Find(&messagePeers).Error; err == nil {
712-
for _, p := range messagePeers {
713-
// Parse time strings - try multiple formats
714-
var firstSeen, lastSeen time.Time
715-
var err error
716-
717-
// Try different time formats that SQLite might return
718-
timeFormats := []string{
719-
"2006-01-02 15:04:05",
720-
"2006-01-02T15:04:05Z",
721-
"2006-01-02T15:04:05",
722-
time.RFC3339,
723-
}
724-
725-
for _, format := range timeFormats {
726-
if firstSeen, err = time.Parse(format, p.FirstSeen); err == nil {
727-
break
728-
}
729-
}
730-
if err != nil {
731-
firstSeen = time.Now() // fallback
732-
}
733-
734-
for _, format := range timeFormats {
735-
if lastSeen, err = time.Parse(format, p.LastSeen); err == nil {
736-
break
737-
}
738-
}
739-
if err != nil {
740-
lastSeen = time.Now() // fallback
741-
}
742-
743-
peerMap[p.Peer] = &PeerStat{
744-
PeerID: p.Peer,
745-
TotalMessages: p.Count,
746-
FirstSeen: firstSeen,
747-
LastSeen: lastSeen,
748-
Networks: []string{},
749-
MessageTypes: make(map[string]int64),
750-
}
751-
}
752-
}
700+
// Skip querying the non-existent messages table - the database has been optimized
701+
// to use specialized tables (blocks, subtrees, node_statuses, rejected_txes)
753702

754703
// Add data from specialized tables
755704
// Blocks
@@ -761,43 +710,38 @@ func InitServer(log *logrus.Logger, db *gorm.DB, statsService *service.StatsServ
761710
LastSeen string
762711
}
763712

764-
// Helper function to process specialized tables
713+
// Optimized helper function to process specialized tables with less memory overhead
765714
processPeerTable := func(tableName, messageType string) {
766715
var peers []PeerTableInfo
767-
if err := db.Table(tableName).
768-
Select("peer_id, network, COUNT(*) as count, MIN(received_at) as first_seen, MAX(received_at) as last_seen").
769-
Where("peer_id != ''").
770-
Group("peer_id, network").
771-
Find(&peers).Error; err == nil {
716+
// Use raw SQL for better performance with large datasets
717+
query := fmt.Sprintf(`
718+
SELECT peer_id, network, COUNT(*) as count,
719+
MIN(received_at) as first_seen,
720+
MAX(received_at) as last_seen
721+
FROM %s
722+
WHERE peer_id != ''
723+
GROUP BY peer_id, network`, tableName)
724+
725+
if err := db.Raw(query).Scan(&peers).Error; err == nil {
772726
for _, p := range peers {
773-
// Parse time strings - try multiple formats
727+
// Use Go's built-in time parsing which handles SQLite format
774728
var firstSeen, lastSeen time.Time
775-
var err error
776-
777-
// Try different time formats that SQLite might return
778-
timeFormats := []string{
779-
"2006-01-02 15:04:05",
780-
"2006-01-02T15:04:05Z",
781-
"2006-01-02T15:04:05",
782-
time.RFC3339,
783-
}
784729

785-
for _, format := range timeFormats {
786-
if firstSeen, err = time.Parse(format, p.FirstSeen); err == nil {
787-
break
788-
}
730+
// SQLite returns timestamps in RFC3339 format by default
731+
firstSeen, _ = time.Parse(time.RFC3339, p.FirstSeen)
732+
if firstSeen.IsZero() {
733+
firstSeen, _ = time.Parse("2006-01-02 15:04:05", p.FirstSeen)
789734
}
790-
if err != nil {
791-
firstSeen = time.Now() // fallback
735+
if firstSeen.IsZero() {
736+
firstSeen = time.Now()
792737
}
793738

794-
for _, format := range timeFormats {
795-
if lastSeen, err = time.Parse(format, p.LastSeen); err == nil {
796-
break
797-
}
739+
lastSeen, _ = time.Parse(time.RFC3339, p.LastSeen)
740+
if lastSeen.IsZero() {
741+
lastSeen, _ = time.Parse("2006-01-02 15:04:05", p.LastSeen)
798742
}
799-
if err != nil {
800-
lastSeen = time.Now() // fallback
743+
if lastSeen.IsZero() {
744+
lastSeen = time.Now()
801745
}
802746

803747
if stat, exists := peerMap[p.PeerID]; exists {
@@ -836,6 +780,8 @@ func InitServer(log *logrus.Logger, db *gorm.DB, statsService *service.StatsServ
836780
peerMap[p.PeerID].MessageTypes[messageType] = p.Count
837781
}
838782
}
783+
} else if err != nil {
784+
logrus.Printf("Error querying %s table for peer stats: %v", tableName, err)
839785
}
840786
}
841787

@@ -845,6 +791,46 @@ func InitServer(log *logrus.Logger, db *gorm.DB, statsService *service.StatsServ
845791
processPeerTable("rejected_txes", "rejected_tx")
846792
processPeerTable("node_statuses", "node_status")
847793

794+
// Get latest user agent and best height from node_statuses for each peer
795+
type NodeStatusInfo struct {
796+
PeerID string
797+
UserAgent string
798+
BestHeight uint32
799+
}
800+
var nodeStatuses []NodeStatusInfo
801+
query := `
802+
SELECT DISTINCT ON (peer_id)
803+
peer_id,
804+
user_agent,
805+
best_height
806+
FROM node_statuses
807+
WHERE peer_id != ''
808+
ORDER BY peer_id, received_at DESC`
809+
810+
if db.Dialector.Name() == "sqlite" {
811+
// SQLite doesn't support DISTINCT ON, use a different approach
812+
query = `
813+
SELECT peer_id, user_agent, best_height
814+
FROM node_statuses ns1
815+
WHERE peer_id != ''
816+
AND received_at = (
817+
SELECT MAX(received_at)
818+
FROM node_statuses ns2
819+
WHERE ns2.peer_id = ns1.peer_id
820+
)`
821+
}
822+
823+
if err := db.Raw(query).Scan(&nodeStatuses).Error; err == nil {
824+
for _, ns := range nodeStatuses {
825+
if stat, exists := peerMap[ns.PeerID]; exists {
826+
stat.LastUserAgent = ns.UserAgent
827+
stat.LastBestHeight = ns.BestHeight
828+
}
829+
}
830+
} else {
831+
logrus.Printf("Error querying node_statuses for user agent and best height: %v", err)
832+
}
833+
848834
// Convert map to slice and sort by total messages
849835
peers := make([]PeerStat, 0, len(peerMap))
850836
for _, peer := range peerMap {

0 commit comments

Comments
 (0)