Refactor CacheLayer implementation by removing abstract class and its concrete implementations for Memcached and Redis, streamlining cache management.

This commit is contained in:
netkas 2025-03-13 13:57:10 -04:00
parent a11c8b463f
commit 99e811086c
Signed by: netkas
GPG key ID: 4D8629441B76E4CC
4 changed files with 13 additions and 351 deletions

View file

@ -1,90 +0,0 @@
<?php
namespace Socialbox\Abstracts;
use RuntimeException;
use Socialbox\Classes\CacheLayer\MemcachedCacheLayer;
use Socialbox\Classes\CacheLayer\RedisCacheLayer;
use Socialbox\Classes\Configuration;
abstract class CacheLayer
{
private static ?CacheLayer $instance = null;
/**
* Stores a value in the cache with an associated key and an optional time-to-live (TTL).
*
* @param string $key The key under which the value is stored.
* @param mixed $value The value to be stored.
* @param int $ttl Optional. The time-to-live for the cache entry in seconds. A value of 0 indicates no expiration.
* @return bool Returns true if the value was successfully set, false otherwise.
*/
public abstract function set(string $key, mixed $value, int $ttl=0): bool;
/**
* Retrieves a value from the cache with the specified key.
*
* @param string $key The key of the value to retrieve.
* @return mixed The value associated with the key, or null if the key does not exist.
*/
public abstract function get(string $key): mixed;
/**
* Deletes a value from the cache with the specified key.
*
* @param string $key The key of the value to delete.
* @return bool Returns true if the value was successfully deleted, false otherwise.
*/
public abstract function delete(string $key): bool;
/**
* Checks if a value exists in the cache with the specified key.
*
* @param string $key The key to check.
* @return bool Returns true if the key exists, false otherwise.
*/
public abstract function exists(string $key): bool;
/**
* Counts the number of items that start with the given prefix.
*
* @param string $prefix The prefix to search for.
* @return int The count of items starting with the provided prefix.
*/
public abstract function getPrefixCount(string $prefix): int;
/**
* Clears all values from the cache.
*
* @return bool Returns true if the cache was successfully cleared, false otherwise.
*/
public abstract function clear(): bool;
/**
* Retrieves the singleton instance of the cache layer.
*
* @return CacheLayer The singleton instance of the cache layer.
*/
public static function getInstance(): CacheLayer
{
if (self::$instance === null)
{
$engine = Configuration::getCacheConfiguration()->getEngine();
if ($engine === 'redis')
{
self::$instance = new RedisCacheLayer();
}
else if ($engine === 'memcached')
{
self::$instance = new MemcachedCacheLayer();
}
else
{
throw new RuntimeException('Invalid cache engine specified in the configuration, must be either "redis" or "memcached".');
}
}
return self::$instance;
}
}

View file

@ -1,18 +1,18 @@
<?php
namespace Socialbox\Classes;
namespace Socialbox\Classes;
class CacheLayer
{
private static CacheLayer $instance;
public static function getInstance(): CacheLayer
class CacheLayer
{
if (!isset(self::$instance))
{
self::$instance = new CacheLayer();
}
private static CacheLayer $instance;
return self::$instance;
public static function getInstance(): CacheLayer
{
if (!isset(self::$instance))
{
self::$instance = new CacheLayer();
}
return self::$instance;
}
}
}

View file

