From 8407a1258f93e33f32c9a80c6ec1c794e2984be7 Mon Sep 17 00:00:00 2001 From: trafficlunar Date: Sat, 22 Mar 2025 14:20:04 +0000 Subject: [PATCH] feat: keys, clicks, and totals in computer statistics --- internal/handler/computer.go | 22 +++++++++++++++++++++- internal/model/computer.go | 14 ++++++++++++-- internal/service/computer.go | 33 +++++++++++++++++++++++++++++++-- internal/storage/datastore.go | 5 ++++- internal/worker/computer.go | 6 ++++-- main.go | 15 +++++++++++++-- 6 files changed, 85 insertions(+), 10 deletions(-) diff --git a/internal/handler/computer.go b/internal/handler/computer.go index 8203829..8544477 100644 --- a/internal/handler/computer.go +++ b/internal/handler/computer.go @@ -3,6 +3,7 @@ package handler import ( "api/internal/model" "api/internal/service" + "api/internal/storage" "api/internal/worker" "encoding/json" "log/slog" @@ -33,7 +34,7 @@ func HandleComputerWebSocket(w http.ResponseWriter, r *http.Request) { } defer conn.Close() - slog.Info("WebSocket connection established!") + slog.Info("WebSocket connection established") service.ComputerData.Online = true for { @@ -52,6 +53,25 @@ func HandleComputerWebSocket(w http.ResponseWriter, r *http.Request) { worker.QueuedClientMessage = clientMessage slog.Info("Recieved message", slog.Any("message", clientMessage)) + + // Add to totals + keysData := storage.GlobalDataStore.Get("keys") + clicksData := storage.GlobalDataStore.Get("clicks") + + var keys float64 + var clicks float64 + + if keysData != nil { + keys = keysData.(float64) + } + if clicksData != nil { + clicks = clicksData.(float64) + } + + storage.GlobalDataStore.Set("keys", keys+float64(clientMessage.Keys)) + storage.GlobalDataStore.Set("clicks", clicks+float64(clientMessage.Clicks)) + + service.LoadComputerStatTotals() } } diff --git a/internal/model/computer.go b/internal/model/computer.go index 1fc3481..7621e01 100644 --- a/internal/model/computer.go +++ b/internal/model/computer.go @@ -3,17 +3,27 @@ package model import "time" type ComputerWebSocketMessage struct { - Cpu uint8 `json:"cpu"` - Ram uint8 `json:"ram"` + Cpu uint8 `json:"cpu"` + Ram uint8 `json:"ram"` + Keys uint16 `json:"keys"` + Clicks uint16 `json:"clicks"` } type ComputerData struct { Online bool `json:"online"` + Totals ComputerTotals `json:"totals"` Graph []ComputerGraphData `json:"graph"` } +type ComputerTotals struct { + Keys float64 `json:"keys"` + Clicks float64 `json:"clicks"` +} + type ComputerGraphData struct { Timestamp time.Time `json:"timestamp"` Cpu int `json:"cpu"` Ram int `json:"ram"` + Keys int `json:"keys"` + Clicks int `json:"clicks"` } diff --git a/internal/service/computer.go b/internal/service/computer.go index db63751..ca283b3 100644 --- a/internal/service/computer.go +++ b/internal/service/computer.go @@ -2,22 +2,49 @@ package service import ( "api/internal/model" + "api/internal/storage" "time" ) var ComputerData model.ComputerData = model.ComputerData{ Online: false, - Graph: initializeGraphData(), + Totals: model.ComputerTotals{ + Keys: 0, + Clicks: 0, + }, + Graph: initializeGraphData(), +} + +func LoadComputerStatTotals() { + keysData := storage.GlobalDataStore.Get("keys") + clicksData := storage.GlobalDataStore.Get("clicks") + + var keys float64 + var clicks float64 + + if keysData != nil { + keys = keysData.(float64) + } + if clicksData != nil { + clicks = clicksData.(float64) + } + + ComputerData.Totals = model.ComputerTotals{ + Keys: keys, + Clicks: clicks, + } } func initializeGraphData() []model.ComputerGraphData { graphData := make([]model.ComputerGraphData, 60) - for i := 0; i < 60; i++ { + for i := range 60 { graphData[i] = model.ComputerGraphData{ Timestamp: time.Now().Truncate(1 * time.Minute).Add(time.Duration(-60+i) * time.Minute), Cpu: 0, Ram: 0, + Keys: 0, + Clicks: 0, } } @@ -29,6 +56,8 @@ func AddComputerData(clientMessage model.ComputerWebSocketMessage) { Timestamp: time.Now().Truncate(time.Minute).Add(-time.Minute), Cpu: int(clientMessage.Cpu), Ram: int(clientMessage.Ram), + Keys: int(clientMessage.Keys), + Clicks: int(clientMessage.Clicks), }) if len(ComputerData.Graph) > 60 { diff --git a/internal/storage/datastore.go b/internal/storage/datastore.go index 5d9fc97..6b8d5f0 100644 --- a/internal/storage/datastore.go +++ b/internal/storage/datastore.go @@ -12,7 +12,9 @@ type DataStore struct { Mutex sync.Mutex } -var GlobalDataStore *DataStore +var GlobalDataStore = &DataStore{ + Data: make(map[string]any), +} func InitDataStore() *DataStore { GlobalDataStore = &DataStore{ @@ -36,6 +38,7 @@ func InitDataStore() *DataStore { return nil } + slog.Info("Loaded data store") return GlobalDataStore } diff --git a/internal/worker/computer.go b/internal/worker/computer.go index 78e0edd..cdef8dd 100644 --- a/internal/worker/computer.go +++ b/internal/worker/computer.go @@ -18,8 +18,10 @@ func StartComputerWorker() { if now.Second() == 0 { if !service.ComputerData.Online { service.AddComputerData(model.ComputerWebSocketMessage{ - Cpu: 0, - Ram: 0, + Cpu: 0, + Ram: 0, + Keys: 0, + Clicks: 0, }) } else { service.AddComputerData(QueuedClientMessage) diff --git a/main.go b/main.go index fd60ff5..ed81f93 100644 --- a/main.go +++ b/main.go @@ -4,12 +4,14 @@ import ( "log/slog" "os" "os/signal" + "sync" "syscall" "github.com/joho/godotenv" "github.com/lmittmann/tint" "api/internal/server" + "api/internal/service" "api/internal/storage" "api/internal/worker" ) @@ -20,10 +22,19 @@ func main() { err := godotenv.Load() if err != nil { - slog.Warn("No .env file was found; using environment variables.", slog.Any("error", err)) + slog.Warn("No .env file was found; using environment variables", slog.Any("error", err)) } - storage.InitDataStore() + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + storage.InitDataStore() + }() + + wg.Wait() + service.LoadComputerStatTotals() go worker.StartWorkers() // Shutdown-chan~~