add automatic volatile cleanup goroutine
Marco Andronaco andronacomarco@gmail.com
Tue, 16 Jan 2024 10:43:03 +0100
4 files changed,
30 insertions(+),
17 deletions(-)
M
.env.example
→
.env.example
@@ -3,3 +3,4 @@ PORT=3000
CACHE_DURATION_MINUTES=5 TIMEOUT_DURATION_MINUTES=10 MAX_SIZE_MB=20 +CLEANUP_INTERVAL_SECONDS=30
M
fixyoutube.go
→
fixyoutube.go
@@ -181,12 +181,14 @@ apiKey = getenvDefault("API_KEY", "itsme")
port := getenvDefault("PORT", "3000") cacheDuration := getenvDefaultParse("CACHE_DURATION_MINUTES", "5") timeoutDuration := getenvDefaultParse("TIMEOUT_DURATION_MINUTES", "10") + cleanupInterval := getenvDefaultParse("CLEANUP_INTERVAL_SECONDS", "30") maxSizeMB := getenvDefaultParse("MAX_SIZE_MB", "20") myClient := &http.Client{Timeout: 10 * time.Second} options := invidious.ClientOptions{ CacheDuration: time.Duration(cacheDuration) * time.Minute, TimeoutDuration: time.Duration(timeoutDuration) * time.Minute, + CleanupInterval: time.Duration(cleanupInterval) * time.Second, MaxSizeBytes: int64(maxSizeMB * 1000000), } videoapi := invidious.NewClient(myClient, options)
M
invidious/invidious.go
→
invidious/invidious.go
@@ -19,6 +19,7 @@
type ClientOptions struct { CacheDuration time.Duration TimeoutDuration time.Duration + CleanupInterval time.Duration MaxSizeBytes int64 }@@ -114,8 +115,8 @@ }
func NewClient(httpClient *http.Client, options ClientOptions) *Client { InitDB() - timeouts := volatile.NewVolatile[string, error](options.TimeoutDuration) - buffers := volatile.NewVolatile[string, VideoBuffer](options.CacheDuration) + timeouts := volatile.NewVolatile[string, error](options.TimeoutDuration, options.CleanupInterval) + buffers := volatile.NewVolatile[string, VideoBuffer](options.CacheDuration, options.CleanupInterval) client := &Client{ http: httpClient, timeouts: timeouts,
M
volatile/volatile.go
→
volatile/volatile.go
@@ -19,21 +19,7 @@ data map[K]Element[V]
timeToLive time.Duration } -func reverseIntArray(arr []int) { - length := len(arr) - for i := 0; i < length/2; i++ { - arr[i], arr[length-i-1] = arr[length-i-1], arr[i] - } -} - -func NewVolatile[K comparable, V any](timeToLive time.Duration) *Volatile[K, V] { - return &Volatile[K, V]{ - data: make(map[K]Element[V]), - timeToLive: timeToLive, - } -} - -func (v *Volatile[K, V]) clean() { +func (v *Volatile[K, V]) clean() int { now := time.Now() keysToDelete := []K{}@@ -45,6 +31,29 @@ }
for _, key := range keysToDelete { delete(v.data, key) } + return len(keysToDelete) +} + +func (v *Volatile[K, V]) cleanupRoutine(interval time.Duration) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + amt := v.clean() + logger.Debug(amt, " elements were automatically removed from cache.") + } + } +} + +func NewVolatile[K comparable, V any](timeToLive time.Duration, cleanupInterval time.Duration) *Volatile[K, V] { + v := &Volatile[K, V]{ + data: make(map[K]Element[V]), + timeToLive: timeToLive, + } + go v.cleanupRoutine(cleanupInterval) + return v } func (v *Volatile[K, V]) Has(key K) bool {