feat(backend): cache user/member counts
This commit is contained in:
parent
af1403d0c9
commit
80cf699a73
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"codeberg.org/pronounscc/pronouns.cc/backend/log"
|
||||
"emperror.dev/errors"
|
||||
|
@ -41,6 +42,10 @@ type DB struct {
|
|||
baseURL *url.URL
|
||||
|
||||
TotalRequests prometheus.Counter
|
||||
|
||||
activeUsersDay, activeUsersWeek, activeUsersMonth int64
|
||||
usersTotal, membersTotal int64
|
||||
countMu sync.RWMutex
|
||||
}
|
||||
|
||||
func New() (*DB, error) {
|
||||
|
|
|
@ -21,6 +21,11 @@ func (db *DB) initMetrics() (err error) {
|
|||
if err != nil {
|
||||
log.Errorf("getting user count for metrics: %v", err)
|
||||
}
|
||||
|
||||
db.countMu.Lock()
|
||||
db.usersTotal = count
|
||||
db.countMu.Unlock()
|
||||
|
||||
return float64(count)
|
||||
}))
|
||||
if err != nil {
|
||||
|
@ -35,6 +40,11 @@ func (db *DB) initMetrics() (err error) {
|
|||
if err != nil {
|
||||
log.Errorf("getting member count for metrics: %v", err)
|
||||
}
|
||||
|
||||
db.countMu.Lock()
|
||||
db.membersTotal = count
|
||||
db.countMu.Unlock()
|
||||
|
||||
return float64(count)
|
||||
}))
|
||||
if err != nil {
|
||||
|
@ -49,6 +59,11 @@ func (db *DB) initMetrics() (err error) {
|
|||
if err != nil {
|
||||
log.Errorf("getting active user count for metrics: %v", err)
|
||||
}
|
||||
|
||||
db.countMu.Lock()
|
||||
db.activeUsersMonth = count
|
||||
db.countMu.Unlock()
|
||||
|
||||
return float64(count)
|
||||
}))
|
||||
if err != nil {
|
||||
|
@ -63,6 +78,11 @@ func (db *DB) initMetrics() (err error) {
|
|||
if err != nil {
|
||||
log.Errorf("getting active user count for metrics: %v", err)
|
||||
}
|
||||
|
||||
db.countMu.Lock()
|
||||
db.activeUsersWeek = count
|
||||
db.countMu.Unlock()
|
||||
|
||||
return float64(count)
|
||||
}))
|
||||
if err != nil {
|
||||
|
@ -77,6 +97,11 @@ func (db *DB) initMetrics() (err error) {
|
|||
if err != nil {
|
||||
log.Errorf("getting active user count for metrics: %v", err)
|
||||
}
|
||||
|
||||
db.countMu.Lock()
|
||||
db.activeUsersDay = count
|
||||
db.countMu.Unlock()
|
||||
|
||||
return float64(count)
|
||||
}))
|
||||
if err != nil {
|
||||
|
@ -107,6 +132,22 @@ func (db *DB) initMetrics() (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (db *DB) Counts(ctx context.Context) (numUsers, numMembers, usersDay, usersWeek, usersMonth int64) {
|
||||
db.countMu.Lock()
|
||||
if numUsers != 0 {
|
||||
defer db.countMu.Unlock()
|
||||
return db.usersTotal, db.membersTotal, db.activeUsersDay, db.activeUsersWeek, db.activeUsersMonth
|
||||
}
|
||||
db.countMu.Unlock()
|
||||
|
||||
numUsers, _ = db.TotalUserCount(ctx)
|
||||
numMembers, _ = db.TotalMemberCount(ctx)
|
||||
usersDay, _ = db.ActiveUsers(ctx, ActiveDay)
|
||||
usersWeek, _ = db.ActiveUsers(ctx, ActiveWeek)
|
||||
usersMonth, _ = db.ActiveUsers(ctx, ActiveMonth)
|
||||
return numUsers, numMembers, usersDay, usersWeek, usersMonth
|
||||
}
|
||||
|
||||
func (db *DB) TotalUserCount(ctx context.Context) (numUsers int64, err error) {
|
||||
err = db.QueryRow(ctx, "SELECT COUNT(*) FROM users WHERE deleted_at IS NULL").Scan(&numUsers)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,9 +4,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
|
||||
"codeberg.org/pronounscc/pronouns.cc/backend/db"
|
||||
"codeberg.org/pronounscc/pronouns.cc/backend/server"
|
||||
"emperror.dev/errors"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
)
|
||||
|
@ -39,30 +37,7 @@ type MetaUsers struct {
|
|||
func (s *Server) meta(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := r.Context()
|
||||
|
||||
numUsers, err := s.DB.TotalUserCount(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying user count")
|
||||
}
|
||||
|
||||
activeMonth, err := s.DB.ActiveUsers(ctx, db.ActiveMonth)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying user count")
|
||||
}
|
||||
|
||||
activeWeek, err := s.DB.ActiveUsers(ctx, db.ActiveWeek)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying user count")
|
||||
}
|
||||
|
||||
activeDay, err := s.DB.ActiveUsers(ctx, db.ActiveDay)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying user count")
|
||||
}
|
||||
|
||||
numMembers, err := s.DB.TotalMemberCount(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "querying user count")
|
||||
}
|
||||
numUsers, numMembers, activeDay, activeWeek, activeMonth := s.DB.Counts(ctx)
|
||||
|
||||
render.JSON(w, r, MetaResponse{
|
||||
GitRepository: server.Repository,
|
||||
|
|
Loading…
Reference in New Issue