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