mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 19:56:18 -04:00
UI Refresh
This commit is contained in:
@@ -5,12 +5,33 @@ import (
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileCache struct {
|
||||
dir string
|
||||
// CacheStats tracks cache hit/miss statistics.
|
||||
type CacheStats struct {
|
||||
Hits int64
|
||||
Misses int64
|
||||
}
|
||||
|
||||
// FileCache implements a file-backed HTTP response cache with TTL expiry.
|
||||
type FileCache struct {
|
||||
dir string
|
||||
stats CacheStats
|
||||
}
|
||||
|
||||
// Default TTL values.
|
||||
const (
|
||||
// CacheTTLShort is for current-season, frequently changing data (meetings, sessions, results).
|
||||
CacheTTLShort = 15 * time.Minute
|
||||
// CacheTTLMedium is for semi-stable data (championship standings, driver lists).
|
||||
CacheTTLMedium = 1 * time.Hour
|
||||
// CacheTTLLong is for historical data that rarely changes (past season data).
|
||||
CacheTTLLong = 24 * time.Hour
|
||||
)
|
||||
|
||||
func NewFileCache() *FileCache {
|
||||
var cacheDir string
|
||||
userCacheDir, err := os.UserCacheDir()
|
||||
@@ -35,13 +56,56 @@ func (c *FileCache) getCachePath(key string) string {
|
||||
return filepath.Join(c.dir, filename)
|
||||
}
|
||||
|
||||
// Get retrieves data from the cache. Returns nil, false if not found.
|
||||
// ttlForURL determines the appropriate TTL based on the URL pattern.
|
||||
func ttlForURL(url string) time.Duration {
|
||||
// Historical data (specific year queries for past years)
|
||||
if strings.Contains(url, "year=2023") || strings.Contains(url, "year=2024") {
|
||||
return CacheTTLLong
|
||||
}
|
||||
|
||||
// Frequently changing endpoints
|
||||
if strings.Contains(url, "/position") ||
|
||||
strings.Contains(url, "/intervals") ||
|
||||
strings.Contains(url, "/car_data") ||
|
||||
strings.Contains(url, "/location") {
|
||||
return CacheTTLShort
|
||||
}
|
||||
|
||||
// Semi-stable data
|
||||
if strings.Contains(url, "/championship") ||
|
||||
strings.Contains(url, "/drivers") {
|
||||
return CacheTTLMedium
|
||||
}
|
||||
|
||||
// Default: medium TTL for everything else
|
||||
return CacheTTLMedium
|
||||
}
|
||||
|
||||
// Get retrieves data from the cache. Returns nil, false if not found or expired.
|
||||
func (c *FileCache) Get(key string) ([]byte, bool) {
|
||||
path := c.getCachePath(key)
|
||||
data, err := os.ReadFile(path)
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
atomic.AddInt64(&c.stats.Misses, 1)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Check TTL based on file modification time
|
||||
ttl := ttlForURL(key)
|
||||
if time.Since(info.ModTime()) > ttl {
|
||||
// Expired — remove the stale file
|
||||
_ = os.Remove(path)
|
||||
atomic.AddInt64(&c.stats.Misses, 1)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
atomic.AddInt64(&c.stats.Misses, 1)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
atomic.AddInt64(&c.stats.Hits, 1)
|
||||
return data, true
|
||||
}
|
||||
|
||||
@@ -50,3 +114,45 @@ func (c *FileCache) Set(key string, data []byte) error {
|
||||
path := c.getCachePath(key)
|
||||
return os.WriteFile(path, data, 0644)
|
||||
}
|
||||
|
||||
// Stats returns current cache hit/miss stats.
|
||||
func (c *FileCache) Stats() CacheStats {
|
||||
return CacheStats{
|
||||
Hits: atomic.LoadInt64(&c.stats.Hits),
|
||||
Misses: atomic.LoadInt64(&c.stats.Misses),
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes all cached files.
|
||||
func (c *FileCache) Clear() error {
|
||||
entries, err := os.ReadDir(c.dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if strings.HasSuffix(entry.Name(), ".json") {
|
||||
_ = os.Remove(filepath.Join(c.dir, entry.Name()))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Size returns the number of cached files and total size in bytes.
|
||||
func (c *FileCache) Size() (int, int64) {
|
||||
entries, err := os.ReadDir(c.dir)
|
||||
if err != nil {
|
||||
return 0, 0
|
||||
}
|
||||
count := 0
|
||||
var totalSize int64
|
||||
for _, entry := range entries {
|
||||
if strings.HasSuffix(entry.Name(), ".json") {
|
||||
count++
|
||||
info, err := entry.Info()
|
||||
if err == nil {
|
||||
totalSize += info.Size()
|
||||
}
|
||||
}
|
||||
}
|
||||
return count, totalSize
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user