Refactor CacheLayer implementation by removing abstract class and its concrete implementations for Memcached and Redis, streamlining cache management.
This commit is contained in:
parent
a11c8b463f
commit
99e811086c
4 changed files with 13 additions and 351 deletions
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Socialbox\Classes;
|
namespace Socialbox\Classes;
|
||||||
|
|
||||||
class CacheLayer
|
class CacheLayer
|
||||||
{
|
|
||||||
private static CacheLayer $instance;
|
|
||||||
|
|
||||||
public static function getInstance(): CacheLayer
|
|
||||||
{
|
{
|
||||||
if (!isset(self::$instance))
|
private static CacheLayer $instance;
|
||||||
{
|
|
||||||
self::$instance = new CacheLayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$instance;
|
public static function getInstance(): CacheLayer
|
||||||
|
{
|
||||||
|
if (!isset(self::$instance))
|
||||||
|
{
|
||||||
|
self::$instance = new CacheLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue