Skip to content

Commit

Permalink
Add CacheConfig, replacing cacheInterface, cacheSweep and cacheCompre…
Browse files Browse the repository at this point in the history
…ss (#1003)

* BC: CacheConfig

* wrong conflict merge

* getter and default null
  • Loading branch information
SQKo authored Dec 6, 2022
1 parent c85b9ee commit ded817c
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 38 deletions.
40 changes: 19 additions & 21 deletions src/Discord/Discord.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Discord\Exceptions\IntentException;
use Discord\Factory\Factory;
use Discord\Helpers\BigInt;
use Discord\Helpers\CacheConfig;
use Discord\Http\Http;
use Discord\Parts\Guild\Guild;
use Discord\Parts\OAuth\Application;
Expand Down Expand Up @@ -322,11 +323,11 @@ class Discord
protected $factory;

/**
* The react/cache interface.
* The cache configuration.
*
* @var \React\Cache\CacheInterface[]|\Psr\SimpleCache\CacheInterface[]
* @var CacheConfig
*/
protected $cache;
protected $cacheConfig;

/**
* The Client class.
Expand Down Expand Up @@ -368,8 +369,8 @@ public function __construct(array $options = [])

$this->logger->debug('Initializing DiscordPHP '.self::VERSION.' (DiscordPHP-Http: '.Http::VERSION.' & Gateway: v'.self::GATEWAY_VERSION.') on PHP '.PHP_VERSION);

$this->cache = $options['cacheInterface'];
$this->logger->warning('Attached experimental CacheInterface: '.get_class($this->cache[AbstractRepository::class]));
$this->cacheConfig = $options['cache'];
$this->logger->warning('Attached experimental CacheInterface: '.get_class($this->getCacheConfig()->interface));

$connector = new SocketConnector($options['socket_options'], $this->loop);
$this->wsFactory = new Connector($this->loop, $connector);
Expand Down Expand Up @@ -1385,9 +1386,7 @@ protected function resolveOptions(array $options = []): array
'intents',
'socket_options',
'dnsConfig',
'cacheInterface',
'cacheSweep',
'cacheCompress',
'cache',
])
->setDefaults([
'logger' => null,
Expand All @@ -1397,9 +1396,7 @@ protected function resolveOptions(array $options = []): array
'retrieveBans' => false,
'intents' => Intents::getDefaultIntents(),
'socket_options' => [],
'cacheInterface' => new ArrayCache(),
'cacheSweep' => false,
'cacheCompress' => false,
'cache' => new ArrayCache(),
])
->setAllowedTypes('token', 'string')
->setAllowedTypes('logger', ['null', LoggerInterface::class])
Expand All @@ -1411,11 +1408,12 @@ protected function resolveOptions(array $options = []): array
->setAllowedTypes('intents', ['array', 'int'])
->setAllowedTypes('socket_options', 'array')
->setAllowedTypes('dnsConfig', ['string', \React\Dns\Config\Config::class])
->setAllowedTypes('cacheInterface', ['array', \React\Cache\CacheInterface::class, \Psr\SimpleCache\CacheInterface::class])
->setAllowedTypes('cacheSweep', 'bool')
->setAllowedTypes('cacheCompress', 'bool')
->setNormalizer('cacheInterface', function ($options, $value) {
->setAllowedTypes('cache', ['array', CacheConfig::class, \React\Cache\CacheInterface::class, \Psr\SimpleCache\CacheInterface::class])
->setNormalizer('cache', function ($options, $value) {
if (! is_array($value)) {
if (! ($value instanceof CacheConfig)) {
$value = new CacheConfig($value);
}
return [AbstractRepository::class => $value];
}

Expand Down Expand Up @@ -1577,19 +1575,19 @@ public function getHttp(): Http
}

/**
* Gets the cache interface.
* Gets the cache configuration.
*
* @param string $name Repository class name.
*
* @return \React\Cache\CacheInterface|\Psr\SimpleCache\CacheInterface
* @return CacheConfig
*/
public function getCache($repository_class = AbstractRepository::class)
public function getCacheConfig($repository_class = AbstractRepository::class)
{
if (! isset($this->cache[$repository_class])) {
if (! isset($this->cacheConfig[$repository_class])) {
$repository_class = AbstractRepository::class;
}

return $this->cache[$repository_class];
return $this->cacheConfig[$repository_class];
}

/**
Expand All @@ -1601,7 +1599,7 @@ public function getCache($repository_class = AbstractRepository::class)
*/
public function __get(string $name)
{
$allowed = ['loop', 'options', 'logger', 'http', 'application_commands', 'cache'];
$allowed = ['loop', 'options', 'logger', 'http', 'application_commands'];

if (in_array($name, $allowed)) {
return $this->{$name};
Expand Down
77 changes: 77 additions & 0 deletions src/Discord/Helpers/CacheConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

/*
* This file is a part of the DiscordPHP project.
*
* Copyright (c) 2015-present David Cole <[email protected]>
*
* This file is subject to the MIT license that is bundled
* with this source code in the LICENSE.md file.
*/

namespace Discord\Helpers;

/**
* Cache configuration class. To be used with Discord `cache` Options.
*
* @see Discord
*
* @since 10.0.0
*
* @property-read \React\Cache\CacheInterface|\Psr\SimpleCache\CacheInterface $interface The PSR-16 cache interface.
* @property-read bool $separator The cache key prefix separator if supported by the interface. Usually dot `.` for generic cache or colon `:` for Redis/Memcached.
*/
class CacheConfig
{
/**
* @var \React\Cache\CacheInterface|\Psr\SimpleCache\CacheInterface
*/
protected $interface;

/**
* Whether to compress cache data before serialization, disabled by default, ignored in ArrayCache.
*
* @var bool
*/
public bool $compress = false;

/**
* Whether to automatically sweep cached items from memory, disabled by default.
*
* @var bool
*/
public bool $sweep = false;

/**
* @var string
*/
protected string $separator = '.';

/**
* @param \React\Cache\CacheInterface|\Psr\SimpleCache\CacheInterface $interface The PSR-16 Cache Interface.
* @param bool $compress Whether to compress cache data before serialization, ignored in ArrayCache.
* @param bool $sweep Whether to automatically sweep cache.
* @param string|null $separator The cache key prefix separator, null for default.
*/
public function __construct($interface, bool $compress = false, bool $sweep = false, ?string $separator = null)
{
$this->interface = $interface;
$this->sweep = $sweep;
$this->compress = $compress;
if (null === $separator) {
$separator = '.';
$interfaceName = get_class($interface);
if (stripos($interfaceName, 'Redis') !== false || stripos($interfaceName, 'Memcached') !== false) {
$separator = ':';
}
}
$this->separator = $separator;
}

public function __get(string $name)
{
if (in_array($name, ['interface', 'separator'])) {
return $this->$name;
}
}
}
34 changes: 18 additions & 16 deletions src/Discord/Helpers/CacheWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,30 +67,32 @@ class CacheWrapper
protected $prefix;

/**
* @param Discord $discord
* @param \React\Cache\CacheInterface|\Psr\SimpleCache\CacheInterface $cacheInterface The actual CacheInterface.
* @param array &$items Repository items passed by reference.
* @param string &$class Part class name.
* @param string[] $vars Variable containing hierarchy parent IDs.
* Cache configuration.
*
* @var CacheConfig
*/
protected $config;

/**
* @param Discord $discord
* @param CacheConfig $config The cache configuration.
* @param array &$items Repository items passed by reference.
* @param string &$class Part class name.
* @param string[] $vars Variable containing hierarchy parent IDs.
*
* @internal
*/
public function __construct(Discord $discord, $cacheInterface, &$items, string &$class, array $vars)
public function __construct(Discord $discord, $config, &$items, string &$class, array $vars)
{
$this->discord = $discord;
$this->interface = $cacheInterface;
$this->config = $config;
$this->items = &$items;
$this->class = &$class;

$separator = '.';
$cacheInterfaceName = get_class($cacheInterface);
if (stripos($cacheInterfaceName, 'Redis') !== false || stripos($cacheInterfaceName, 'Memcached') !== false) {
$separator = ':';
}

$this->prefix = implode($separator, [substr(strrchr($this->class, '\\'), 1)] + $vars).$separator;
$this->interface = $config->interface;
$this->prefix = implode($config->separator, [substr(strrchr($this->class, '\\'), 1)] + $vars).$config->separator;

if ($discord->options['cacheSweep']) {
if ($config->sweep) {
// Sweep every heartbeat ack
$discord->on('heartbeat-ack', [$this, 'sweep']);
}
Expand Down Expand Up @@ -424,7 +426,7 @@ public function serializer($part)
if ($this->interface instanceof \React\Cache\CacheInterface && ! ($this->interface instanceof ArrayCache)) {
$data = serialize($data);

if ($this->discord->options['cacheCompress']) {
if ($this->config->compress) {
$data = zlib_encode($data, ZLIB_ENCODING_DEFLATE);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Discord/Repository/AbstractRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function __construct(Discord $discord, array $vars = [])
$this->http = $discord->getHttpClient();
$this->factory = $discord->getFactory();
$this->vars = $vars;
$this->cache = new CacheWrapper($discord, $discord->getCache(static::class), $this->items, $this->class, $this->vars);
$this->cache = new CacheWrapper($discord, $discord->getCacheConfig(static::class), $this->items, $this->class, $this->vars);

parent::__construct([], $this->discrim, $this->class);
}
Expand Down

0 comments on commit ded817c

Please sign in to comment.