[CACHE] Add support for multiple pools with the syntax (as an example) SOCIAL_CACHE_ADAPTER='default=redis://localhost:6379,memcached://localhost:11211;db.config=apcu://'

This commit is contained in:
Hugo Sales 2020-07-11 22:43:05 +00:00 committed by Hugo Sales
parent d35b6f3437
commit c549bea4a9
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
2 changed files with 45 additions and 14 deletions

View File

@ -25,7 +25,7 @@ use Symfony\Component\Cache\Adapter\ChainAdapter;
abstract class Cache abstract class Cache
{ {
protected static AbstractAdapter $pool; protected static AbstractAdapter $pools;
private static string $ENV_VAR = 'SOCIAL_CACHE_ADAPTER'; private static string $ENV_VAR = 'SOCIAL_CACHE_ADAPTER';
/** /**
@ -33,27 +33,58 @@ abstract class Cache
* We may want multiple of these in the future, but for now it seems * We may want multiple of these in the future, but for now it seems
* unnecessary * unnecessary
*/ */
public static function setPool() public static function setupCache()
{ {
if (!isset($_ENV[self::$ENV_VAR])) { if (!isset($_ENV[self::$ENV_VAR])) {
return; die("A cache adapter is needed in the environment variable {$ENV_VAR}");
} }
$adapters = F\map(explode(':', strtolower($_ENV[self::$ENV_VAR])), $adapters = [];
function (string $a) { foreach (explode(';', $_ENV[self::$ENV_VAR]) as $a) {
return 'Adapter\\' . ucfirst($a) . 'Adapter'; list($pool, $val) = explode('=', $a);
}); foreach (explode(',', $val) as $dsn) {
list($scheme, $rest) = explode('://', $dsn);
if (count($adapters) === 1) { switch ($scheme) {
self::$pool = new $adapters[0]; case 'memcached':
} else { // memcached can have multiple servers
self::$pool = new ChainAdapter($adapters); $dsn = F\map(explode(',', $rest), function ($h) use ($scheme) { return $scheme . $h; });
$adapters[$pool][] = new Adapter\MemcachedAdapter($dsn);
break;
case 'filesystem':
$adapters[$pool][] = new Adapter\FilesystemAdapter($rest);
break;
case 'redis':
$adapters[$pool][] = new Adapter\RedisAdapter($dsn);
break;
case 'apcu':
$adapters[$pool][] = new Adapter\ApcuAdapter();
break;
case 'opcache':
$adapters[$pool][] = new Adapter\PhpArrayAdapter(stream_get_meta_data(tmpfile())['uri'], new FilesystemAdapter());
break;
case 'doctrine':
$adapters[$pool][] = new Adapter\PdoAdapter($dsn);
break;
default:
Log::error("Unknown or discouraged cache scheme '{$scheme}'");
return;
}
}
if (count($adapters[$pool]) === 1) {
self::$pools[$pool] = array_pop($adapters[$pool]);
} else {
self::$pools[$pool] = new ChainAdapter($adapters);
}
} }
} }
public static function get(string $key, callable $calculate, float $beta = 1.0) public static function get(string $key, callable $calculate, string $pool = 'default', float $beta = 1.0)
{ {
return self::$pool->get($key, $calculate, $beta); if (self::$pools[$pool] instanceof AbstractAdapter) {
return self::$pool->get($key, $calculate, $beta);
} else {
}
} }
public static function delete(string $key): bool public static function delete(string $key): bool

View File

@ -99,8 +99,8 @@ class GNUsocial implements EventSubscriberInterface
Form::setFactory($this->form_factory); Form::setFactory($this->form_factory);
Queue::setMessageBus($this->message_bus); Queue::setMessageBus($this->message_bus);
Cache::setPool();
DefaultSettings::setDefaults(); DefaultSettings::setDefaults();
Cache::setupCache();
ModulesManager::loadModules(); ModulesManager::loadModules();
} }