From 6302b60d273baf762d11e2073dd736b46901cde6 Mon Sep 17 00:00:00 2001 From: rishavvajpayee Date: Mon, 28 Oct 2024 19:33:37 +0530 Subject: [PATCH 1/2] WIP: add cleanup and commands left in /health headers --- internal/middleware/ratelimiter.go | 3 +- internal/server/http.go | 49 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/internal/middleware/ratelimiter.go b/internal/middleware/ratelimiter.go index f8d3c52..1f9ad61 100644 --- a/internal/middleware/ratelimiter.go +++ b/internal/middleware/ratelimiter.go @@ -111,8 +111,7 @@ func calculateNextCleanupTime(ctx context.Context, client *db.DiceDB, cronFreque lastCleanupTime := time.UnixMilli(lastCronCleanupTime) nextCleanupTime := lastCleanupTime.Add(cronFrequencyInterval) - timeDifference := nextCleanupTime.Sub(time.Now()) - return int64(timeDifference.Seconds()), nil + return int64(time.Until(nextCleanupTime).Seconds()), nil } func MockRateLimiter(client *mock.DiceDBMock, next http.Handler, limit int64, window float64) http.Handler { diff --git a/internal/server/http.go b/internal/server/http.go index b5209c2..b450bb3 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -6,12 +6,16 @@ import ( "errors" "log/slog" "net/http" + "strconv" "strings" "time" "server/internal/db" "server/internal/middleware" + "server/internal/server/utils" util "server/util" + + "github.com/dicedb/dicedb-go" ) type HTTPServer struct { @@ -100,6 +104,22 @@ func (s *HTTPServer) Shutdown() error { } func (s *HTTPServer) HealthCheck(w http.ResponseWriter, request *http.Request) { + nextCleanup, err := s.getNextCleanupTime() + if err != nil { + slog.Error("Failed to get the cleanupTime", slog.Any("err", err)) + http.Error(w, errorResponse("internal server error"), http.StatusInternalServerError) + return + } + + commandsLeft, err := s.getCommandsLeft() + if err != nil { + slog.Error("Failed to get the commands Left", slog.Any("err", err)) + http.Error(w, errorResponse("internal server error"), http.StatusInternalServerError) + return + } + + w.Header().Set("x-next-cleanup-time", strconv.FormatInt(nextCleanup, 10)) + w.Header().Set("x-commands-left", strconv.FormatInt(commandsLeft, 10)) util.JSONResponse(w, http.StatusOK, map[string]string{"message": "server is running"}) } @@ -142,3 +162,32 @@ func (s *HTTPServer) CliHandler(w http.ResponseWriter, r *http.Request) { func (s *HTTPServer) SearchHandler(w http.ResponseWriter, request *http.Request) { util.JSONResponse(w, http.StatusOK, map[string]string{"message": "search results"}) } + +func (s *HTTPServer) getNextCleanupTime() (int64, error) { + resp := s.DiceClient.Client.Get(context.Background(), utils.LastCronCleanupTimeUnixMs) + if resp.Err() != nil { + if errors.Is(resp.Err(), dicedb.Nil) { + return time.Now().UnixMilli(), nil + } + return 0, resp.Err() + } + + lastCleanupStr := resp.Val() + if lastCleanupStr == "" { + return 0, resp.Err() + } + + lastCleanup, err := strconv.ParseInt(lastCleanupStr, 10, 64) + if err != nil { + return 0, err + } + lastCleanupTime := time.UnixMilli(lastCleanup) + nextCleanupTime := lastCleanupTime.Add(15 * time.Minute).UnixMilli() + + return nextCleanupTime, nil +} + +func (s *HTTPServer) getCommandsLeft() (int64, error) { + // clarification required + return 1, nil +} From 5febcceecb34a69bac14e58c3db4a8695b91f21e Mon Sep 17 00:00:00 2001 From: rishavvajpayee Date: Tue, 29 Oct 2024 13:50:59 +0530 Subject: [PATCH 2/2] added commands left to headers --- internal/server/http.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/internal/server/http.go b/internal/server/http.go index b450bb3..cd4f631 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -4,12 +4,14 @@ import ( "context" "encoding/json" "errors" + "fmt" "log/slog" "net/http" "strconv" "strings" "time" + "server/config" "server/internal/db" "server/internal/middleware" "server/internal/server/utils" @@ -188,6 +190,26 @@ func (s *HTTPServer) getNextCleanupTime() (int64, error) { } func (s *HTTPServer) getCommandsLeft() (int64, error) { - // clarification required - return 1, nil + configValue := config.LoadConfig() + currentWindow := time.Now().Unix() / int64(configValue.Server.RequestWindowSec) + key := fmt.Sprintf("request_count:%d", currentWindow) + + val, err := s.DiceClient.Client.Get(context.Background(), key).Result() + if err != nil { + if errors.Is(err, dicedb.Nil) { + return 1000, nil + } + return 0, err + } + + requestCount, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return 0, err + } + + remaining := int64(1000) - requestCount + if remaining < 0 { + remaining = 0 + } + return remaining, nil }