fixup! fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi.

This commit is contained in:
2025-10-20 00:52:08 +01:00
parent fdde481925
commit 5a30eff192
2 changed files with 27 additions and 10 deletions
+5 -3
View File
@@ -93,7 +93,8 @@ type UniversalCache struct {
logger *Logger
// Backend for distributed caching (NEW)
backend backends.CacheBackend
backend backends.CacheBackend
ownsBackend bool // If true, cache should close backend on Close(); if false, backend is shared
// Memory management
currentSize int64
@@ -120,6 +121,7 @@ func NewUniversalCache(config UniversalCacheConfig) *UniversalCache {
func NewUniversalCacheWithBackend(config UniversalCacheConfig, cacheBackend backends.CacheBackend) *UniversalCache {
cache := createUniversalCache(config)
cache.backend = cacheBackend
cache.ownsBackend = false // Shared backend, managed externally
return cache
}
@@ -517,8 +519,8 @@ func (c *UniversalCache) Close() error {
// Clear all items
c.Clear()
// Close backend if present
if c.backend != nil {
// Close backend only if this cache owns it (not shared)
if c.backend != nil && c.ownsBackend {
if err := c.backend.Close(); err != nil {
c.logger.Infof("Failed to close cache backend: %v", err)
}
+22 -7
View File
@@ -15,8 +15,9 @@ type UniversalCacheManager struct {
metadataCache *UniversalCache
jwkCache *UniversalCache
sessionCache *UniversalCache
introspectionCache *UniversalCache // OAuth 2.0 Token Introspection cache (RFC 7662)
tokenTypeCache *UniversalCache // Cache for token type detection results
introspectionCache *UniversalCache // OAuth 2.0 Token Introspection cache (RFC 7662)
tokenTypeCache *UniversalCache // Cache for token type detection results
sharedBackend backends.CacheBackend // Shared backend (Redis) that should be closed by manager, not individual caches
mu sync.RWMutex
logger *Logger
}
@@ -156,17 +157,18 @@ func initializeCachesWithRedis(manager *UniversalCacheManager, logger *Logger, r
EnableMetrics: true,
}
var redisBackend backends.CacheBackend
var err error
// Create Redis backend with resilience features if enabled
redisBackend, err = backends.NewRedisBackend(redisBackendConfig)
// Use concrete type to avoid Yaegi reflection issues with interface assignment
// The concrete type will be automatically converted to interface when needed
baseBackend, err := backends.NewRedisBackend(redisBackendConfig)
if err != nil {
logger.Errorf("Failed to create Redis backend: %v. Falling back to memory-only mode.", err)
initializeDefaultCaches(manager, logger)
return
}
// Build the backend with optional wrappers
var redisBackend backends.CacheBackend = baseBackend
// Wrap with circuit breaker if enabled
if redisConfig.EnableCircuitBreaker {
cbConfig := resilience.DefaultCircuitBreakerConfig()
@@ -196,6 +198,9 @@ func initializeCachesWithRedis(manager *UniversalCacheManager, logger *Logger, r
logger.Info("Redis backend wrapped with health checker")
}
// Store the fully-wrapped shared backend in the manager so it can be closed properly
manager.sharedBackend = redisBackend
// Decide which backend to use based on cache mode
var createBackend func(cacheType CacheType) backends.CacheBackend
@@ -364,6 +369,7 @@ func (m *UniversalCacheManager) Close() error {
m.mu.Lock()
defer m.mu.Unlock()
// Close all caches first (they won't close the shared backend)
for _, cache := range []*UniversalCache{
m.tokenCache, m.blacklistCache, m.metadataCache, m.jwkCache, m.sessionCache, m.introspectionCache, m.tokenTypeCache,
} {
@@ -372,6 +378,15 @@ func (m *UniversalCacheManager) Close() error {
}
}
// Now close the shared backend if present
if m.sharedBackend != nil {
if err := m.sharedBackend.Close(); err != nil {
m.logger.Infof("Failed to close shared cache backend: %v", err)
} else {
m.logger.Info("UniversalCacheManager: Closed shared backend")
}
}
m.logger.Info("UniversalCacheManager: Closed all caches")
return nil
}