From 1f241ecdb3b1dc9555fed2f3dfbe8b06005bfaa6 Mon Sep 17 00:00:00 2001 From: TwinProduction Date: Sat, 15 Aug 2020 16:44:28 -0400 Subject: [PATCH] Support Gzip and cache result to prevent wasting CPU --- main.go | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 1651bec5..23d72080 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,8 @@ package main import ( + "bytes" + "compress/gzip" "encoding/json" "github.com/TwinProduction/gatus/config" "github.com/TwinProduction/gatus/watchdog" @@ -8,6 +10,16 @@ import ( "log" "net/http" "os" + "strings" + "time" +) + +const CacheTTL = 10 * time.Second + +var ( + cachedServiceResults []byte + cachedServiceResultsGzipped []byte + cachedServiceResultsTimestamp time.Time ) func main() { @@ -37,14 +49,30 @@ func loadConfiguration() *config.Config { return config.Get() } -func serviceResultsHandler(writer http.ResponseWriter, _ *http.Request) { - serviceResults := watchdog.GetServiceResults() - data, err := json.Marshal(serviceResults) - if err != nil { - log.Printf("[main][serviceResultsHandler] Unable to marshall object to JSON: %s", err.Error()) - writer.WriteHeader(http.StatusInternalServerError) - _, _ = writer.Write([]byte("Unable to marshall object to JSON")) - return +func serviceResultsHandler(writer http.ResponseWriter, r *http.Request) { + if isExpired := cachedServiceResultsTimestamp.IsZero() || time.Now().Sub(cachedServiceResultsTimestamp) > CacheTTL; isExpired { + buffer := &bytes.Buffer{} + gzipWriter := gzip.NewWriter(buffer) + serviceResults := watchdog.GetServiceResults() + data, err := json.Marshal(serviceResults) + if err != nil { + log.Printf("[main][serviceResultsHandler] Unable to marshall object to JSON: %s", err.Error()) + writer.WriteHeader(http.StatusInternalServerError) + _, _ = writer.Write([]byte("Unable to marshall object to JSON")) + return + } + gzipWriter.Write(data) + gzipWriter.Close() + cachedServiceResults = data + cachedServiceResultsGzipped = buffer.Bytes() + cachedServiceResultsTimestamp = time.Now() + } + var data []byte + if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { + writer.Header().Set("Content-Encoding", "gzip") + data = cachedServiceResultsGzipped + } else { + data = cachedServiceResults } writer.Header().Add("Content-type", "application/json") writer.WriteHeader(http.StatusOK)