mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-30 06:16:37 +08:00
381c79417e
Four long-running goroutines were launched with a bare go statement, so a
panic in any of them took down the whole process: the RAM cache's expired-key
eviction, the batch writer's flush worker, the disk cache cleanup worker and
the PoW memory store sweeper. Route them through util.Go.
The architecture gate only grepped for 'go func(', which is why the named-call
form went unnoticed; widen it to cover both launch styles.
99 lines
2.8 KiB
Go
99 lines
2.8 KiB
Go
// 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"
|
|
"Wavelet/pkg/util"
|
|
)
|
|
|
|
// 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
|
|
util.Go(func() { 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 getDB(ctx) == nil {
|
|
return
|
|
}
|
|
|
|
// 1. Max Size
|
|
maxSizeMB := int64(defaultMaxSizeMB)
|
|
var maxVal string
|
|
if err := getDB(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 := getDB(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 := getDB(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)
|
|
}
|