Skip to content

Commit

Permalink
Add legacy cache wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
SQKo committed Dec 3, 2023
1 parent 269e4e2 commit 709aaa7
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 12 deletions.
8 changes: 5 additions & 3 deletions src/Discord/Discord.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,9 @@ 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->cacheConfig = $options['cache'];
$this->logger->warning('Attached experimental CacheInterface: '.get_class($this->getCacheConfig()->interface));
if ($cacheConfig = $this->getCacheConfig()) {
$this->logger->warning('Attached experimental CacheInterface: '.get_class($cacheConfig->interface));
}

$connector = new SocketConnector($options['socket_options'], $this->loop);
$this->wsFactory = new Connector($this->loop, $connector);
Expand Down Expand Up @@ -1579,11 +1581,11 @@ public function getHttp(): Http
*
* @param string $name Repository class name.
*
* @return CacheConfig
* @return ?CacheConfig
*/
public function getCacheConfig($repository_class = AbstractRepository::class)
{
if (! isset($this->cacheConfig[$repository_class])) {
if (! array_key_exists($repository_class, $this->cacheConfig)) {
$repository_class = AbstractRepository::class;
}

Expand Down
7 changes: 3 additions & 4 deletions src/Discord/Helpers/CacheWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
*
* @since 10.0.0
*
* @property-read \React\Cache\CacheInterface|\Psr\SimpleCache\CacheInterface $interface The actual ReactPHP PSR-16 CacheInterface.
* @property-read CacheConfig $config Cache configuration.
* @property-read CacheConfig $config Cache configuration.
*/
class CacheWrapper
{
Expand Down Expand Up @@ -506,8 +505,8 @@ public function sweep(): int

public function __get(string $name)
{
if (in_array($name, ['interface', 'config'])) {
return $this->$name;
if ($name === 'config') {
return $this->config;
}
}
}
207 changes: 207 additions & 0 deletions src/Discord/Helpers/LegacyCacheWrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<?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;

use Discord\Discord;
use Discord\Parts\Part;
use React\Promise\PromiseInterface;

use function React\Promise\resolve;

/**
* Legacy v7.x in memory cache behavior
*
* @since 10.0.0
* @internal
*/
final class LegacyCacheWrapper extends CacheWrapper
{
/**
* Repository items array reference.
*
* @var ?Part[] Cache Key => Cache Part.
*/
protected $items;

/**
* @param Discord $discord
* @param array &$items Repository items passed by reference.
* @param string &$class Part class name.
*
* @internal
*/
public function __construct(Discord $discord, &$items, string &$class)
{
$this->discord = $discord;
$this->items = &$items;
$this->class = &$class;

$this->prefix = '';
}

public function __destruct()
{
}

/**
* Get Part from cache.
*
* @param string $key
* @param mixed $default
*
* @return PromiseInterface<mixed>
*/
public function get($key, $default = null)
{
return resolve($this->items[$key] ?? $default);
}

/**
* Set Part into cache.
*
* @param string $key
* @param Part $value
*
* @return PromiseInterface<bool>
*/
public function set($key, $value, $ttl = null)
{
$this->items[$key] = $value;

return resolve(true);
}

/**
* Delete Part from cache.
*
* @param string $key
*
* @return PromiseInterface<bool>
*/
public function delete($key)
{
if (!array_key_exists($key, $this->items)) {
return resolve(false);
}

unset($this->items[$key]);

return resolve(true);
}

/**
* Get multiple Parts from cache.
*
* @param array $keys
* @param ?Part $default
*
* @return PromiseInterface<array>
*/
public function getMultiple(array $keys, $default = null)
{
$items = [];
foreach ($keys as $key) {
$items[$key] = $this->items[$key] ?? $default;
}

return resolve($items);
}

/**
* Set multiple Parts into cache.
*
* @param Part[] $values
*
* @return PromiseInterface<bool>
*/
public function setMultiple(array $values, $ttl = null)
{
foreach ($values as $key => $value) {
$this->items[$key] = $value;
}

return resolve(true);
}

/**
* Delete multiple Parts from cache.
*
* @param array $keys
*
* @return PromiseInterface<bool>
*/
public function deleteMultiple(array $keys)
{
foreach ($keys as $key) {
unset($this->items[$key]);
}

return resolve(true);
}

/**
* Clear all Parts from cache.
*
* @return PromiseInterface<bool>
*/
public function clear()
{
$this->items = [];

return resolve(true);
}

/**
* Check if Part is present in cache.
*
* @param string $key
*
* @return PromiseInterface<bool>
*/
public function has($key)
{
return resolve(array_key_exists($key, $this->items));
}

/**
* @param Part $part
*
* @return object
*/
public function serializer($part)
{
return (object) (get_object_vars($part) + ['attributes' => $part->getRawAttributes()]);
}

/**
* @param object $value
*
* @return ?Part
*/
public function unserializer($value)
{
if (empty($value->attributes)) {
$this->discord->getLogger()->warning('Cached Part::$attributes is empty', ['class' => $this->class, 'interface' => 'LEGACY', 'data' => $value]);
}
if (empty($value->created)) {
$this->discord->getLogger()->warning('Cached Part::$created is empty', ['class' => $this->class, 'interface' => 'LEGACY', 'data' => $value]);
}
$part = $this->discord->getFactory()->part($this->class, $value->attributes, $value->created);
foreach ($value as $name => $var) {
if (!in_array($name, ['created', 'attributes'])) {
$part->{$name} = $var;
}
}

return $part;
}
}
15 changes: 10 additions & 5 deletions src/Discord/Repository/AbstractRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Discord\Factory\Factory;
use Discord\Helpers\CacheWrapper;
use Discord\Helpers\Collection;
use Discord\Helpers\LegacyCacheWrapper;
use Discord\Http\Endpoint;
use Discord\Http\Http;
use Discord\Parts\Part;
Expand Down Expand Up @@ -90,7 +91,11 @@ public function __construct(Discord $discord, array $vars = [])
$this->http = $discord->getHttpClient();
$this->factory = $discord->getFactory();
$this->vars = $vars;
$this->cache = new CacheWrapper($discord, $discord->getCacheConfig(static::class), $this->items, $this->class, $this->vars);
if ($cacheConfig = $discord->getCacheConfig(static::class)) {
$this->cache = new CacheWrapper($discord, $cacheConfig, $this->items, $this->class, $this->vars);
} else {
$this->cache = new LegacyCacheWrapper($discord, $this->items, $this->class);
}

parent::__construct([], $this->discrim, $this->class);
}
Expand Down Expand Up @@ -124,7 +129,7 @@ public function freshen(array $queryparams = []): ExtendedPromiseInterface
} elseif (! ($this->items[$offset] instanceof WeakReference)) {
$this->items[$offset] = WeakReference::create($value);
}
$this->cache->interface->delete($this->cache->getPrefix().$offset);
$this->cache->delete($offset);
}

return $this->cacheFreshen($response);
Expand Down Expand Up @@ -412,7 +417,7 @@ public function set($offset, $value)
return;
}

$this->cache->interface->set($this->cache->getPrefix().$offset, $this->cache->serializer($value), $this->cache->config->ttl);
$this->cache->set($offset, $value, $this->cache->config->ttl);
$this->items[$offset] = $value;
}

Expand All @@ -431,7 +436,7 @@ public function pull($key, $default = null)
if ($item = $this->offsetGet($key)) {
$default = $item;
unset($this->items[$key]);
$this->cache->interface->delete($this->cache->getPrefix().$key);
$this->cache->delete($key);
}

return $default;
Expand Down Expand Up @@ -466,7 +471,7 @@ public function pushItem($item): self
if (is_a($item, $this->class)) {
$key = $item->{$this->discrim};
$this->items[$key] = $item;
$this->cache->interface->set($this->cache->getPrefix().$key, $this->cache->serializer($item), $this->cache->config->ttl);
$this->cache->set($key, $item);
}

return $this;
Expand Down

0 comments on commit 709aaa7

Please sign in to comment.