refactor: split jikan client into transport/cache/rate subpackages
This commit is contained in:
86
integrations/jikan/cache/store.go
vendored
Normal file
86
integrations/jikan/cache/store.go
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"mal/internal/db"
|
||||
"mal/internal/observability"
|
||||
)
|
||||
|
||||
type Store struct {
|
||||
db db.Querier
|
||||
metrics *observability.Metrics
|
||||
}
|
||||
|
||||
func NewStore(queries db.Querier, metrics *observability.Metrics) *Store {
|
||||
return &Store{db: queries, metrics: metrics}
|
||||
}
|
||||
|
||||
// Get retrieves a fresh cached value by key.
|
||||
func (s *Store) Get(parentCtx context.Context, key string, out any) bool {
|
||||
ctx, cancel := context.WithTimeout(parentCtx, 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
data, err := s.db.GetJikanCache(ctx, key)
|
||||
if err != nil {
|
||||
s.metrics.ObserveCache("jikan", "miss")
|
||||
return false
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(data), out); err != nil {
|
||||
s.metrics.ObserveCache("jikan", "miss")
|
||||
return false
|
||||
}
|
||||
|
||||
s.metrics.ObserveCache("jikan", "hit")
|
||||
return true
|
||||
}
|
||||
|
||||
// GetStale retrieves an expired-but-available cached value by key.
|
||||
func (s *Store) GetStale(parentCtx context.Context, key string, out any) bool {
|
||||
ctx, cancel := context.WithTimeout(parentCtx, 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
data, err := s.db.GetJikanCacheStale(ctx, key)
|
||||
if err != nil {
|
||||
s.metrics.ObserveCache("jikan_stale", "miss")
|
||||
return false
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(data), out); err != nil {
|
||||
s.metrics.ObserveCache("jikan_stale", "miss")
|
||||
return false
|
||||
}
|
||||
|
||||
s.metrics.ObserveCache("jikan_stale", "hit")
|
||||
return true
|
||||
}
|
||||
|
||||
// Set stores data in cache with the specified TTL.
|
||||
func (s *Store) Set(parentCtx context.Context, key string, data any, ttl time.Duration) {
|
||||
ctx, cancel := context.WithTimeout(parentCtx, 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
bytes, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = s.db.SetJikanCache(ctx, db.SetJikanCacheParams{
|
||||
Key: key,
|
||||
Data: string(bytes),
|
||||
ExpiresAt: time.Now().Add(ttl),
|
||||
})
|
||||
if err != nil {
|
||||
observability.LogJSON(
|
||||
observability.LogLevelError,
|
||||
"jikan_cache_set",
|
||||
"jikan",
|
||||
"",
|
||||
map[string]any{"cache_key": key},
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user