@ -1,113 +0,0 @@
<?php
namespace Socialbox\Classes\CacheLayer;
use Memcached;
use RuntimeException;
use Socialbox\Abstracts\CacheLayer;
use Socialbox\Classes\Configuration;
class MemcachedCacheLayer extends CacheLayer
{
private Memcached $memcached;
/**
* Memcached cache layer constructor.
*/
public function __construct()
{
if (!extension_loaded('memcached'))
{
throw new RuntimeException('The Memcached extension is not loaded in your PHP environment.');
}
$this->memcached = new Memcached();
$this->memcached->addServer(Configuration::getCacheConfiguration()->getHost(), Configuration::getCacheConfiguration()->getPort());
if(Configuration::getCacheConfiguration()->getUsername() !== null || Configuration::getCacheConfiguration()->getPassword() !== null)
{
$this->memcached->setSaslAuthData(Configuration::getCacheConfiguration()->getUsername(), Configuration::getCacheConfiguration()->getPassword());
}
}
/**
* @inheritDoc
*/
public function set(string $key, mixed $value, int $ttl = 0): bool
{
if (!$this->memcached->set($key, $value, $ttl))
{
throw new RuntimeException('Failed to set the value in the Memcached cache.');
}
return true;
}
/**
* @inheritDoc
*/
public function get(string $key): mixed
{
$result = $this->memcached->get($key);
if ($this->memcached->getResultCode() !== Memcached::RES_SUCCESS)
{
throw new RuntimeException('Failed to get the value from the Memcached cache.');
}
return $result;
}
/**
* @inheritDoc
*/
public function delete(string $key): bool
{
if (!$this->memcached->delete($key) && $this->memcached->getResultCode() !== Memcached::RES_NOTFOUND)
{
throw new RuntimeException('Failed to delete the value from the Memcached cache.');
}
return true;
}
/**
* @inheritDoc
*/
public function exists(string $key): bool
{
$this->memcached->get($key);
return $this->memcached->getResultCode() === Memcached::RES_SUCCESS;
}
/**
* @inheritDoc
*/
public function getPrefixCount(string $prefix): int
{
$stats = $this->memcached->getStats();
$count = 0;
foreach ($stats as $server => $data)
{
if (str_starts_with($server, $prefix))
{
$count += $data['curr_items'];
}
}
return $count;
}
/**
* @inheritDoc
*/
public function clear(): bool
{
if (!$this->memcached->flush())
{
throw new RuntimeException('Failed to clear the Memcached cache.');
}
return true;
}
}

View file

@ -1,135 +0,0 @@
<?php
namespace Socialbox\Classes\CacheLayer;
use Redis;
use RedisException;
use RuntimeException;
use Socialbox\Abstracts\CacheLayer;
use Socialbox\Classes\Configuration;
class RedisCacheLayer extends CacheLayer
{
private Redis $redis;
/**
* Redis cache layer constructor.
*/
public function __construct()
{
if (!extension_loaded('redis'))
{
throw new RuntimeException('The Redis extension is not loaded in your PHP environment.');
}
$this->redis = new Redis();
try
{
$this->redis->connect(Configuration::getCacheConfiguration()->getHost(), Configuration::getCacheConfiguration()->getPort());
if (Configuration::getCacheConfiguration()->getPassword() !== null)
{
$this->redis->auth(Configuration::getCacheConfiguration()->getPassword());
}
if (Configuration::getCacheConfiguration()->getDatabase() !== null)
{
$this->redis->select(Configuration::getCacheConfiguration()->getDatabase());
}
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to connect to the Redis server.', 0, $e);
}
}
/**
* @inheritDoc
*/
public function set(string $key, mixed $value, int $ttl = 0): bool
{
try
{
return $this->redis->set($key, $value, $ttl);
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to set the value in the Redis cache.', 0, $e);
}
}
/**
* @inheritDoc
*/
public function get(string $key): mixed
{
try
{
return $this->redis->get($key);
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to get the value from the Redis cache.', 0, $e);
}
}
/**
* @inheritDoc
*/
public function delete(string $key): bool
{
try
{
return $this->redis->del($key) > 0;
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to delete the value from the Redis cache.', 0, $e);
}
}
/**
* @inheritDoc
*/
public function exists(string $key): bool
{
try
{
return $this->redis->exists($key);
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to check if the key exists in the Redis cache.', 0, $e);
}
}
/**
* @inheritDoc
*/
public function getPrefixCount(string $prefix): int
{
try
{
return count($this->redis->keys($prefix . '*'));
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to get the count of keys with the specified prefix in the Redis cache.', 0, $e);
}
}
/**
* @inheritDoc
*/
public function clear(): bool
{
try
{
return $this->redis->flushAll();
}
catch (RedisException $e)
{
throw new RuntimeException('Failed to clear the Redis cache.', 0, $e);
}
}
}