Protect cached vsp stats with mutex.
This commit is contained in:
parent
5a1a1b487e
commit
13c4f4faea
@ -10,7 +10,7 @@ import (
|
||||
// adminPage is the handler for "GET /admin".
|
||||
func adminPage(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "admin.html", gin.H{
|
||||
"VspStats": stats,
|
||||
"VspStats": getVSPStats(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ func ticketSearch(c *gin.Context) {
|
||||
"Found": found,
|
||||
"Ticket": ticket,
|
||||
},
|
||||
"VspStats": stats,
|
||||
"VspStats": getVSPStats(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ func adminLogin(c *gin.Context) {
|
||||
if password != cfg.AdminPass {
|
||||
log.Warnf("Failed login attempt from %s", c.ClientIP())
|
||||
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
|
||||
"VspStats": stats,
|
||||
"VspStats": getVSPStats(),
|
||||
"IncorrectPassword": true,
|
||||
})
|
||||
return
|
||||
|
||||
@ -2,6 +2,7 @@ package webapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/decred/vspd/database"
|
||||
@ -21,14 +22,26 @@ type vspStats struct {
|
||||
Debug bool
|
||||
}
|
||||
|
||||
var statsMtx sync.RWMutex
|
||||
var stats *vspStats
|
||||
|
||||
func updateVSPStats(db *database.VspDatabase, cfg Config) (*vspStats, error) {
|
||||
func getVSPStats() *vspStats {
|
||||
statsMtx.RLock()
|
||||
defer statsMtx.RUnlock()
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
func updateVSPStats(db *database.VspDatabase, cfg Config) error {
|
||||
total, feeConfirmed, err := db.CountTickets()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
return &vspStats{
|
||||
|
||||
statsMtx.Lock()
|
||||
defer statsMtx.Unlock()
|
||||
|
||||
stats = &vspStats{
|
||||
PubKey: signPubKey,
|
||||
TotalTickets: total,
|
||||
FeeConfirmedTickets: feeConfirmed,
|
||||
@ -38,11 +51,13 @@ func updateVSPStats(db *database.VspDatabase, cfg Config) (*vspStats, error) {
|
||||
SupportEmail: cfg.SupportEmail,
|
||||
VspClosed: cfg.VspClosed,
|
||||
Debug: cfg.Debug,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func homepage(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "homepage.html", gin.H{
|
||||
"VspStats": stats,
|
||||
"VspStats": getVSPStats(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ func requireAdmin() gin.HandlerFunc {
|
||||
|
||||
if admin == nil {
|
||||
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
|
||||
"VspStats": stats,
|
||||
"VspStats": getVSPStats(),
|
||||
})
|
||||
c.Abort()
|
||||
return
|
||||
|
||||
@ -59,10 +59,10 @@ func Start(ctx context.Context, requestShutdownChan chan struct{}, shutdownWg *s
|
||||
return fmt.Errorf("Failed to get keypair: %v", err)
|
||||
}
|
||||
|
||||
// Populate template data before starting webserver.
|
||||
stats, err = updateVSPStats(vdb, config)
|
||||
// Populate cached VSP stats before starting webserver.
|
||||
err = updateVSPStats(vdb, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not initialize homepage data: %v", err)
|
||||
return fmt.Errorf("could not initialize VSP stats cache: %v", err)
|
||||
}
|
||||
|
||||
// Get the last used address index and the feeXpub from the database, and
|
||||
@ -147,9 +147,9 @@ func Start(ctx context.Context, requestShutdownChan chan struct{}, shutdownWg *s
|
||||
shutdownWg.Done()
|
||||
return
|
||||
case <-ticker.C:
|
||||
stats, err = updateVSPStats(db, cfg)
|
||||
err = updateVSPStats(db, cfg)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to update homepage data: %v", err)
|
||||
log.Errorf("Failed to update cached VSP stats: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user