mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 13:23:07 +01:00
46
internal/cache/expire.go
vendored
Normal file
46
internal/cache/expire.go
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache[T any] struct {
|
||||||
|
f func() (T, error)
|
||||||
|
Timestamp time.Time
|
||||||
|
Duration time.Duration
|
||||||
|
Data T
|
||||||
|
}
|
||||||
|
|
||||||
|
func New[T any](f func() (T, error), duration time.Duration) *Cache[T] {
|
||||||
|
return &Cache[T]{
|
||||||
|
f: f,
|
||||||
|
Duration: duration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache[T]) GetWithHit() (T, error, bool) {
|
||||||
|
hit := true
|
||||||
|
if c.Timestamp.IsZero() || time.Since(c.Timestamp) > c.Duration {
|
||||||
|
hit = false
|
||||||
|
|
||||||
|
var err error
|
||||||
|
c.Data, err = c.f()
|
||||||
|
if err != nil {
|
||||||
|
return c.Data, err, hit
|
||||||
|
}
|
||||||
|
c.Timestamp = time.Now()
|
||||||
|
}
|
||||||
|
if hit {
|
||||||
|
log.Debugf("Cache hit for %T", c.Data)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Cache miss for %T", c.Data)
|
||||||
|
}
|
||||||
|
return c.Data, nil, hit
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache[T]) Get() (T, error) {
|
||||||
|
data, err, _ := c.GetWithHit()
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
@@ -3,13 +3,22 @@ package web
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/amir20/dozzle/internal/cache"
|
||||||
"github.com/amir20/dozzle/internal/releases"
|
"github.com/amir20/dozzle/internal/releases"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var cachedReleases *cache.Cache[[]releases.Release]
|
||||||
|
|
||||||
func (h *handler) releases(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) releases(w http.ResponseWriter, r *http.Request) {
|
||||||
releases, err := releases.Fetch(h.config.Version)
|
if cachedReleases == nil {
|
||||||
|
cachedReleases = cache.New(func() ([]releases.Release, error) {
|
||||||
|
return releases.Fetch(h.config.Version)
|
||||||
|
}, time.Hour)
|
||||||
|
}
|
||||||
|
releases, err, hit := cachedReleases.GetWithHit()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
@@ -17,8 +26,10 @@ func (h *handler) releases(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Cache-Control", "max-age=3600")
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if hit {
|
||||||
|
w.Header().Set("X-Cache", "HIT")
|
||||||
|
}
|
||||||
|
|
||||||
if err := json.NewEncoder(w).Encode(releases); err != nil {
|
if err := json.NewEncoder(w).Encode(releases); err != nil {
|
||||||
log.Errorf("json encoding error while streaming %v", err.Error())
|
log.Errorf("json encoding error while streaming %v", err.Error())
|
||||||
|
|||||||
Reference in New Issue
Block a user