Add X-Cache-Time-Remaining header

This commit is contained in:
Jacob Gunther
2022-08-21 19:24:39 -05:00
parent 6c750bcaed
commit e16f8c38bb
4 changed files with 68 additions and 28 deletions

View File

@@ -3,6 +3,6 @@ port: 3001
redis: redis://127.0.0.1:6379/0 redis: redis://127.0.0.1:6379/0
cache: cache:
enable: false enable: false
java_cache_duration: 5m java_cache_duration: 1m
bedrock_cache_duration: 5m bedrock_cache_duration: 1m
icon_cache_duration: 15m icon_cache_duration: 15m

View File

@@ -57,9 +57,27 @@ func (r *Redis) Exists(key string) (bool, error) {
return val == 1, err return val == 1, err
} }
func (r *Redis) GetString(key string) (string, error) { func (r *Redis) TTL(key string) (time.Duration, error) {
if !r.Enabled { if !r.Enabled {
return "", nil return 0, nil
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
res := r.Client.TTL(ctx, key)
if err := res.Err(); err != nil {
return 0, err
}
return res.Result()
}
func (r *Redis) GetJSON(key string, value interface{}) error {
if !r.Enabled {
return nil
} }
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
@@ -69,10 +87,16 @@ func (r *Redis) GetString(key string) (string, error) {
res := r.Client.Get(ctx, key) res := r.Client.Get(ctx, key)
if err := res.Err(); err != nil { if err := res.Err(); err != nil {
return "", err return err
} }
return res.Result() data, err := res.Bytes()
if err != nil {
return err
}
return json.Unmarshal(data, value)
} }
func (r *Redis) GetBytes(key string) ([]byte, error) { func (r *Redis) GetBytes(key string) ([]byte, error) {

View File

@@ -3,6 +3,7 @@ package main
import ( import (
"log" "log"
"net/http" "net/http"
"strconv"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
@@ -27,18 +28,17 @@ func JavaStatusHandler(ctx *fiber.Ctx) error {
return ctx.Status(http.StatusBadRequest).SendString("Invalid address value") return ctx.Status(http.StatusBadRequest).SendString("Invalid address value")
} }
response, err := GetJavaStatus(host, port) response, expiresAt, err := GetJavaStatus(host, port)
if err != nil { if err != nil {
return err return err
} }
switch v := response.(type) { if expiresAt != nil {
case string: ctx.Set("X-Cache-Time-Remaining", strconv.Itoa(int(expiresAt.Seconds())))
return ctx.Type("json").SendString(v)
default:
return ctx.JSON(response)
} }
return ctx.JSON(response)
} }
func BedrockStatusHandler(ctx *fiber.Ctx) error { func BedrockStatusHandler(ctx *fiber.Ctx) error {
@@ -48,18 +48,17 @@ func BedrockStatusHandler(ctx *fiber.Ctx) error {
return ctx.Status(http.StatusBadRequest).SendString("Invalid address value") return ctx.Status(http.StatusBadRequest).SendString("Invalid address value")
} }
response, err := GetBedrockStatus(host, port) response, expiresAt, err := GetBedrockStatus(host, port)
if err != nil { if err != nil {
return err return err
} }
switch v := response.(type) { if expiresAt != nil {
case string: ctx.Set("X-Cache-Time-Remaining", strconv.Itoa(int(expiresAt.Seconds())))
return ctx.Type("json").SendString(v)
default:
return ctx.JSON(response)
} }
return ctx.JSON(response)
} }
func IconHandler(ctx *fiber.Ctx) error { func IconHandler(ctx *fiber.Ctx) error {

View File

@@ -4,6 +4,7 @@ import (
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"strings" "strings"
"time"
"github.com/mcstatus-io/mcutil" "github.com/mcstatus-io/mcutil"
) )
@@ -75,48 +76,64 @@ type Mod struct {
Version string `json:"version"` Version string `json:"version"`
} }
func GetJavaStatus(host string, port uint16) (interface{}, error) { func GetJavaStatus(host string, port uint16) (interface{}, *time.Duration, error) {
cacheKey := fmt.Sprintf("java:%s-%d", host, port) cacheKey := fmt.Sprintf("java:%s-%d", host, port)
cacheExists, err := r.Exists(cacheKey) cacheExists, err := r.Exists(cacheKey)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
if cacheExists { if cacheExists {
return r.GetString(cacheKey) var response JavaStatusResponse
if err = r.GetJSON(cacheKey, &response); err != nil {
return nil, nil, err
}
expiresAt, err := r.TTL(cacheKey)
return response, &expiresAt, err
} }
response := FetchJavaStatus(host, port) response := FetchJavaStatus(host, port)
if err := r.SetJSON(cacheKey, response, config.Cache.JavaCacheDuration); err != nil { if err := r.SetJSON(cacheKey, response, config.Cache.JavaCacheDuration); err != nil {
return nil, err return nil, nil, err
} }
return response, nil return response, nil, nil
} }
func GetBedrockStatus(host string, port uint16) (interface{}, error) { func GetBedrockStatus(host string, port uint16) (interface{}, *time.Duration, error) {
cacheKey := fmt.Sprintf("bedrock:%s-%d", host, port) cacheKey := fmt.Sprintf("bedrock:%s-%d", host, port)
cacheExists, err := r.Exists(cacheKey) cacheExists, err := r.Exists(cacheKey)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
if cacheExists { if cacheExists {
return r.GetString(cacheKey) var response BedrockStatusResponse
if err = r.GetJSON(cacheKey, &response); err != nil {
return nil, nil, err
}
expiresAt, err := r.TTL(cacheKey)
return response, &expiresAt, err
} }
response := FetchBedrockStatus(host, port) response := FetchBedrockStatus(host, port)
if err := r.SetJSON(cacheKey, response, config.Cache.BedrockCacheDuration); err != nil { if err := r.SetJSON(cacheKey, response, config.Cache.BedrockCacheDuration); err != nil {
return nil, err return nil, nil, err
} }
return response, nil return response, nil, nil
} }
func GetServerIcon(host string, port uint16) ([]byte, error) { func GetServerIcon(host string, port uint16) ([]byte, error) {