use Asika\SimpleConsole\CommandArgsException;
use Friendica\App;
-use Friendica\Core\Cache\ICacheDriver;
+use Friendica\Core\Cache\ICache;
use Friendica\Core\Config\Configuration;
use Friendica\Factory\CacheDriverFactory;
use RuntimeException;
private $cacheDriverName;
/**
- * @var ICacheDriver
+ * @var ICache
*/
private $cache;
return $help;
}
- public function __construct(App\Mode $appMode, Configuration $config, ICacheDriver $cache, array $argv = null)
+ public function __construct(App\Mode $appMode, Configuration $config, ICache $cache, array $argv = null)
{
parent::__construct($argv);
if (count($this->args) >= 3) {
$key = $this->getArgument(1);
$value = $this->getArgument(2);
- $duration = intval($this->getArgument(3, ICacheDriver::FIVE_MINUTES));
+ $duration = intval($this->getArgument(3, ICache::FIVE_MINUTES));
if (is_array($this->cache->get($key))) {
throw new RuntimeException("$key is an array and can't be set using this command.");
namespace Friendica\Core;
use Friendica\BaseObject;
-use Friendica\Core\Cache\ICacheDriver;
+use Friendica\Core\Cache\ICache;
/**
* @brief Class for storing data for a short time
*/
class Cache extends BaseObject
{
- /** @deprecated Use ICacheDriver::MONTH */
- const MONTH = ICacheDriver::MONTH;
- /** @deprecated Use ICacheDriver::WEEK */
- const WEEK = 604800;
- /** @deprecated Use ICacheDriver::DAY */
- const DAY = 86400;
- /** @deprecated Use ICacheDriver::HOUR */
- const HOUR = 3600;
- /** @deprecated Use ICacheDriver::HALF_HOUR */
- const HALF_HOUR = 1800;
- /** @deprecated Use ICacheDriver::QUARTER_HOUR */
- const QUARTER_HOUR = 900;
- /** @deprecated Use ICacheDriver::FIVE_MINUTES */
- const FIVE_MINUTES = 300;
- /** @deprecated Use ICacheDriver::MINUTE */
- const MINUTE = 60;
- /** @deprecated Use ICacheDriver::INFINITE */
- const INFINITE = 0;
+ /** @deprecated Use ICache::MONTH */
+ const MONTH = ICache::MONTH;
+ /** @deprecated Use ICache::WEEK */
+ const WEEK = ICache::WEEK;
+ /** @deprecated Use ICache::DAY */
+ const DAY = ICache::DAY;
+ /** @deprecated Use ICache::HOUR */
+ const HOUR = ICache::HOUR;
+ /** @deprecated Use ICache::HALF_HOUR */
+ const HALF_HOUR = ICache::HALF_HOUR;
+ /** @deprecated Use ICache::QUARTER_HOUR */
+ const QUARTER_HOUR = ICache::QUARTER_HOUR;
+ /** @deprecated Use ICache::FIVE_MINUTES */
+ const FIVE_MINUTES = ICache::FIVE_MINUTES;
+ /** @deprecated Use ICache::MINUTE */
+ const MINUTE = ICache::MINUTE;
+ /** @deprecated Use ICache::INFINITE */
+ const INFINITE = ICache::INFINITE;
/**
* @brief Returns all the cache keys sorted alphabetically
*/
public static function getAllKeys($prefix = null)
{
- return self::getClass(ICacheDriver::class)->getAllKeys($prefix);
+ return self::getClass(ICache::class)->getAllKeys($prefix);
}
/**
*/
public static function get($key)
{
- return self::getClass(ICacheDriver::class)->get($key);
+ return self::getClass(ICache::class)->get($key);
}
/**
* @return bool
* @throws \Exception
*/
- public static function set($key, $value, $duration = ICacheDriver::MONTH)
+ public static function set($key, $value, $duration = ICache::MONTH)
{
- return self::getClass(ICacheDriver::class)->set($key, $value, $duration);
+ return self::getClass(ICache::class)->set($key, $value, $duration);
}
/**
*/
public static function delete($key)
{
- return self::getClass(ICacheDriver::class)->delete($key);
+ return self::getClass(ICache::class)->delete($key);
}
/**
*/
public static function clear($outdated = true)
{
- return self::getClass(ICacheDriver::class)->clear($outdated);
+ return self::getClass(ICache::class)->clear($outdated);
}
}
use Friendica\Core\Cache;
/**
- * APCu Cache Driver.
+ * APCu Cache.
*
* @author Philipp Holzer <admin@philipp.info>
*/
-class APCuCache extends AbstractCacheDriver implements IMemoryCacheDriver
+class APCuCache extends AbstractCache implements IMemoryCache
{
use TraitCompareSet;
use TraitCompareDelete;
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+/**
+ * Abstract class for common used functions
+ *
+ * Class AbstractCache
+ *
+ * @package Friendica\Core\Cache
+ */
+abstract class AbstractCache implements ICache
+{
+ /**
+ * @var string The hostname
+ */
+ private $hostName;
+
+ public function __construct(string $hostName)
+ {
+ $this->hostName = $hostName;
+ }
+
+ /**
+ * Returns the prefix (to avoid namespace conflicts)
+ *
+ * @return string
+ * @throws \Exception
+ */
+ protected function getPrefix()
+ {
+ // We fetch with the hostname as key to avoid problems with other applications
+ return $this->hostName;
+ }
+
+ /**
+ * @param string $key The original key
+ * @return string The cache key used for the cache
+ * @throws \Exception
+ */
+ protected function getCacheKey($key)
+ {
+ return $this->getPrefix() . ":" . $key;
+ }
+
+ /**
+ * @param array $keys A list of cached keys
+ * @return array A list of original keys
+ */
+ protected function getOriginalKeys($keys)
+ {
+ if (empty($keys)) {
+ return [];
+ } else {
+ // Keys are prefixed with the node hostname, let's remove it
+ array_walk($keys, function (&$value) {
+ $value = preg_replace('/^' . $this->hostName . ':/', '', $value);
+ });
+
+ sort($keys);
+
+ return $keys;
+ }
+ }
+
+ /**
+ * Filters the keys of an array with a given prefix
+ * Returns the filtered keys as an new array
+ *
+ * @param array $array The array, which should get filtered
+ * @param string|null $prefix The prefix (if null, all keys will get returned)
+ *
+ * @return array The filtered array with just the keys
+ */
+ protected function filterArrayKeysByPrefix($array, $prefix = null)
+ {
+ if (empty($prefix)) {
+ return array_keys($array);
+ } else {
+ $result = [];
+
+ foreach (array_keys($array) as $key) {
+ if (strpos($key, $prefix) === 0) {
+ array_push($result, $key);
+ }
+ }
+
+ return $result;
+ }
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-/**
- * Abstract class for common used functions
- *
- * Class AbstractCacheDriver
- *
- * @package Friendica\Core\Cache
- */
-abstract class AbstractCacheDriver implements ICacheDriver
-{
- /**
- * @var string The hostname
- */
- private $hostName;
-
- public function __construct(string $hostName)
- {
- $this->hostName = $hostName;
- }
-
- /**
- * Returns the prefix (to avoid namespace conflicts)
- *
- * @return string
- * @throws \Exception
- */
- protected function getPrefix()
- {
- // We fetch with the hostname as key to avoid problems with other applications
- return $this->hostName;
- }
-
- /**
- * @param string $key The original key
- * @return string The cache key used for the cache
- * @throws \Exception
- */
- protected function getCacheKey($key)
- {
- return $this->getPrefix() . ":" . $key;
- }
-
- /**
- * @param array $keys A list of cached keys
- * @return array A list of original keys
- */
- protected function getOriginalKeys($keys)
- {
- if (empty($keys)) {
- return [];
- } else {
- // Keys are prefixed with the node hostname, let's remove it
- array_walk($keys, function (&$value) {
- $value = preg_replace('/^' . $this->hostName . ':/', '', $value);
- });
-
- sort($keys);
-
- return $keys;
- }
- }
-
- /**
- * Filters the keys of an array with a given prefix
- * Returns the filtered keys as an new array
- *
- * @param array $array The array, which should get filtered
- * @param string|null $prefix The prefix (if null, all keys will get returned)
- *
- * @return array The filtered array with just the keys
- */
- protected function filterArrayKeysByPrefix($array, $prefix = null)
- {
- if (empty($prefix)) {
- return array_keys($array);
- } else {
- $result = [];
-
- foreach (array_keys($array) as $key) {
- if (strpos($key, $prefix) === 0) {
- array_push($result, $key);
- }
- }
-
- return $result;
- }
- }
-}
use Friendica\Core\Cache;
/**
- * Implementation of the IMemoryCacheDriver mainly for testing purpose
+ * Implementation of the IMemoryCache mainly for testing purpose
*
* Class ArrayCache
*
* @package Friendica\Core\Cache
*/
-class ArrayCache extends AbstractCacheDriver implements IMemoryCacheDriver
+class ArrayCache extends AbstractCache implements IMemoryCache
{
use TraitCompareDelete;
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+use Friendica\Core\Cache;
+use Friendica\Database\Database;
+use Friendica\Util\DateTimeFormat;
+
+/**
+ * Database Cache
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class DatabaseCache extends AbstractCache implements ICache
+{
+ /**
+ * @var Database
+ */
+ private $dba;
+
+ public function __construct(string $hostname, Database $dba)
+ {
+ parent::__construct($hostname);
+
+ $this->dba = $dba;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function getAllKeys($prefix = null)
+ {
+ if (empty($prefix)) {
+ $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+ } else {
+ $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+ }
+
+ $stmt = $this->dba->select('cache', ['k'], $where);
+
+ $keys = [];
+ while ($key = $this->dba->fetch($stmt)) {
+ array_push($keys, $key['k']);
+ }
+ $this->dba->close($stmt);
+
+ return $keys;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function get($key)
+ {
+ $cache = $this->dba->selectFirst('cache', ['v'], ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, DateTimeFormat::utcNow()]);
+
+ if ($this->dba->isResult($cache)) {
+ $cached = $cache['v'];
+ $value = @unserialize($cached);
+
+ // Only return a value if the serialized value is valid.
+ // We also check if the db entry is a serialized
+ // boolean 'false' value (which we want to return).
+ if ($cached === serialize(false) || $value !== false) {
+ return $value;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ if ($ttl > 0) {
+ $fields = [
+ 'v' => serialize($value),
+ 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds'),
+ 'updated' => DateTimeFormat::utcNow()
+ ];
+ } else {
+ $fields = [
+ 'v' => serialize($value),
+ 'expires' => -1,
+ 'updated' => DateTimeFormat::utcNow()
+ ];
+ }
+
+ return $this->dba->update('cache', $fields, ['k' => $key], true);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function delete($key)
+ {
+ return $this->dba->delete('cache', ['k' => $key]);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function clear($outdated = true)
+ {
+ if ($outdated) {
+ return $this->dba->delete('cache', ['`expires` < NOW()']);
+ } else {
+ return $this->dba->delete('cache', ['`k` IS NOT NULL ']);
+ }
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-use Friendica\Core\Cache;
-use Friendica\Database\Database;
-use Friendica\Util\DateTimeFormat;
-
-/**
- * Database Cache Driver
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class DatabaseCacheDriver extends AbstractCacheDriver implements ICacheDriver
-{
- /**
- * @var Database
- */
- private $dba;
-
- public function __construct(string $hostname, Database $dba)
- {
- parent::__construct($hostname);
-
- $this->dba = $dba;
- }
-
- /**
- * (@inheritdoc)
- */
- public function getAllKeys($prefix = null)
- {
- if (empty($prefix)) {
- $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
- } else {
- $where = ['`expires` >= ? AND `k` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
- }
-
- $stmt = $this->dba->select('cache', ['k'], $where);
-
- $keys = [];
- while ($key = $this->dba->fetch($stmt)) {
- array_push($keys, $key['k']);
- }
- $this->dba->close($stmt);
-
- return $keys;
- }
-
- /**
- * (@inheritdoc)
- */
- public function get($key)
- {
- $cache = $this->dba->selectFirst('cache', ['v'], ['`k` = ? AND (`expires` >= ? OR `expires` = -1)', $key, DateTimeFormat::utcNow()]);
-
- if ($this->dba->isResult($cache)) {
- $cached = $cache['v'];
- $value = @unserialize($cached);
-
- // Only return a value if the serialized value is valid.
- // We also check if the db entry is a serialized
- // boolean 'false' value (which we want to return).
- if ($cached === serialize(false) || $value !== false) {
- return $value;
- }
- }
-
- return null;
- }
-
- /**
- * (@inheritdoc)
- */
- public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- if ($ttl > 0) {
- $fields = [
- 'v' => serialize($value),
- 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds'),
- 'updated' => DateTimeFormat::utcNow()
- ];
- } else {
- $fields = [
- 'v' => serialize($value),
- 'expires' => -1,
- 'updated' => DateTimeFormat::utcNow()
- ];
- }
-
- return $this->dba->update('cache', $fields, ['k' => $key], true);
- }
-
- /**
- * (@inheritdoc)
- */
- public function delete($key)
- {
- return $this->dba->delete('cache', ['k' => $key]);
- }
-
- /**
- * (@inheritdoc)
- */
- public function clear($outdated = true)
- {
- if ($outdated) {
- return $this->dba->delete('cache', ['`expires` < NOW()']);
- } else {
- return $this->dba->delete('cache', ['`k` IS NOT NULL ']);
- }
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+/**
+ * Cache Interface
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+interface ICache
+{
+ const MONTH = 2592000;
+ const WEEK = 604800;
+ const DAY = 86400;
+ const HOUR = 3600;
+ const HALF_HOUR = 1800;
+ const QUARTER_HOUR = 900;
+ const FIVE_MINUTES = 300;
+ const MINUTE = 60;
+ const INFINITE = 0;
+
+ /**
+ * Lists all cache keys
+ *
+ * @param string prefix optional a prefix to search
+ *
+ * @return array Empty if it isn't supported by the cache driver
+ */
+ public function getAllKeys($prefix = null);
+
+ /**
+ * Fetches cached data according to the key
+ *
+ * @param string $key The key to the cached data
+ *
+ * @return mixed Cached $value or "null" if not found
+ */
+ public function get($key);
+
+ /**
+ * Stores data in the cache identified by the key. The input $value can have multiple formats.
+ *
+ * @param string $key The cache key
+ * @param mixed $value The value to store
+ * @param integer $ttl The cache lifespan, must be one of the Cache constants
+ *
+ * @return bool
+ */
+ public function set($key, $value, $ttl = self::FIVE_MINUTES);
+
+ /**
+ * Delete a key from the cache
+ *
+ * @param string $key The cache key
+ *
+ * @return bool
+ */
+ public function delete($key);
+
+ /**
+ * Remove outdated data from the cache
+ * @param boolean $outdated just remove outdated values
+ *
+ * @return bool
+ */
+ public function clear($outdated = true);
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-/**
- * Cache Driver Interface
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-interface ICacheDriver
-{
- const MONTH = 2592000;
- const WEEK = 604800;
- const DAY = 86400;
- const HOUR = 3600;
- const HALF_HOUR = 1800;
- const QUARTER_HOUR = 900;
- const FIVE_MINUTES = 300;
- const MINUTE = 60;
- const INFINITE = 0;
-
- /**
- * Lists all cache keys
- *
- * @param string prefix optional a prefix to search
- *
- * @return array Empty if it isn't supported by the cache driver
- */
- public function getAllKeys($prefix = null);
-
- /**
- * Fetches cached data according to the key
- *
- * @param string $key The key to the cached data
- *
- * @return mixed Cached $value or "null" if not found
- */
- public function get($key);
-
- /**
- * Stores data in the cache identified by the key. The input $value can have multiple formats.
- *
- * @param string $key The cache key
- * @param mixed $value The value to store
- * @param integer $ttl The cache lifespan, must be one of the Cache constants
- *
- * @return bool
- */
- public function set($key, $value, $ttl = self::FIVE_MINUTES);
-
- /**
- * Delete a key from the cache
- *
- * @param string $key The cache key
- *
- * @return bool
- */
- public function delete($key);
-
- /**
- * Remove outdated data from the cache
- * @param boolean $outdated just remove outdated values
- *
- * @return bool
- */
- public function clear($outdated = true);
-}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+/**
+ * This interface defines methods for Memory-Caches only
+ *
+ * Interface IMemoryCache
+ *
+ * @package Friendica\Core\Cache
+ */
+interface IMemoryCache extends ICache
+{
+ /**
+ * Sets a value if it's not already stored
+ *
+ * @param string $key The cache key
+ * @param mixed $value The old value we know from the cache
+ * @param int $ttl The cache lifespan, must be one of the Cache constants
+ * @return bool
+ */
+ public function add($key, $value, $ttl = ICache::FIVE_MINUTES);
+
+ /**
+ * Compares if the old value is set and sets the new value
+ *
+ * @param string $key The cache key
+ * @param mixed $oldValue The old value we know from the cache
+ * @param mixed $newValue The new value we want to set
+ * @param int $ttl The cache lifespan, must be one of the Cache constants
+ *
+ * @return bool
+ */
+ public function compareSet($key, $oldValue, $newValue, $ttl = ICache::FIVE_MINUTES);
+
+ /**
+ * Compares if the old value is set and removes it
+ *
+ * @param string $key The cache key
+ * @param mixed $value The old value we know and want to delete
+ * @return bool
+ */
+ public function compareDelete($key, $value);
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-/**
- * This interface defines methods for Memory-Caches only
- *
- * Interface IMemoryCacheDriver
- *
- * @package Friendica\Core\Cache
- */
-interface IMemoryCacheDriver extends ICacheDriver
-{
- /**
- * Sets a value if it's not already stored
- *
- * @param string $key The cache key
- * @param mixed $value The old value we know from the cache
- * @param int $ttl The cache lifespan, must be one of the Cache constants
- * @return bool
- */
- public function add($key, $value, $ttl = ICacheDriver::FIVE_MINUTES);
-
- /**
- * Compares if the old value is set and sets the new value
- *
- * @param string $key The cache key
- * @param mixed $oldValue The old value we know from the cache
- * @param mixed $newValue The new value we want to set
- * @param int $ttl The cache lifespan, must be one of the Cache constants
- *
- * @return bool
- */
- public function compareSet($key, $oldValue, $newValue, $ttl = ICacheDriver::FIVE_MINUTES);
-
- /**
- * Compares if the old value is set and removes it
- *
- * @param string $key The cache key
- * @param mixed $value The old value we know and want to delete
- * @return bool
- */
- public function compareDelete($key, $value);
-}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+use Exception;
+use Friendica\Core\Cache;
+use Friendica\Core\Config\Configuration;
+use Memcache;
+
+/**
+ * Memcache Cache
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class MemcacheCache extends AbstractCache implements IMemoryCache
+{
+ use TraitCompareSet;
+ use TraitCompareDelete;
+
+ /**
+ * @var Memcache
+ */
+ private $memcache;
+
+ /**
+ * @throws Exception
+ */
+ public function __construct(string $hostname, Configuration $config)
+ {
+ if (!class_exists('Memcache', false)) {
+ throw new Exception('Memcache class isn\'t available');
+ }
+
+ parent::__construct($hostname);
+
+ $this->memcache = new Memcache();
+
+ $memcache_host = $config->get('system', 'memcache_host');
+ $memcache_port = $config->get('system', 'memcache_port');
+
+ if (!$this->memcache->connect($memcache_host, $memcache_port)) {
+ throw new Exception('Expected Memcache server at ' . $memcache_host . ':' . $memcache_port . ' isn\'t available');
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function getAllKeys($prefix = null)
+ {
+ $keys = [];
+ $allSlabs = $this->memcache->getExtendedStats('slabs');
+ foreach ($allSlabs as $slabs) {
+ foreach (array_keys($slabs) as $slabId) {
+ $cachedump = $this->memcache->getExtendedStats('cachedump', (int)$slabId);
+ foreach ($cachedump as $key => $arrVal) {
+ if (!is_array($arrVal)) {
+ continue;
+ }
+ $keys = array_merge($keys, array_keys($arrVal));
+ }
+ }
+ }
+
+ $keys = $this->getOriginalKeys($keys);
+
+ return $this->filterArrayKeysByPrefix($keys, $prefix);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function get($key)
+ {
+ $return = null;
+ $cachekey = $this->getCacheKey($key);
+
+ // We fetch with the hostname as key to avoid problems with other applications
+ $cached = $this->memcache->get($cachekey);
+
+ // @see http://php.net/manual/en/memcache.get.php#84275
+ if (is_bool($cached) || is_double($cached) || is_long($cached)) {
+ return $return;
+ }
+
+ $value = @unserialize($cached);
+
+ // Only return a value if the serialized value is valid.
+ // We also check if the db entry is a serialized
+ // boolean 'false' value (which we want to return).
+ if ($cached === serialize(false) || $value !== false) {
+ $return = $value;
+ }
+
+ return $return;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+
+ // We store with the hostname as key to avoid problems with other applications
+ if ($ttl > 0) {
+ return $this->memcache->set(
+ $cachekey,
+ serialize($value),
+ MEMCACHE_COMPRESSED,
+ time() + $ttl
+ );
+ } else {
+ return $this->memcache->set(
+ $cachekey,
+ serialize($value),
+ MEMCACHE_COMPRESSED
+ );
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function delete($key)
+ {
+ $cachekey = $this->getCacheKey($key);
+ return $this->memcache->delete($cachekey);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function clear($outdated = true)
+ {
+ if ($outdated) {
+ return true;
+ } else {
+ return $this->memcache->flush();
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+ return $this->memcache->add($cachekey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-use Exception;
-use Friendica\Core\Cache;
-use Friendica\Core\Config\Configuration;
-use Memcache;
-
-/**
- * Memcache Cache Driver
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class MemcacheCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
-{
- use TraitCompareSet;
- use TraitCompareDelete;
-
- /**
- * @var Memcache
- */
- private $memcache;
-
- /**
- * @throws Exception
- */
- public function __construct(string $hostname, Configuration $config)
- {
- if (!class_exists('Memcache', false)) {
- throw new Exception('Memcache class isn\'t available');
- }
-
- parent::__construct($hostname);
-
- $this->memcache = new Memcache();
-
- $memcache_host = $config->get('system', 'memcache_host');
- $memcache_port = $config->get('system', 'memcache_port');
-
- if (!$this->memcache->connect($memcache_host, $memcache_port)) {
- throw new Exception('Expected Memcache server at ' . $memcache_host . ':' . $memcache_port . ' isn\'t available');
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function getAllKeys($prefix = null)
- {
- $keys = [];
- $allSlabs = $this->memcache->getExtendedStats('slabs');
- foreach ($allSlabs as $slabs) {
- foreach (array_keys($slabs) as $slabId) {
- $cachedump = $this->memcache->getExtendedStats('cachedump', (int)$slabId);
- foreach ($cachedump as $key => $arrVal) {
- if (!is_array($arrVal)) {
- continue;
- }
- $keys = array_merge($keys, array_keys($arrVal));
- }
- }
- }
-
- $keys = $this->getOriginalKeys($keys);
-
- return $this->filterArrayKeysByPrefix($keys, $prefix);
- }
-
- /**
- * (@inheritdoc)
- */
- public function get($key)
- {
- $return = null;
- $cachekey = $this->getCacheKey($key);
-
- // We fetch with the hostname as key to avoid problems with other applications
- $cached = $this->memcache->get($cachekey);
-
- // @see http://php.net/manual/en/memcache.get.php#84275
- if (is_bool($cached) || is_double($cached) || is_long($cached)) {
- return $return;
- }
-
- $value = @unserialize($cached);
-
- // Only return a value if the serialized value is valid.
- // We also check if the db entry is a serialized
- // boolean 'false' value (which we want to return).
- if ($cached === serialize(false) || $value !== false) {
- $return = $value;
- }
-
- return $return;
- }
-
- /**
- * (@inheritdoc)
- */
- public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
-
- // We store with the hostname as key to avoid problems with other applications
- if ($ttl > 0) {
- return $this->memcache->set(
- $cachekey,
- serialize($value),
- MEMCACHE_COMPRESSED,
- time() + $ttl
- );
- } else {
- return $this->memcache->set(
- $cachekey,
- serialize($value),
- MEMCACHE_COMPRESSED
- );
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function delete($key)
- {
- $cachekey = $this->getCacheKey($key);
- return $this->memcache->delete($cachekey);
- }
-
- /**
- * (@inheritdoc)
- */
- public function clear($outdated = true)
- {
- if ($outdated) {
- return true;
- } else {
- return $this->memcache->flush();
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
- return $this->memcache->add($cachekey, serialize($value), MEMCACHE_COMPRESSED, $ttl);
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+use Exception;
+use Friendica\Core\Cache;
+use Friendica\Core\Config\Configuration;
+use Memcached;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Memcached Cache
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ */
+class MemcachedCache extends AbstractCache implements IMemoryCache
+{
+ use TraitCompareSet;
+ use TraitCompareDelete;
+
+ /**
+ * @var \Memcached
+ */
+ private $memcached;
+
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
+ /**
+ * Due to limitations of the INI format, the expected configuration for Memcached servers is the following:
+ * array {
+ * 0 => "hostname, port(, weight)",
+ * 1 => ...
+ * }
+ *
+ * @param array $memcached_hosts
+ * @throws \Exception
+ */
+ public function __construct(string $hostname, Configuration $config, LoggerInterface $logger)
+ {
+ if (!class_exists('Memcached', false)) {
+ throw new Exception('Memcached class isn\'t available');
+ }
+
+ parent::__construct($hostname);
+
+ $this->logger = $logger;
+
+ $this->memcached = new Memcached();
+
+ $memcached_hosts = $config->get('system', 'memcached_hosts');
+
+ array_walk($memcached_hosts, function (&$value) {
+ if (is_string($value)) {
+ $value = array_map('trim', explode(',', $value));
+ }
+ });
+
+ $this->memcached->addServers($memcached_hosts);
+
+ if (count($this->memcached->getServerList()) == 0) {
+ throw new Exception('Expected Memcached servers aren\'t available, config:' . var_export($memcached_hosts, true));
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function getAllKeys($prefix = null)
+ {
+ $keys = $this->getOriginalKeys($this->memcached->getAllKeys());
+
+ if ($this->memcached->getResultCode() == Memcached::RES_SUCCESS) {
+ return $this->filterArrayKeysByPrefix($keys, $prefix);
+ } else {
+ $this->logger->debug('Memcached \'getAllKeys\' failed', ['result' => $this->memcached->getResultMessage()]);
+ return [];
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function get($key)
+ {
+ $return = null;
+ $cachekey = $this->getCacheKey($key);
+
+ // We fetch with the hostname as key to avoid problems with other applications
+ $value = $this->memcached->get($cachekey);
+
+ if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
+ $return = $value;
+ } else {
+ $this->logger->debug('Memcached \'get\' failed', ['result' => $this->memcached->getResultMessage()]);
+ }
+
+ return $return;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+
+ // We store with the hostname as key to avoid problems with other applications
+ if ($ttl > 0) {
+ return $this->memcached->set(
+ $cachekey,
+ $value,
+ $ttl
+ );
+ } else {
+ return $this->memcached->set(
+ $cachekey,
+ $value
+ );
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function delete($key)
+ {
+ $cachekey = $this->getCacheKey($key);
+ return $this->memcached->delete($cachekey);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function clear($outdated = true)
+ {
+ if ($outdated) {
+ return true;
+ } else {
+ return $this->memcached->flush();
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+ return $this->memcached->add($cachekey, $value, $ttl);
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-use Exception;
-use Friendica\Core\Cache;
-use Friendica\Core\Config\Configuration;
-use Memcached;
-use Psr\Log\LoggerInterface;
-
-/**
- * Memcached Cache Driver
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- */
-class MemcachedCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
-{
- use TraitCompareSet;
- use TraitCompareDelete;
-
- /**
- * @var \Memcached
- */
- private $memcached;
-
- /**
- * @var LoggerInterface
- */
- private $logger;
-
- /**
- * Due to limitations of the INI format, the expected configuration for Memcached servers is the following:
- * array {
- * 0 => "hostname, port(, weight)",
- * 1 => ...
- * }
- *
- * @param array $memcached_hosts
- * @throws \Exception
- */
- public function __construct(string $hostname, Configuration $config, LoggerInterface $logger)
- {
- if (!class_exists('Memcached', false)) {
- throw new Exception('Memcached class isn\'t available');
- }
-
- parent::__construct($hostname);
-
- $this->logger = $logger;
-
- $this->memcached = new Memcached();
-
- $memcached_hosts = $config->get('system', 'memcached_hosts');
-
- array_walk($memcached_hosts, function (&$value) {
- if (is_string($value)) {
- $value = array_map('trim', explode(',', $value));
- }
- });
-
- $this->memcached->addServers($memcached_hosts);
-
- if (count($this->memcached->getServerList()) == 0) {
- throw new Exception('Expected Memcached servers aren\'t available, config:' . var_export($memcached_hosts, true));
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function getAllKeys($prefix = null)
- {
- $keys = $this->getOriginalKeys($this->memcached->getAllKeys());
-
- if ($this->memcached->getResultCode() == Memcached::RES_SUCCESS) {
- return $this->filterArrayKeysByPrefix($keys, $prefix);
- } else {
- $this->logger->debug('Memcached \'getAllKeys\' failed', ['result' => $this->memcached->getResultMessage()]);
- return [];
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function get($key)
- {
- $return = null;
- $cachekey = $this->getCacheKey($key);
-
- // We fetch with the hostname as key to avoid problems with other applications
- $value = $this->memcached->get($cachekey);
-
- if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
- $return = $value;
- } else {
- $this->logger->debug('Memcached \'get\' failed', ['result' => $this->memcached->getResultMessage()]);
- }
-
- return $return;
- }
-
- /**
- * (@inheritdoc)
- */
- public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
-
- // We store with the hostname as key to avoid problems with other applications
- if ($ttl > 0) {
- return $this->memcached->set(
- $cachekey,
- $value,
- $ttl
- );
- } else {
- return $this->memcached->set(
- $cachekey,
- $value
- );
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function delete($key)
- {
- $cachekey = $this->getCacheKey($key);
- return $this->memcached->delete($cachekey);
- }
-
- /**
- * (@inheritdoc)
- */
- public function clear($outdated = true)
- {
- if ($outdated) {
- return true;
- } else {
- return $this->memcached->flush();
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
- return $this->memcached->add($cachekey, $value, $ttl);
- }
-}
*
* It is using the decorator pattern (@see
*/
-class ProfilerCache implements ICacheDriver, IMemoryCacheDriver
+class ProfilerCache implements ICache, IMemoryCache
{
/**
- * @var ICacheDriver The original cache driver
+ * @var ICache The original cache driver
*/
private $cache;
*/
private $profiler;
- public function __construct(ICacheDriver $cache, Profiler $profiler)
+ public function __construct(ICache $cache, Profiler $profiler)
{
$this->cache = $cache;
$this->profiler = $profiler;
*/
public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
{
- if ($this->cache instanceof IMemoryCacheDriver) {
+ if ($this->cache instanceof IMemoryCache) {
$time = microtime(true);
$return = $this->cache->add($key, $value, $ttl);
*/
public function compareSet($key, $oldValue, $newValue, $ttl = Cache::FIVE_MINUTES)
{
- if ($this->cache instanceof IMemoryCacheDriver) {
+ if ($this->cache instanceof IMemoryCache) {
$time = microtime(true);
$return = $this->cache->compareSet($key, $oldValue, $newValue, $ttl);
*/
public function compareDelete($key, $value)
{
- if ($this->cache instanceof IMemoryCacheDriver) {
+ if ($this->cache instanceof IMemoryCache) {
$time = microtime(true);
$return = $this->cache->compareDelete($key, $value);
--- /dev/null
+<?php
+
+namespace Friendica\Core\Cache;
+
+use Exception;
+use Friendica\Core\Cache;
+use Friendica\Core\Config\Configuration;
+use Redis;
+
+/**
+ * Redis Cache. This driver is based on Memcache driver
+ *
+ * @author Hypolite Petovan <hypolite@mrpetovan.com>
+ * @author Roland Haeder <roland@mxchange.org>
+ */
+class RedisCache extends AbstractCache implements IMemoryCache
+{
+ /**
+ * @var Redis
+ */
+ private $redis;
+
+ /**
+ * @throws Exception
+ */
+ public function __construct(string $hostname, Configuration $config)
+ {
+ if (!class_exists('Redis', false)) {
+ throw new Exception('Redis class isn\'t available');
+ }
+
+ parent::__construct($hostname);
+
+ $this->redis = new Redis();
+
+ $redis_host = $config->get('system', 'redis_host');
+ $redis_port = $config->get('system', 'redis_port');
+ $redis_pw = $config->get('system', 'redis_password');
+ $redis_db = $config->get('system', 'redis_db', 0);
+
+ if (!$this->redis->connect($redis_host, $redis_port)) {
+ throw new Exception('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
+ }
+
+ if (isset($redis_pw) && !$this->redis->auth($redis_pw)) {
+ throw new Exception('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
+ }
+
+ if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
+ throw new Exception('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function getAllKeys($prefix = null)
+ {
+ if (empty($prefix)) {
+ $search = '*';
+ } else {
+ $search = $prefix . '*';
+ }
+
+ $list = $this->redis->keys($this->getCacheKey($search));
+
+ return $this->getOriginalKeys($list);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function get($key)
+ {
+ $return = null;
+ $cachekey = $this->getCacheKey($key);
+
+ $cached = $this->redis->get($cachekey);
+ if ($cached === false && !$this->redis->exists($cachekey)) {
+ return null;
+ }
+
+ $value = unserialize($cached);
+
+ // Only return a value if the serialized value is valid.
+ // We also check if the db entry is a serialized
+ // boolean 'false' value (which we want to return).
+ if ($cached === serialize(false) || $value !== false) {
+ $return = $value;
+ }
+
+ return $return;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+
+ $cached = serialize($value);
+
+ if ($ttl > 0) {
+ return $this->redis->setex(
+ $cachekey,
+ $ttl,
+ $cached
+ );
+ } else {
+ return $this->redis->set(
+ $cachekey,
+ $cached
+ );
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function delete($key)
+ {
+ $cachekey = $this->getCacheKey($key);
+ return ($this->redis->delete($cachekey) > 0);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function clear($outdated = true)
+ {
+ if ($outdated) {
+ return true;
+ } else {
+ return $this->redis->flushAll();
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+ $cached = serialize($value);
+
+ return $this->redis->setnx($cachekey, $cached);
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function compareSet($key, $oldValue, $newValue, $ttl = Cache::FIVE_MINUTES)
+ {
+ $cachekey = $this->getCacheKey($key);
+
+ $newCached = serialize($newValue);
+
+ $this->redis->watch($cachekey);
+ // If the old value isn't what we expected, somebody else changed the key meanwhile
+ if ($this->get($key) === $oldValue) {
+ if ($ttl > 0) {
+ $result = $this->redis->multi()
+ ->setex($cachekey, $ttl, $newCached)
+ ->exec();
+ } else {
+ $result = $this->redis->multi()
+ ->set($cachekey, $newCached)
+ ->exec();
+ }
+ return $result !== false;
+ }
+ $this->redis->unwatch();
+ return false;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function compareDelete($key, $value)
+ {
+ $cachekey = $this->getCacheKey($key);
+
+ $this->redis->watch($cachekey);
+ // If the old value isn't what we expected, somebody else changed the key meanwhile
+ if ($this->get($key) === $value) {
+ $result = $this->redis->multi()
+ ->del($cachekey)
+ ->exec();
+ return $result !== false;
+ }
+ $this->redis->unwatch();
+ return false;
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Cache;
-
-use Exception;
-use Friendica\Core\Cache;
-use Friendica\Core\Config\Configuration;
-use Redis;
-
-/**
- * Redis Cache Driver. This driver is based on Memcache driver
- *
- * @author Hypolite Petovan <hypolite@mrpetovan.com>
- * @author Roland Haeder <roland@mxchange.org>
- */
-class RedisCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
-{
- /**
- * @var Redis
- */
- private $redis;
-
- /**
- * @throws Exception
- */
- public function __construct(string $hostname, Configuration $config)
- {
- if (!class_exists('Redis', false)) {
- throw new Exception('Redis class isn\'t available');
- }
-
- parent::__construct($hostname);
-
- $this->redis = new Redis();
-
- $redis_host = $config->get('system', 'redis_host');
- $redis_port = $config->get('system', 'redis_port');
- $redis_pw = $config->get('system', 'redis_password');
- $redis_db = $config->get('system', 'redis_db', 0);
-
- if (!$this->redis->connect($redis_host, $redis_port)) {
- throw new Exception('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
- }
-
- if (isset($redis_pw) && !$this->redis->auth($redis_pw)) {
- throw new Exception('Cannot authenticate redis server at ' . $redis_host . ':' . $redis_port);
- }
-
- if ($redis_db !== 0 && !$this->redis->select($redis_db)) {
- throw new Exception('Cannot switch to redis db ' . $redis_db . ' at ' . $redis_host . ':' . $redis_port);
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function getAllKeys($prefix = null)
- {
- if (empty($prefix)) {
- $search = '*';
- } else {
- $search = $prefix . '*';
- }
-
- $list = $this->redis->keys($this->getCacheKey($search));
-
- return $this->getOriginalKeys($list);
- }
-
- /**
- * (@inheritdoc)
- */
- public function get($key)
- {
- $return = null;
- $cachekey = $this->getCacheKey($key);
-
- $cached = $this->redis->get($cachekey);
- if ($cached === false && !$this->redis->exists($cachekey)) {
- return null;
- }
-
- $value = unserialize($cached);
-
- // Only return a value if the serialized value is valid.
- // We also check if the db entry is a serialized
- // boolean 'false' value (which we want to return).
- if ($cached === serialize(false) || $value !== false) {
- $return = $value;
- }
-
- return $return;
- }
-
- /**
- * (@inheritdoc)
- */
- public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
-
- $cached = serialize($value);
-
- if ($ttl > 0) {
- return $this->redis->setex(
- $cachekey,
- $ttl,
- $cached
- );
- } else {
- return $this->redis->set(
- $cachekey,
- $cached
- );
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function delete($key)
- {
- $cachekey = $this->getCacheKey($key);
- return ($this->redis->delete($cachekey) > 0);
- }
-
- /**
- * (@inheritdoc)
- */
- public function clear($outdated = true)
- {
- if ($outdated) {
- return true;
- } else {
- return $this->redis->flushAll();
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
- $cached = serialize($value);
-
- return $this->redis->setnx($cachekey, $cached);
- }
-
- /**
- * (@inheritdoc)
- */
- public function compareSet($key, $oldValue, $newValue, $ttl = Cache::FIVE_MINUTES)
- {
- $cachekey = $this->getCacheKey($key);
-
- $newCached = serialize($newValue);
-
- $this->redis->watch($cachekey);
- // If the old value isn't what we expected, somebody else changed the key meanwhile
- if ($this->get($key) === $oldValue) {
- if ($ttl > 0) {
- $result = $this->redis->multi()
- ->setex($cachekey, $ttl, $newCached)
- ->exec();
- } else {
- $result = $this->redis->multi()
- ->set($cachekey, $newCached)
- ->exec();
- }
- return $result !== false;
- }
- $this->redis->unwatch();
- return false;
- }
-
- /**
- * (@inheritdoc)
- */
- public function compareDelete($key, $value)
- {
- $cachekey = $this->getCacheKey($key);
-
- $this->redis->watch($cachekey);
- // If the old value isn't what we expected, somebody else changed the key meanwhile
- if ($this->get($key) === $value) {
- $result = $this->redis->multi()
- ->del($cachekey)
- ->exec();
- return $result !== false;
- }
- $this->redis->unwatch();
- return false;
- }
-}
namespace Friendica\Core;
use Friendica\BaseObject;
-use Friendica\Core\Cache\ICacheDriver;
-use Friendica\Core\Lock\ILockDriver;
+use Friendica\Core\Cache\ICache;
+use Friendica\Core\Lock\ILock;
/**
* This class contain Functions for preventing parallel execution of functions
* @return boolean Was the lock successful?
* @throws \Exception
*/
- public static function acquire($key, $timeout = 120, $ttl = ICacheDriver::FIVE_MINUTES)
+ public static function acquire($key, $timeout = 120, $ttl = ICache::FIVE_MINUTES)
{
- return self::getClass(ILockDriver::class)->acquireLock($key, $timeout, $ttl);
+ return self::getClass(ILock::class)->acquireLock($key, $timeout, $ttl);
}
/**
*/
public static function release($key, $override = false)
{
- return self::getClass(ILockDriver::class)->releaseLock($key, $override);
+ return self::getClass(ILock::class)->releaseLock($key, $override);
}
/**
*/
public static function releaseAll()
{
- self::getClass(ILockDriver::class)->releaseAll();
+ self::getClass(ILock::class)->releaseAll();
}
}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Lock;
+
+/**
+ * Class AbstractLock
+ *
+ * @package Friendica\Core\Lock
+ *
+ * Basic class for Locking with common functions (local acquired locks, releaseAll, ..)
+ */
+abstract class AbstractLock implements ILock
+{
+ /**
+ * @var array The local acquired locks
+ */
+ protected $acquiredLocks = [];
+
+ /**
+ * Check if we've locally acquired a lock
+ *
+ * @param string key The Name of the lock
+ *
+ * @return bool Returns true if the lock is set
+ */
+ protected function hasAcquiredLock($key)
+ {
+ return isset($this->acquireLock[$key]) && $this->acquiredLocks[$key] === true;
+ }
+
+ /**
+ * Mark a locally acquired lock
+ *
+ * @param string $key The Name of the lock
+ */
+ protected function markAcquire($key)
+ {
+ $this->acquiredLocks[$key] = true;
+ }
+
+ /**
+ * Mark a release of a locally acquired lock
+ *
+ * @param string $key The Name of the lock
+ */
+ protected function markRelease($key)
+ {
+ unset($this->acquiredLocks[$key]);
+ }
+
+ /**
+ * Releases all lock that were set by us
+ *
+ * @return boolean Was the unlock of all locks successful?
+ */
+ public function releaseAll()
+ {
+ $return = true;
+
+ foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
+ if (!$this->releaseLock($acquiredLock)) {
+ $return = false;
+ }
+ }
+
+ return $return;
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Lock;
-
-/**
- * Class AbstractLockDriver
- *
- * @package Friendica\Core\Lock
- *
- * Basic class for Locking with common functions (local acquired locks, releaseAll, ..)
- */
-abstract class AbstractLockDriver implements ILockDriver
-{
- /**
- * @var array The local acquired locks
- */
- protected $acquiredLocks = [];
-
- /**
- * Check if we've locally acquired a lock
- *
- * @param string key The Name of the lock
- *
- * @return bool Returns true if the lock is set
- */
- protected function hasAcquiredLock($key)
- {
- return isset($this->acquireLock[$key]) && $this->acquiredLocks[$key] === true;
- }
-
- /**
- * Mark a locally acquired lock
- *
- * @param string $key The Name of the lock
- */
- protected function markAcquire($key)
- {
- $this->acquiredLocks[$key] = true;
- }
-
- /**
- * Mark a release of a locally acquired lock
- *
- * @param string $key The Name of the lock
- */
- protected function markRelease($key)
- {
- unset($this->acquiredLocks[$key]);
- }
-
- /**
- * Releases all lock that were set by us
- *
- * @return boolean Was the unlock of all locks successful?
- */
- public function releaseAll()
- {
- $return = true;
-
- foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
- if (!$this->releaseLock($acquiredLock)) {
- $return = false;
- }
- }
-
- return $return;
- }
-}
namespace Friendica\Core\Lock;
use Friendica\Core\Cache;
-use Friendica\Core\Cache\IMemoryCacheDriver;
+use Friendica\Core\Cache\IMemoryCache;
-class CacheLockDriver extends AbstractLockDriver
+class CacheLockDriver extends AbstractLock
{
/**
- * @var \Friendica\Core\Cache\ICacheDriver;
+ * @var \Friendica\Core\Cache\ICache;
*/
private $cache;
/**
* CacheLockDriver constructor.
*
- * @param IMemoryCacheDriver $cache The CacheDriver for this type of lock
+ * @param IMemoryCache $cache The CacheDriver for this type of lock
*/
- public function __construct(IMemoryCacheDriver $cache)
+ public function __construct(IMemoryCache $cache)
{
$this->cache = $cache;
}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Lock;
+
+use Friendica\Core\Cache;
+use Friendica\Database\Database;
+use Friendica\Util\DateTimeFormat;
+
+/**
+ * Locking driver that stores the locks in the database
+ */
+class DatabaseLock extends AbstractLock
+{
+ /**
+ * The current ID of the process
+ *
+ * @var int
+ */
+ private $pid;
+
+ /**
+ * @var Database The database connection of Friendica
+ */
+ private $dba;
+
+ /**
+ * @param null|int $pid The Id of the current process (null means determine automatically)
+ */
+ public function __construct(Database $dba, $pid = null)
+ {
+ $this->dba = $dba;
+ $this->pid = isset($pid) ? $pid : getmypid();
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
+ {
+ $got_lock = false;
+ $start = time();
+
+ do {
+ $this->dba->lock('locks');
+ $lock = $this->dba->selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+
+ if ($this->dba->isResult($lock)) {
+ if ($lock['locked']) {
+ // We want to lock something that was already locked by us? So we got the lock.
+ if ($lock['pid'] == $this->pid) {
+ $got_lock = true;
+ }
+ }
+ if (!$lock['locked']) {
+ $this->dba->update('locks', ['locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
+ $got_lock = true;
+ }
+ } else {
+ $this->dba->insert('locks', ['name' => $key, 'locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
+ $got_lock = true;
+ $this->markAcquire($key);
+ }
+
+ $this->dba->unlock();
+
+ if (!$got_lock && ($timeout > 0)) {
+ usleep(rand(100000, 2000000));
+ }
+ } while (!$got_lock && ((time() - $start) < $timeout));
+
+ return $got_lock;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function releaseLock($key, $override = false)
+ {
+ if ($override) {
+ $where = ['name' => $key];
+ } else {
+ $where = ['name' => $key, 'pid' => $this->pid];
+ }
+
+ $return = $this->dba->delete('locks', $where);
+
+ $this->markRelease($key);
+
+ return $return;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function releaseAll()
+ {
+ $return = $this->dba->delete('locks', ['pid' => $this->pid]);
+
+ $this->acquiredLocks = [];
+
+ return $return;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function isLocked($key)
+ {
+ $lock = $this->dba->selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+
+ if ($this->dba->isResult($lock)) {
+ return $lock['locked'] !== false;
+ } else {
+ return false;
+ }
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\Cache;
-use Friendica\Database\Database;
-use Friendica\Util\DateTimeFormat;
-
-/**
- * Locking driver that stores the locks in the database
- */
-class DatabaseLockDriver extends AbstractLockDriver
-{
- /**
- * The current ID of the process
- *
- * @var int
- */
- private $pid;
-
- /**
- * @var Database The database connection of Friendica
- */
- private $dba;
-
- /**
- * @param null|int $pid The Id of the current process (null means determine automatically)
- */
- public function __construct(Database $dba, $pid = null)
- {
- $this->dba = $dba;
- $this->pid = isset($pid) ? $pid : getmypid();
- }
-
- /**
- * (@inheritdoc)
- */
- public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
- {
- $got_lock = false;
- $start = time();
-
- do {
- $this->dba->lock('locks');
- $lock = $this->dba->selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
-
- if ($this->dba->isResult($lock)) {
- if ($lock['locked']) {
- // We want to lock something that was already locked by us? So we got the lock.
- if ($lock['pid'] == $this->pid) {
- $got_lock = true;
- }
- }
- if (!$lock['locked']) {
- $this->dba->update('locks', ['locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
- $got_lock = true;
- }
- } else {
- $this->dba->insert('locks', ['name' => $key, 'locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
- $got_lock = true;
- $this->markAcquire($key);
- }
-
- $this->dba->unlock();
-
- if (!$got_lock && ($timeout > 0)) {
- usleep(rand(100000, 2000000));
- }
- } while (!$got_lock && ((time() - $start) < $timeout));
-
- return $got_lock;
- }
-
- /**
- * (@inheritdoc)
- */
- public function releaseLock($key, $override = false)
- {
- if ($override) {
- $where = ['name' => $key];
- } else {
- $where = ['name' => $key, 'pid' => $this->pid];
- }
-
- $return = $this->dba->delete('locks', $where);
-
- $this->markRelease($key);
-
- return $return;
- }
-
- /**
- * (@inheritdoc)
- */
- public function releaseAll()
- {
- $return = $this->dba->delete('locks', ['pid' => $this->pid]);
-
- $this->acquiredLocks = [];
-
- return $return;
- }
-
- /**
- * (@inheritdoc)
- */
- public function isLocked($key)
- {
- $lock = $this->dba->selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
-
- if ($this->dba->isResult($lock)) {
- return $lock['locked'] !== false;
- } else {
- return false;
- }
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Lock;
+
+use Friendica\Core\Cache;
+
+/**
+ * Lock Interface
+ *
+ * @author Philipp Holzer <admin@philipp.info>
+ */
+interface ILock
+{
+ /**
+ * Checks, if a key is currently locked to a or my process
+ *
+ * @param string $key The name of the lock
+ *
+ * @return bool
+ */
+ public function isLocked($key);
+
+ /**
+ *
+ * Acquires a lock for a given name
+ *
+ * @param string $key The Name of the lock
+ * @param integer $timeout Seconds until we give up
+ * @param integer $ttl Seconds The lock lifespan, must be one of the Cache constants
+ *
+ * @return boolean Was the lock successful?
+ */
+ public function acquireLock($key, $timeout = 120, $ttl = Cache\ICache::FIVE_MINUTES);
+
+ /**
+ * Releases a lock if it was set by us
+ *
+ * @param string $key The Name of the lock
+ * @param bool $override Overrides the lock to get released
+ *
+ * @return boolean Was the unlock successful?
+ */
+ public function releaseLock($key, $override = false);
+
+ /**
+ * Releases all lock that were set by us
+ *
+ * @return boolean Was the unlock of all locks successful?
+ */
+ public function releaseAll();
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\Cache;
-
-/**
- * Lock Driver Interface
- *
- * @author Philipp Holzer <admin@philipp.info>
- */
-interface ILockDriver
-{
- /**
- * Checks, if a key is currently locked to a or my process
- *
- * @param string $key The name of the lock
- *
- * @return bool
- */
- public function isLocked($key);
-
- /**
- *
- * Acquires a lock for a given name
- *
- * @param string $key The Name of the lock
- * @param integer $timeout Seconds until we give up
- * @param integer $ttl Seconds The lock lifespan, must be one of the Cache constants
- *
- * @return boolean Was the lock successful?
- */
- public function acquireLock($key, $timeout = 120, $ttl = Cache\ICacheDriver::FIVE_MINUTES);
-
- /**
- * Releases a lock if it was set by us
- *
- * @param string $key The Name of the lock
- * @param bool $override Overrides the lock to get released
- *
- * @return boolean Was the unlock successful?
- */
- public function releaseLock($key, $override = false);
-
- /**
- * Releases all lock that were set by us
- *
- * @return boolean Was the unlock of all locks successful?
- */
- public function releaseAll();
-}
--- /dev/null
+<?php
+
+namespace Friendica\Core\Lock;
+
+use Friendica\Core\Cache;
+
+class SemaphoreLock extends AbstractLock
+{
+ private static $semaphore = [];
+
+ public function __construct()
+ {
+ if (!function_exists('sem_get')) {
+ throw new \Exception('Semaphore lock not supported');
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ private static function semaphoreKey($key)
+ {
+ $temp = get_temppath();
+
+ $file = $temp . '/' . $key . '.sem';
+
+ if (!file_exists($file)) {
+ file_put_contents($file, $key);
+ }
+
+ return ftok($file, 'f');
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
+ {
+ self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
+ if (self::$semaphore[$key]) {
+ if (sem_acquire(self::$semaphore[$key], ($timeout == 0))) {
+ $this->markAcquire($key);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function releaseLock($key, $override = false)
+ {
+ if (empty(self::$semaphore[$key])) {
+ return false;
+ } else {
+ $success = @sem_release(self::$semaphore[$key]);
+ unset(self::$semaphore[$key]);
+ $this->markRelease($key);
+ return $success;
+ }
+ }
+
+ /**
+ * (@inheritdoc)
+ */
+ public function isLocked($key)
+ {
+ return isset(self::$semaphore[$key]);
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\Cache;
-
-class SemaphoreLockDriver extends AbstractLockDriver
-{
- private static $semaphore = [];
-
- public function __construct()
- {
- if (!function_exists('sem_get')) {
- throw new \Exception('Semaphore lock not supported');
- }
- }
-
- /**
- * (@inheritdoc)
- */
- private static function semaphoreKey($key)
- {
- $temp = get_temppath();
-
- $file = $temp . '/' . $key . '.sem';
-
- if (!file_exists($file)) {
- file_put_contents($file, $key);
- }
-
- return ftok($file, 'f');
- }
-
- /**
- * (@inheritdoc)
- */
- public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
- {
- self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
- if (self::$semaphore[$key]) {
- if (sem_acquire(self::$semaphore[$key], ($timeout == 0))) {
- $this->markAcquire($key);
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * (@inheritdoc)
- */
- public function releaseLock($key, $override = false)
- {
- if (empty(self::$semaphore[$key])) {
- return false;
- } else {
- $success = @sem_release(self::$semaphore[$key]);
- unset(self::$semaphore[$key]);
- $this->markRelease($key);
- return $success;
- }
- }
-
- /**
- * (@inheritdoc)
- */
- public function isLocked($key)
- {
- return isset(self::$semaphore[$key]);
- }
-}
namespace Friendica\Factory;
use Friendica\Core\Cache;
-use Friendica\Core\Cache\ICacheDriver;
+use Friendica\Core\Cache\ICache;
use Friendica\Core\Config\Configuration;
use Friendica\Database\Database;
use Friendica\Util\BaseURL;
/**
* This method creates a CacheDriver for the given cache driver name
*
- * @return ICacheDriver The instance of the CacheDriver
+ * @return ICache The instance of the CacheDriver
* @throws \Exception The exception if something went wrong during the CacheDriver creation
*/
public function create()
switch ($driver) {
case 'memcache':
- $cache = new Cache\MemcacheCacheDriver($this->hostname, $this->config);
+ $cache = new Cache\MemcacheCache($this->hostname, $this->config);
break;
case 'memcached':
- $cache = new Cache\MemcachedCacheDriver($this->hostname, $this->config, $this->logger);
+ $cache = new Cache\MemcachedCache($this->hostname, $this->config, $this->logger);
break;
case 'redis':
- $cache = new Cache\RedisCacheDriver($this->hostname, $this->config);
+ $cache = new Cache\RedisCache($this->hostname, $this->config);
break;
case 'apcu':
$cache = new Cache\APCuCache($this->hostname);
break;
default:
- $cache = new Cache\DatabaseCacheDriver($this->hostname, $this->dba);
+ $cache = new Cache\DatabaseCache($this->hostname, $this->dba);
}
$profiling = $this->config->get('system', 'profiling', false);
namespace Friendica\Factory;
-use Friendica\Core\Cache\ICacheDriver;
-use Friendica\Core\Cache\IMemoryCacheDriver;
+use Friendica\Core\Cache\ICache;
+use Friendica\Core\Cache\IMemoryCache;
use Friendica\Core\Config\Configuration;
use Friendica\Core\Lock;
use Friendica\Database\Database;
private $dba;
/**
- * @var ICacheDriver The memory cache driver in case we use it
+ * @var ICache The memory cache driver in case we use it
*/
private $cacheDriver;
*/
private $logger;
- public function __construct(ICacheDriver $cacheDriver, Configuration $config, Database $dba, Profiler $profiler, LoggerInterface $logger)
+ public function __construct(ICache $cacheDriver, Configuration $config, Database $dba, Profiler $profiler, LoggerInterface $logger)
{
$this->cacheDriver = $cacheDriver;
$this->config = $config;
case 'memcache':
case 'memcached':
case 'redis':
- if ($this->cacheDriver instanceof IMemoryCacheDriver) {
+ if ($this->cacheDriver instanceof IMemoryCache) {
return new Lock\CacheLockDriver($this->cacheDriver);
}
break;
case 'database':
- return new Lock\DatabaseLockDriver($this->dba);
+ return new Lock\DatabaseLock($this->dba);
break;
case 'semaphore':
- return new Lock\SemaphoreLockDriver();
+ return new Lock\SemaphoreLock();
break;
default:
* 2. Cache Locking
* 3. Database Locking
*
- * @return Lock\ILockDriver
+ * @return Lock\ILock
*/
private function useAutoDriver()
{
// 1. Try to use Semaphores for - local - locking
if (function_exists('sem_get')) {
try {
- return new Lock\SemaphoreLockDriver();
+ return new Lock\SemaphoreLock();
} catch (\Exception $exception) {
$this->logger->debug('Using Semaphore driver for locking failed.', ['exception' => $exception]);
}
$cache_driver = $this->config->get('system', 'cache_driver', 'database');
if ($cache_driver != 'database') {
try {
- if ($this->cacheDriver instanceof IMemoryCacheDriver) {
+ if ($this->cacheDriver instanceof IMemoryCache) {
return new Lock\CacheLockDriver($this->cacheDriver);
}
} catch (\Exception $exception) {
}
// 3. Use Database Locking as a Fallback
- return new Lock\DatabaseLockDriver($this->dba);
+ return new Lock\DatabaseLock($this->dba);
}
}
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\Config;
-use Friendica\Core\Lock\ILockDriver;
+use Friendica\Core\Lock\ILock;
use Friendica\Database\Database;
use Friendica\Factory;
use Friendica\Util;
* $app = $dice->create(App::class, [], ['$channel' => 'index']);
* and is automatically passed as an argument with the same name
*/
- LoggerInterface::class => [
+ LoggerInterface::class => [
'instanceOf' => Factory\LoggerFactory::class,
'call' => [
['create', [], Dice::CHAIN_CALL],
],
],
- '$devLogger' => [
+ '$devLogger' => [
'instanceOf' => Factory\LoggerFactory::class,
'call' => [
['createDev', [], Dice::CHAIN_CALL],
]
],
- Cache\ICacheDriver::class => [
+ Cache\ICache::class => [
'instanceOf' => Factory\CacheDriverFactory::class,
- 'call' => [
+ 'call' => [
['create', [], Dice::CHAIN_CALL],
],
],
- Cache\IMemoryCacheDriver::class => [
- 'instanceOf' => Cache\ICacheDriver::class,
+ Cache\IMemoryCache::class => [
+ 'instanceOf' => Cache\ICache::class,
],
- ILockDriver::class => [
+ ILock::class => [
'instanceOf' => Factory\LockDriverFactory::class,
- 'call' => [
+ 'call' => [
['create', [], Dice::CHAIN_CALL],
],
],
namespace Friendica\Test\Util;
use Friendica\Core\Cache;
-use Friendica\Core\Lock\DatabaseLockDriver;
+use Friendica\Core\Lock\DatabaseLock;
trait DbaLockMockTrait
{
/**
* Mocking acquireLock with DBA-backend
- * @see DatabaseLockDriver::acquireLock()
*
* @param mixed $key The key to lock
* @param int $ttl The TimeToLive
* @param bool $rowExists True, if a row already exists in the lock table
* @param null $time The current timestamp
* @param null|int $times How often the method will get used
+ *
+ *@see DatabaseLock::acquireLock()
+ *
*/
public function mockAcquireLock($key, $ttl = Cache::FIVE_MINUTES, $locked = false, $pid = null, $rowExists = true, $time = null, $times = null)
{
/**
* Mocking isLocked with DBA-backend
- * @see DatabaseLockDriver::isLocked()
*
* @param mixed $key The key of the lock
* @param null|bool $return True, if the key is already locked
- * @param null $time The current timestamp
+ * @param null $time The current timestamp
* @param null|int $times How often the method will get used
+ *
+ *@see DatabaseLock::isLocked()
+ *
*/
public function mockIsLocked($key, $return = true, $time = null, $times = null)
{
/**
* Mocking releaseAll with DBA-backend
- * @see DatabaseLockDriver::releaseAll()
*
- * @param null $pid The PID which was set
- * @param null|int $times How often the method will get used
+ * @param null $pid The PID which was set
+ * @param null|int $times How often the method will get used
+ *
+ *@see DatabaseLock::releaseAll()
+ *
*/
public function mockReleaseAll($pid = null, $times = null)
{
/**
* Mocking ReleaseLock with DBA-backend
- * @see DatabaseLockDriver::releaseLock()
*
* @param mixed $key The key to release
* @param null|int $pid The PID which was set
* @param null|int $times How often the method will get used
+ *
+ *@see DatabaseLock::releaseLock()
+ *
*/
public function mockReleaseLock($key, $pid = null, $times = null)
{
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Cache;
-
-use Friendica\Core\Cache\APCuCache;
-
-class APCuCacheDriverTest extends MemoryCacheTest
-{
- protected function setUp()
- {
- if (!APCuCache::isAvailable()) {
- $this->markTestSkipped('APCu is not available');
- }
-
- parent::setUp();
- }
-
- protected function getInstance()
- {
- $this->cache = new APCuCache('localhost');
- return $this->cache;
- }
-
- public function tearDown()
- {
- $this->cache->clear(false);
- parent::tearDown();
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Cache;
+
+use Friendica\Core\Cache\APCuCache;
+
+class APCuCacheTest extends MemoryCacheTest
+{
+ protected function setUp()
+ {
+ if (!APCuCache::isAvailable()) {
+ $this->markTestSkipped('APCu is not available');
+ }
+
+ parent::setUp();
+ }
+
+ protected function getInstance()
+ {
+ $this->cache = new APCuCache('localhost');
+ return $this->cache;
+ }
+
+ public function tearDown()
+ {
+ $this->cache->clear(false);
+ parent::tearDown();
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Cache;
-
-use Friendica\Core\Cache\ArrayCache;
-
-class ArrayCacheDriverTest extends MemoryCacheTest
-{
- protected function getInstance()
- {
- $this->cache = new ArrayCache('localhost');
- return $this->cache;
- }
-
- public function tearDown()
- {
- $this->cache->clear(false);
- parent::tearDown();
- }
-
- public function testTTL()
- {
- // Array Cache doesn't support TTL
- return true;
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Cache;
+
+use Friendica\Core\Cache\ArrayCache;
+
+class ArrayCacheTest extends MemoryCacheTest
+{
+ protected function getInstance()
+ {
+ $this->cache = new ArrayCache('localhost');
+ return $this->cache;
+ }
+
+ public function tearDown()
+ {
+ $this->cache->clear(false);
+ parent::tearDown();
+ }
+
+ public function testTTL()
+ {
+ // Array Cache doesn't support TTL
+ return true;
+ }
+}
namespace Friendica\Test\src\Core\Cache;
-use Friendica\Core\Cache\MemcachedCacheDriver;
+use Friendica\Core\Cache\MemcachedCache;
use Friendica\Test\MockedTest;
use Friendica\Util\PidFile;
protected $startTime = 1417011228;
/**
- * @var \Friendica\Core\Cache\ICacheDriver
+ * @var \Friendica\Core\Cache\ICache
*/
protected $instance;
/**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
+ * @var \Friendica\Core\Cache\IMemoryCache
*/
protected $cache;
*/
public function testGetAllKeys($value1, $value2, $value3)
{
- if ($this->cache instanceof MemcachedCacheDriver) {
+ if ($this->cache instanceof MemcachedCache) {
$this->markTestSkipped('Memcached doesn\'t support getAllKeys anymore');
}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Cache;
-
-use Friendica\Core\Cache;
-use Friendica\Factory\ConfigFactory;
-use Friendica\Test\DatabaseTestTrait;
-use Friendica\Test\Util\Database\StaticDatabase;
-use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
-use Friendica\Util\Profiler;
-use Psr\Log\NullLogger;
-
-class DatabaseCacheDriverTest extends CacheTest
-{
- use DatabaseTestTrait;
- use VFSTrait;
-
- protected function setUp()
- {
- $this->setUpVfsDir();
-
- parent::setUp();
- }
-
- protected function getInstance()
- {
- $logger = new NullLogger();
- $profiler = \Mockery::mock(Profiler::class);
- $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
-
- // load real config to avoid mocking every config-entry which is related to the Database class
- $configFactory = new ConfigFactory();
- $loader = new ConfigFileLoader($this->root->url());
- $configCache = $configFactory->createCache($loader);
-
- $dba = new StaticDatabase($configCache, $profiler, $logger);
-
- $this->cache = new Cache\DatabaseCacheDriver('database', $dba);
- return $this->cache;
- }
-
- public function tearDown()
- {
- $this->cache->clear(false);
- parent::tearDown();
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Cache;
+
+use Friendica\Core\Cache;
+use Friendica\Factory\ConfigFactory;
+use Friendica\Test\DatabaseTestTrait;
+use Friendica\Test\Util\Database\StaticDatabase;
+use Friendica\Test\Util\VFSTrait;
+use Friendica\Util\ConfigFileLoader;
+use Friendica\Util\Profiler;
+use Psr\Log\NullLogger;
+
+class DatabaseCacheTest extends CacheTest
+{
+ use DatabaseTestTrait;
+ use VFSTrait;
+
+ protected function setUp()
+ {
+ $this->setUpVfsDir();
+
+ parent::setUp();
+ }
+
+ protected function getInstance()
+ {
+ $logger = new NullLogger();
+ $profiler = \Mockery::mock(Profiler::class);
+ $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
+
+ // load real config to avoid mocking every config-entry which is related to the Database class
+ $configFactory = new ConfigFactory();
+ $loader = new ConfigFileLoader($this->root->url());
+ $configCache = $configFactory->createCache($loader);
+
+ $dba = new StaticDatabase($configCache, $profiler, $logger);
+
+ $this->cache = new Cache\DatabaseCache('database', $dba);
+ return $this->cache;
+ }
+
+ public function tearDown()
+ {
+ $this->cache->clear(false);
+ parent::tearDown();
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Cache;
-
-use Friendica\Core\Cache\MemcacheCacheDriver;
-use Friendica\Core\Config\Configuration;
-
-/**
- * @requires extension memcache
- */
-class MemcacheCacheDriverTest extends MemoryCacheTest
-{
- protected function getInstance()
- {
- $configMock = \Mockery::mock(Configuration::class);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'memcache_host')
- ->andReturn('localhost');
- $configMock
- ->shouldReceive('get')
- ->with('system', 'memcache_port')
- ->andReturn(11211);
-
- $this->cache = new MemcacheCacheDriver('localhost', $configMock);
- return $this->cache;
- }
-
- public function tearDown()
- {
- $this->cache->clear(false);
- parent::tearDown();
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Cache;
+
+use Friendica\Core\Cache\MemcacheCache;
+use Friendica\Core\Config\Configuration;
+
+/**
+ * @requires extension memcache
+ */
+class MemcacheCacheTest extends MemoryCacheTest
+{
+ protected function getInstance()
+ {
+ $configMock = \Mockery::mock(Configuration::class);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'memcache_host')
+ ->andReturn('localhost');
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'memcache_port')
+ ->andReturn(11211);
+
+ $this->cache = new MemcacheCache('localhost', $configMock);
+ return $this->cache;
+ }
+
+ public function tearDown()
+ {
+ $this->cache->clear(false);
+ parent::tearDown();
+ }
+}
+++ /dev/null
-<?php
-
-
-namespace Friendica\Test\src\Core\Cache;
-
-use Friendica\Core\Cache\MemcachedCacheDriver;
-use Friendica\Core\Config\Configuration;
-use Psr\Log\NullLogger;
-
-/**
- * @requires extension memcached
- */
-class MemcachedCacheDriverTest extends MemoryCacheTest
-{
- protected function getInstance()
- {
- $configMock = \Mockery::mock(Configuration::class);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'memcached_hosts')
- ->andReturn([0 => 'localhost, 11211']);
-
- $logger = new NullLogger();
-
- $this->cache = new MemcachedCacheDriver('localhost', $configMock, $logger);
- return $this->cache;
- }
-
- public function tearDown()
- {
- $this->cache->clear(false);
- parent::tearDown();
- }
-}
--- /dev/null
+<?php
+
+
+namespace Friendica\Test\src\Core\Cache;
+
+use Friendica\Core\Cache\MemcachedCache;
+use Friendica\Core\Config\Configuration;
+use Psr\Log\NullLogger;
+
+/**
+ * @requires extension memcached
+ */
+class MemcachedCacheTest extends MemoryCacheTest
+{
+ protected function getInstance()
+ {
+ $configMock = \Mockery::mock(Configuration::class);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'memcached_hosts')
+ ->andReturn([0 => 'localhost, 11211']);
+
+ $logger = new NullLogger();
+
+ $this->cache = new MemcachedCache('localhost', $configMock, $logger);
+ return $this->cache;
+ }
+
+ public function tearDown()
+ {
+ $this->cache->clear(false);
+ parent::tearDown();
+ }
+}
namespace Friendica\Test\src\Core\Cache;
-use Friendica\Core\Cache\IMemoryCacheDriver;
+use Friendica\Core\Cache\IMemoryCache;
abstract class MemoryCacheTest extends CacheTest
{
/**
- * @var \Friendica\Core\Cache\IMemoryCacheDriver
+ * @var \Friendica\Core\Cache\IMemoryCache
*/
protected $instance;
{
parent::setUp();
- if (!($this->instance instanceof IMemoryCacheDriver)) {
+ if (!($this->instance instanceof IMemoryCache)) {
throw new \Exception('MemoryCacheTest unsupported');
}
}
+++ /dev/null
-<?php
-
-
-namespace Friendica\Test\src\Core\Cache;
-
-use Friendica\Core\Cache\RedisCacheDriver;
-use Friendica\Core\Config\Configuration;
-
-/**
- * @requires extension redis
- */
-class RedisCacheDriverTest extends MemoryCacheTest
-{
- protected function getInstance()
- {
- $configMock = \Mockery::mock(Configuration::class);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_host')
- ->andReturn('localhost');
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_port')
- ->andReturn(null);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_db', 0)
- ->andReturn(3);
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_password')
- ->andReturn(null);
-
- $this->cache = new RedisCacheDriver('localhost', $configMock);
- return $this->cache;
- }
-
- public function tearDown()
- {
- $this->cache->clear(false);
- parent::tearDown();
- }
-}
--- /dev/null
+<?php
+
+
+namespace Friendica\Test\src\Core\Cache;
+
+use Friendica\Core\Cache\RedisCache;
+use Friendica\Core\Config\Configuration;
+
+/**
+ * @requires extension redis
+ */
+class RedisCacheTest extends MemoryCacheTest
+{
+ protected function getInstance()
+ {
+ $configMock = \Mockery::mock(Configuration::class);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_host')
+ ->andReturn('localhost');
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_port')
+ ->andReturn(null);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_db', 0)
+ ->andReturn(3);
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_password')
+ ->andReturn(null);
+
+ $this->cache = new RedisCache('localhost', $configMock);
+ return $this->cache;
+ }
+
+ public function tearDown()
+ {
+ $this->cache->clear(false);
+ parent::tearDown();
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Friendica\Core\Cache\APCuCache;
-use Friendica\Core\Lock\CacheLockDriver;
-
-class APCuCacheLockDriverTest extends LockTest
-{
- protected function setUp()
- {
- if (!APCuCache::isAvailable()) {
- $this->markTestSkipped('APCu is not available');
- }
-
- parent::setUp();
- }
-
- protected function getInstance()
- {
- return new CacheLockDriver(new APCuCache('localhost'));
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Friendica\Core\Cache\APCuCache;
+use Friendica\Core\Lock\CacheLockDriver;
+
+class APCuCacheLockTest extends LockTest
+{
+ protected function setUp()
+ {
+ if (!APCuCache::isAvailable()) {
+ $this->markTestSkipped('APCu is not available');
+ }
+
+ parent::setUp();
+ }
+
+ protected function getInstance()
+ {
+ return new CacheLockDriver(new APCuCache('localhost'));
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Friendica\Core\Cache\ArrayCache;
-use Friendica\Core\Lock\CacheLockDriver;
-
-class ArrayCacheLockDriverTest extends LockTest
-{
- protected function getInstance()
- {
- return new CacheLockDriver(new ArrayCache('localhost'));
- }
-
- public function testLockTTL()
- {
- // ArrayCache doesn't support TTL
- return true;
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Friendica\Core\Cache\ArrayCache;
+use Friendica\Core\Lock\CacheLockDriver;
+
+class ArrayCacheLockTest extends LockTest
+{
+ protected function getInstance()
+ {
+ return new CacheLockDriver(new ArrayCache('localhost'));
+ }
+
+ public function testLockTTL()
+ {
+ // ArrayCache doesn't support TTL
+ return true;
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Friendica\Core\Lock\DatabaseLockDriver;
-use Friendica\Factory\ConfigFactory;
-use Friendica\Test\DatabaseTestTrait;
-use Friendica\Test\Util\Database\StaticDatabase;
-use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
-use Friendica\Util\Profiler;
-use Psr\Log\NullLogger;
-
-class DatabaseLockDriverTest extends LockTest
-{
- use VFSTrait;
- use DatabaseTestTrait;
-
- protected $pid = 123;
-
- protected function setUp()
- {
- $this->setUpVfsDir();
-
- parent::setUp();
- }
-
- protected function getInstance()
- {
- $logger = new NullLogger();
- $profiler = \Mockery::mock(Profiler::class);
- $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
-
- // load real config to avoid mocking every config-entry which is related to the Database class
- $configFactory = new ConfigFactory();
- $loader = new ConfigFileLoader($this->root->url());
- $configCache = $configFactory->createCache($loader);
-
- $dba = new StaticDatabase($configCache, $profiler, $logger);
-
- return new DatabaseLockDriver($dba, $this->pid);
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Friendica\Core\Lock\DatabaseLock;
+use Friendica\Factory\ConfigFactory;
+use Friendica\Test\DatabaseTestTrait;
+use Friendica\Test\Util\Database\StaticDatabase;
+use Friendica\Test\Util\VFSTrait;
+use Friendica\Util\ConfigFileLoader;
+use Friendica\Util\Profiler;
+use Psr\Log\NullLogger;
+
+class DatabaseLockDriverTest extends LockTest
+{
+ use VFSTrait;
+ use DatabaseTestTrait;
+
+ protected $pid = 123;
+
+ protected function setUp()
+ {
+ $this->setUpVfsDir();
+
+ parent::setUp();
+ }
+
+ protected function getInstance()
+ {
+ $logger = new NullLogger();
+ $profiler = \Mockery::mock(Profiler::class);
+ $profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
+
+ // load real config to avoid mocking every config-entry which is related to the Database class
+ $configFactory = new ConfigFactory();
+ $loader = new ConfigFileLoader($this->root->url());
+ $configCache = $configFactory->createCache($loader);
+
+ $dba = new StaticDatabase($configCache, $profiler, $logger);
+
+ return new DatabaseLock($dba, $this->pid);
+ }
+}
protected $startTime = 1417011228;
/**
- * @var \Friendica\Core\Lock\ILockDriver
+ * @var \Friendica\Core\Lock\ILock
*/
protected $instance;
+++ /dev/null
-<?php
-
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Friendica\Core\Cache\MemcacheCacheDriver;
-use Friendica\Core\Config\Configuration;
-use Friendica\Core\Lock\CacheLockDriver;
-
-/**
- * @requires extension Memcache
- */
-class MemcacheCacheLockDriverTest extends LockTest
-{
- protected function getInstance()
- {
- $configMock = \Mockery::mock(Configuration::class);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'memcache_host')
- ->andReturn('localhost');
- $configMock
- ->shouldReceive('get')
- ->with('system', 'memcache_port')
- ->andReturn(11211);
-
- return new CacheLockDriver(new MemcacheCacheDriver('localhost', $configMock));
- }
-}
--- /dev/null
+<?php
+
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Friendica\Core\Cache\MemcacheCache;
+use Friendica\Core\Config\Configuration;
+use Friendica\Core\Lock\CacheLockDriver;
+
+/**
+ * @requires extension Memcache
+ */
+class MemcacheCacheLockTest extends LockTest
+{
+ protected function getInstance()
+ {
+ $configMock = \Mockery::mock(Configuration::class);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'memcache_host')
+ ->andReturn('localhost');
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'memcache_port')
+ ->andReturn(11211);
+
+ return new CacheLockDriver(new MemcacheCache('localhost', $configMock));
+ }
+}
+++ /dev/null
-<?php
-
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Friendica\Core\Cache\MemcachedCacheDriver;
-use Friendica\Core\Config\Configuration;
-use Friendica\Core\Lock\CacheLockDriver;
-use Psr\Log\NullLogger;
-
-/**
- * @requires extension memcached
- */
-class MemcachedCacheLockDriverTest extends LockTest
-{
- protected function getInstance()
- {
- $configMock = \Mockery::mock(Configuration::class);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'memcached_hosts')
- ->andReturn([0 => 'localhost, 11211']);
-
- $logger = new NullLogger();
-
- return new CacheLockDriver(new MemcachedCacheDriver('localhost', $configMock, $logger));
- }
-}
--- /dev/null
+<?php
+
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Friendica\Core\Cache\MemcachedCache;
+use Friendica\Core\Config\Configuration;
+use Friendica\Core\Lock\CacheLockDriver;
+use Psr\Log\NullLogger;
+
+/**
+ * @requires extension memcached
+ */
+class MemcachedCacheLockTest extends LockTest
+{
+ protected function getInstance()
+ {
+ $configMock = \Mockery::mock(Configuration::class);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'memcached_hosts')
+ ->andReturn([0 => 'localhost, 11211']);
+
+ $logger = new NullLogger();
+
+ return new CacheLockDriver(new MemcachedCache('localhost', $configMock, $logger));
+ }
+}
+++ /dev/null
-<?php
-
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Friendica\Core\Cache\RedisCacheDriver;
-use Friendica\Core\Config\Configuration;
-use Friendica\Core\Lock\CacheLockDriver;
-
-/**
- * @requires extension redis
- */
-class RedisCacheLockDriverTest extends LockTest
-{
- protected function getInstance()
- {
- $configMock = \Mockery::mock(Configuration::class);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_host')
- ->andReturn('localhost');
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_port')
- ->andReturn(null);
-
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_db', 0)
- ->andReturn(3);
- $configMock
- ->shouldReceive('get')
- ->with('system', 'redis_password')
- ->andReturn(null);
-
- return new CacheLockDriver(new RedisCacheDriver('localhost', $configMock));
- }
-}
--- /dev/null
+<?php
+
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Friendica\Core\Cache\RedisCache;
+use Friendica\Core\Config\Configuration;
+use Friendica\Core\Lock\CacheLockDriver;
+
+/**
+ * @requires extension redis
+ */
+class RedisCacheLockTest extends LockTest
+{
+ protected function getInstance()
+ {
+ $configMock = \Mockery::mock(Configuration::class);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_host')
+ ->andReturn('localhost');
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_port')
+ ->andReturn(null);
+
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_db', 0)
+ ->andReturn(3);
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'redis_password')
+ ->andReturn(null);
+
+ return new CacheLockDriver(new RedisCache('localhost', $configMock));
+ }
+}
+++ /dev/null
-<?php
-
-namespace Friendica\Test\src\Core\Lock;
-
-use Dice\Dice;
-use Friendica\App;
-use Friendica\BaseObject;
-use Friendica\Core\Config\Configuration;
-use Friendica\Core\Lock\SemaphoreLockDriver;
-
-class SemaphoreLockDriverTest extends LockTest
-{
- public function setUp()
- {
- parent::setUp();
-
- $dice = \Mockery::mock(Dice::class)->makePartial();
-
- $app = \Mockery::mock(App::class);
- $app->shouldReceive('getHostname')->andReturn('friendica.local');
- $dice->shouldReceive('create')->with(App::class)->andReturn($app);
-
- $configMock = \Mockery::mock(Configuration::class);
- $configMock
- ->shouldReceive('get')
- ->with('system', 'temppath', NULL, false)
- ->andReturn('/tmp/');
- $dice->shouldReceive('create')->with(Configuration::class)->andReturn($configMock);
-
- // @todo Because "get_temppath()" is using static methods, we have to initialize the BaseObject
- BaseObject::setDependencyInjection($dice);
- }
-
- protected function getInstance()
- {
- return new SemaphoreLockDriver();
- }
-
- function testLockTTL()
- {
- // Semaphore doesn't work with TTL
- return true;
- }
-}
--- /dev/null
+<?php
+
+namespace Friendica\Test\src\Core\Lock;
+
+use Dice\Dice;
+use Friendica\App;
+use Friendica\BaseObject;
+use Friendica\Core\Config\Configuration;
+use Friendica\Core\Lock\SemaphoreLock;
+
+class SemaphoreLockTest extends LockTest
+{
+ public function setUp()
+ {
+ parent::setUp();
+
+ $dice = \Mockery::mock(Dice::class)->makePartial();
+
+ $app = \Mockery::mock(App::class);
+ $app->shouldReceive('getHostname')->andReturn('friendica.local');
+ $dice->shouldReceive('create')->with(App::class)->andReturn($app);
+
+ $configMock = \Mockery::mock(Configuration::class);
+ $configMock
+ ->shouldReceive('get')
+ ->with('system', 'temppath', NULL, false)
+ ->andReturn('/tmp/');
+ $dice->shouldReceive('create')->with(Configuration::class)->andReturn($configMock);
+
+ // @todo Because "get_temppath()" is using static methods, we have to initialize the BaseObject
+ BaseObject::setDependencyInjection($dice);
+ }
+
+ protected function getInstance()
+ {
+ return new SemaphoreLock();
+ }
+
+ function testLockTTL()
+ {
+ // Semaphore doesn't work with TTL
+ return true;
+ }
+}