File size: 2,747 Bytes
a282d4b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import os
import json
import time
from threading import Lock

try:
    import redis
except ImportError:
    redis = None

class MemoryCache:
    def __init__(self):
        self._cache = {}
        self._lock = Lock()

    def get(self, key):
        with self._lock:
            if key not in self._cache:
                return None
            val, expiry = self._cache[key]
            if expiry is not None and time.time() > expiry:
                del self._cache[key]
                return None
            return val

    def set(self, key, value, ttl=None):
        with self._lock:
            expiry = time.time() + ttl if ttl is not None else None
            self._cache[key] = (value, expiry)

    def delete(self, key):
        with self._lock:
            if key in self._cache:
                del self._cache[key]

class CacheManager:
    def __init__(self):
        self.redis_url = os.getenv("REDIS_URL", "redis://localhost:6379/0")
        self.redis_client = None
        self.use_redis = False
        
        if redis is not None:
            try:
                self.redis_client = redis.Redis.from_url(self.redis_url, socket_timeout=1.0)
                # Test connection
                self.redis_client.ping()
                self.use_redis = True
                print("Connected to Redis successfully.")
            except Exception as e:
                print(f"Redis connection failed ({e}). Falling back to in-memory cache.")
        else:
            print("Redis library not installed. Falling back to in-memory cache.")
            
        self.memory_cache = MemoryCache()

    def get(self, key: str):
        if self.use_redis:
            try:
                val = self.redis_client.get(key)
                if val:
                    return json.loads(val.decode('utf-8'))
            except Exception as e:
                # Fallback to memory on Redis error during operation
                print(f"Redis get failed ({e}). Using memory cache fallback.")
        return self.memory_cache.get(key)

    def set(self, key: str, value, ttl: int = None):
        if self.use_redis:
            try:
                self.redis_client.set(key, json.dumps(value), ex=ttl)
                return
            except Exception as e:
                print(f"Redis set failed ({e}). Using memory cache fallback.")
        self.memory_cache.set(key, value, ttl)

    def delete(self, key: str):
        if self.use_redis:
            try:
                self.redis_client.delete(key)
                return
            except Exception as e:
                print(f"Redis delete failed ({e}). Using memory cache fallback.")
        self.memory_cache.delete(key)

# Global cache instance
cache = CacheManager()