Support Gzip and cache result to prevent wasting CPU
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,7 +49,10 @@ func loadConfiguration() *config.Config {
return config.Get()
}
-func serviceResultsHandler(writer http.ResponseWriter, _ *http.Request) {
+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 {
@@ -46,6 +61,19 @@ func serviceResultsHandler(writer http.ResponseWriter, _ *http.Request) {
_, _ = 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)
_, _ = writer.Write(data)
