Protect cached vsp stats with mutex.

This commit is contained in:
jholdstock 2020-06-16 14:56:29 +01:00 committed by David Hill
parent 5a1a1b487e
commit 13c4f4faea
4 changed files with 29 additions and 14 deletions

View File

@ -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

View File

@ -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(),
})
}

View File

@ -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

View File

@ -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)
}
}
}