]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/stats.go
Fix panic on empty news path
[rbdr/mobius] / hotline / stats.go
index bc06a6915776b6ed36bc86917fe256066046a71e..316a67df9429e675e740b447b6cbf2df458b557d 100644 (file)
@@ -1,17 +1,96 @@
 package hotline
 
 import (
+       "sync"
        "time"
 )
 
+// Stat counter keys
+const (
+       StatCurrentlyConnected = iota
+       StatDownloadsInProgress
+       StatUploadsInProgress
+       StatWaitingDownloads
+       StatConnectionPeak
+       StatConnectionCounter
+       StatDownloadCounter
+       StatUploadCounter
+)
+
+type Counter interface {
+       Increment(keys ...int)
+       Decrement(key int)
+       Set(key, val int)
+       Get(key int) int
+       Values() map[string]interface{}
+}
+
 type Stats struct {
-       CurrentlyConnected  int
-       DownloadsInProgress int
-       UploadsInProgress   int
-       WaitingDownloads    int
-       ConnectionPeak      int
-       ConnectionCounter   int
-       DownloadCounter     int
-       UploadCounter       int
-       Since               time.Time
+       stats map[int]int
+       since time.Time
+
+       mu sync.RWMutex
+}
+
+func NewStats() *Stats {
+       return &Stats{
+               since: time.Now(),
+               stats: map[int]int{
+                       StatCurrentlyConnected:  0,
+                       StatDownloadsInProgress: 0,
+                       StatUploadsInProgress:   0,
+                       StatWaitingDownloads:    0,
+                       StatConnectionPeak:      0,
+                       StatDownloadCounter:     0,
+                       StatUploadCounter:       0,
+                       StatConnectionCounter:   0,
+               },
+       }
+}
+
+func (s *Stats) Increment(keys ...int) {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+
+       for _, key := range keys {
+               s.stats[key]++
+       }
+}
+
+func (s *Stats) Decrement(key int) {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+
+       s.stats[key]--
+}
+
+func (s *Stats) Set(key, val int) {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+
+       s.stats[key] = val
+}
+
+func (s *Stats) Get(key int) int {
+       s.mu.RLock()
+       defer s.mu.RUnlock()
+
+       return s.stats[key]
+}
+
+func (s *Stats) Values() map[string]interface{} {
+       s.mu.RLock()
+       defer s.mu.RUnlock()
+
+       return map[string]interface{}{
+               "CurrentlyConnected":  s.stats[StatCurrentlyConnected],
+               "DownloadsInProgress": s.stats[StatDownloadsInProgress],
+               "UploadsInProgress":   s.stats[StatUploadsInProgress],
+               "WaitingDownloads":    s.stats[StatWaitingDownloads],
+               "ConnectionPeak":      s.stats[StatConnectionPeak],
+               "ConnectionCounter":   s.stats[StatConnectionCounter],
+               "DownloadCounter":     s.stats[StatDownloadCounter],
+               "UploadCounter":       s.stats[StatUploadCounter],
+               "Since":               s.since,
+       }
 }