Yadav122's picture
Initial deployment of MailPilot application
7a88b43
import pickle
from logging import Logger
from pymemcache.client.base import Client
from app.core.config import settings
from app.core.exceptions.base_exception import (
ConnectionException,
CouldNotEditMemcache,
KeyNotFoundException,
)
class Cache:
"""
A generic cache class for interacting with Memcached.
"""
def __init__(self, logger: Logger) -> None:
"""
Initialize the cache connection.
:param logger: Logger instance for logging operations
"""
# Load Memcache config from .env
self.host = settings.CACHE_HOST
self.port = settings.CACHE_HOST
self.default_ttl = settings.CACHE_TTL
self.client = self._initialize_connection()
self.logger = logger
def _initialize_connection(self):
"""
Establish a connection to the Memcached server.
:return: Client instance
:raises ConnectionException: If the connection cannot be established
"""
client = Client((self.host, self.port))
if client:
self.logger.info(f"Connected to Memcached at {self.host}: {self.port}")
return client
else:
raise ConnectionException("Could not connect to Memcached server.")
def add(self, key: str, value: dict):
"""
Add an item to the cache.
:param key: Cache key
:param value: Value to store (serialized using pickle)
:raises CouldNotEditMemcache: If the item could not be added
"""
serialized_value = pickle.dumps(value)
res = self.client.add(key, serialized_value, expire=self.default_ttl)
if not res:
raise CouldNotEditMemcache(f"Could not add key {key} to cache.")
self.logger.info(f"Added {key} to cache.")
def get(self, key: str):
"""
Retrieve an item from the cache.
:param key: Cache key
:return: Deserialized value
:raises KeyNotFoundException: If the key is not found in the cache
"""
byte_string = self.get_raw(key)
return pickle.loads(byte_string)
def get_raw(self, key: str):
"""
Retrieve the raw byte string from the cache.
:param key: Cache key
:return: Raw byte string
:raises KeyNotFoundException: If the key is not found in the cache
"""
byte_string = self.client.get(key)
if not byte_string:
raise KeyNotFoundException(f"Key {key} not found in cache.") # noqa: E713
return byte_string
def delete(self, key: str):
"""
Delete an item from the cache.
:param key: Cache key
:return: Result of the delete operation
:raises CouldNotEditMemcache: If the item could not be deleted
"""
res = self.client.delete(key)
if not res:
raise CouldNotEditMemcache(f"Could not delete key {key} from cache.")
self.logger.info(f"Deleted {key} from cache.")
return res
def update(self, key: str, value: dict):
"""
Update an item in the cache.
:param key: Cache key
:param value: New value to store (serialized using pickle)
:raises CouldNotEditMemcache: If the item could not be updated
"""
serialized_value = pickle.dumps(value)
res = self.client.set(key, serialized_value, expire=self.default_ttl)
if not res:
raise CouldNotEditMemcache(f"Could not update key {key} in cache.")
self.logger.info(f"Updated {key} in cache.")