diff --git a/.gitignore b/.gitignore index 06a75af..86523a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -postgres/ \ No newline at end of file +postgres**/ \ No newline at end of file diff --git a/relay/main.go b/relay/main.go index 1ac69b4..4a934da 100644 --- a/relay/main.go +++ b/relay/main.go @@ -8,12 +8,18 @@ import ( "strconv" "time" + "git.highperfocused.tech/highperfocused/lumina-relay/relay/cache" "git.highperfocused.tech/highperfocused/lumina-relay/relay/trending" "github.com/fiatjaf/eventstore/postgresql" "github.com/fiatjaf/khatru" "github.com/fiatjaf/khatru/policies" ) +// Cache for storing generic data like event counts +var dataCache = cache.New() +const eventCountCacheKey = "total_event_count" +const eventCountCacheDuration = 1 * time.Minute + func getEnv(key, fallback string) string { if value, ok := os.LookupEnv(key); ok { return value @@ -21,6 +27,43 @@ func getEnv(key, fallback string) string { return fallback } +// Gets total event count, using cache if available +func getTotalEventCount(db *postgresql.PostgresBackend) (int, error) { + // Try getting from cache first + if cachedCount, ok := dataCache.Get(eventCountCacheKey); ok { + return cachedCount.(int), nil + } + + // If not in cache, query the database + count := 0 + row := db.DB.QueryRow("SELECT COUNT(*) FROM event") + if err := row.Scan(&count); err != nil { + return 0, err + } + + // Update the cache + dataCache.Set(eventCountCacheKey, count, eventCountCacheDuration) + return count, nil +} + +// Updates event count in the background periodically +func startEventCountUpdater(db *postgresql.PostgresBackend) { + go func() { + ticker := time.NewTicker(eventCountCacheDuration) + defer ticker.Stop() + for range ticker.C { + count := 0 + row := db.DB.QueryRow("SELECT COUNT(*) FROM event") + if err := row.Scan(&count); err != nil { + fmt.Printf("Error updating event count: %v\n", err) + continue + } + dataCache.Set(eventCountCacheKey, count, eventCountCacheDuration) + fmt.Printf("Updated event count cache: %d events\n", count) + } + }() +} + func main() { fmt.Print(` LUMINA RELAY @@ -55,6 +98,14 @@ func main() { fmt.Printf("Warning: Error initializing trending system: %v\n", err) } + // Initialize event count cache and start periodic updates + fmt.Println("Initializing event count cache...") + _, err := getTotalEventCount(&db) + if err != nil { + fmt.Printf("Warning: Error initializing event count cache: %v\n", err) + } + startEventCountUpdater(&db) + relay.StoreEvent = append(relay.StoreEvent, db.SaveEvent) relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents) relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent) @@ -73,11 +124,11 @@ func main() { mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/html") - // Query the total number of events - count := 0 - row := db.DB.QueryRow("SELECT COUNT(*) FROM event") - if err := row.Scan(&count); err != nil { - fmt.Printf("Error counting events: %v\n", err) + // Get event count from cache + count, err := getTotalEventCount(&db) + if err != nil { + fmt.Printf("Error getting event count: %v\n", err) + count = 0 // Fall back to zero if there's an error } // Improved HTML content with link to stats page @@ -225,6 +276,13 @@ func main() { mux.HandleFunc("/api/stats", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") + // Get total count from cache + totalCount, err := getTotalEventCount(&db) + if err != nil { + http.Error(w, fmt.Sprintf("Error getting event count: %v", err), http.StatusInternalServerError) + return + } + // Query the number of events for each kind, sorted by kind rows, err := db.DB.Query("SELECT kind, COUNT(*) FROM event GROUP BY kind ORDER BY kind") if err != nil { @@ -234,7 +292,6 @@ func main() { defer rows.Close() stats := make(map[string]int) - totalCount := 0 for rows.Next() { var kind string var count int @@ -243,7 +300,6 @@ func main() { return } stats[kind] = count - totalCount += count } // Add total count to the stats