// Copyright 2026 Arctel.net // SPDX-License-Identifier: Apache-2.0 // Package diskcache wraps the generic pkg/cache/disk to provide database configuration integration. package diskcache import ( "context" "strconv" "sync" "time" pkgcache "Wavelet/pkg/cache/disk" database "Wavelet/plugins/infra/database" ) // Status represents the runtime cache statistics. type Status = pkgcache.Status const ( defaultCacheDir = "uploads/diskcache" defaultMaxSizeMB = 100 defaultTTLMinutes = 60 defaultCleanupInterval = 10 // DefaultExpiration applies the cache-wide default TTL. DefaultExpiration = pkgcache.DefaultExpiration // NoExpiration stores the item without a TTL. Size limits and LRU eviction still apply. NoExpiration = pkgcache.NoExpiration ) // ErrCacheMiss represents a cache miss. var ErrCacheMiss = pkgcache.ErrCacheMiss // DiskCache is a wrapper around the generic pkg/diskcache that integrates with the DB for configs. type DiskCache struct { *pkgcache.Cache } var ( globalCache *DiskCache globalCacheOnce sync.Once ) // GetGlobalCache returns the global singleton DiskCache instance. func GetGlobalCache() *DiskCache { globalCacheOnce.Do(func() { pureCache := pkgcache.New(defaultCacheDir) globalCache = &DiskCache{pureCache} // Load initial configs from database globalCache.ReloadConfig(context.Background()) // Start background routine to clean expired items every 10 minutes go globalCache.StartCleanupWorker(defaultCleanupInterval * time.Minute) }) return globalCache } // New creates a new DiskCache wrapper. func New(basePath string) *DiskCache { return &DiskCache{pkgcache.New(basePath)} } // ReloadConfig reloads policies from database configs dynamically. func (c *DiskCache) ReloadConfig(ctx context.Context) { // Ensure DB is initialized before querying if database.DB(ctx) == nil { return } // 1. Max Size maxSizeMB := int64(defaultMaxSizeMB) var maxVal string if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_max_size_mb").Pluck("value", &maxVal).Error; err == nil && maxVal != "" { if val, err := strconv.ParseInt(maxVal, 10, 64); err == nil && val > 0 { maxSizeMB = val } } // 2. Default TTL ttlMinutes := int64(defaultTTLMinutes) var ttlVal string if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_ttl_minutes").Pluck("value", &ttlVal).Error; err == nil && ttlVal != "" { if val, err := strconv.ParseInt(ttlVal, 10, 64); err == nil && val >= 0 { ttlMinutes = val } } // 3. LRU Enabled lruEnabled := true var lruVal string if err := database.DB(ctx).Table("w_system_configs").Where("key = ?", "disk_cache_lru_enabled").Pluck("value", &lruVal).Error; err == nil && lruVal != "" { if val, err := strconv.ParseBool(lruVal); err == nil { lruEnabled = val } } c.UpdatePolicy(maxSizeMB, ttlMinutes, lruEnabled) }