Skip to content
SQKo edited this page Dec 6, 2022 · 5 revisions

DiscordPHP caching is powered by react/cache or any compatible psr/simple-cache. The Interface can be retrieved from any repositories $repository->cache, e.g.

$discord->users->cache->get('115233618997149700')->then(function ($user) {
    // $user is a cached Part
});

Albeit example, it's preferred to fetch user like usual:

$discord->users->fetch('115233618997149700', true)->then(function ($user) {
    // $user fetched from Discord API will automatically update the cache
});

The cache interfaces are handled in Promise manner, while it may speed up when combined with async, it is worth to note that is not as fast as previous in-memory caching existed since DiscordPHP v5.x. The caching interface suits for those who wants to scale up their Bot and not bound to PHP memory limit nor process, at cost of the speed.

All methods deriving from AbstractRepository (no more Collection) handles the cache implementation already.

Note: Caching libraries containing namespace "Redis" or "Memcached" will have the : colon separator instead of . dot. If you found implementation without the name containing "Redis" or "Memcached", please specify the separator manually with CacheConfig

$psr6Cache = new RedisAdapter($redis, 'dphp', 0); // "Redis" in "RedisAdapter" here will not be detected
$cache = new Psr16Cache($psr6Cache); // Since the wrapper class name does not have "Redis", it will use dot '.', e.g. User.115233618997149700
'cache' => new CacheConfig(interface: $cache, $separator = ':'); // set separator to colon, e.g. User:115233618997149700

The repository prefix can be retrieved from the repository which in the case above $discord->users->cache->getPrefix() would return User:, where User is the name of the Part class.

Known available implementation:

Bundled in ReactPHP Cache, uses in-memory Array, and is used by default.

$cache = new ArrayCache(100); // 100 is the limit with LRU policy

Does not work on Windows

use React\EventLoop\Loop;
use React\Filesystem\Filesystem as ReactFilesystem;
use WyriHaximus\React\Cache\Filesystem;

$loop = Loop::get();
$filesystem = ReactFilesystem::create($loop);
$cache = new Filesystem($filesystem, '/tmp/cache/dphp/');

$discord = new Discord([
    'token' => 'bot token',
    'loop' => $loop, // note the same loop
    'cache' => $cache,
]);

Note the examples below uses ReactPHP-Redis v2.x

use React\EventLoop\Loop;
use WyriHaximus\React\Cache\Redis;

$loop = Loop::get();
$redis = (new Clue\React\Redis\Factory($loop))->createLazyClient('localhost:6379');
$cache = new Redis($redis, 'dphp:'); // prefix is "dphp:"

$discord = new Discord([
    'token' => 'bot token',
    'loop' => $loop, // note the same loop
    'cache' => $cache,
]);

By default the cache key is prefixed reach:cache:, in example above the prefix is set to dphp: so you can get the data as: dphp:User:115233618997149700.

Current version is broken when getting a cache

use React\EventLoop\Factory;
use seregazhuk\React\Cache\Memcached\Memcached;

$loop = Factory::create();
$cache = new Memcached($loop, 'localhost:11211', 'dphp:'); // prefix is "dphp:"

$discord = new Discord([
    'token' => 'bot token',
    'loop' => $loop, // note the same loop
    'cache' => $cache,
]);

By default the cache key is prefixed react:cache:, in example above the prefix is set to dphp: so you can get the data as: dphp:User:115233618997149700.

If you are not fan of ReactPHP Asynchronous Cache library, you can try a compatible PSR-16 Synchronous Cache library, Please note this implementation is slower as it blocks the event loop and may break your bot if not used carefully.

Note the following section uses PSR-16 Adapter

Equivalent to ArrayCache from ReactPHP.

use Symfony\Component\Cache\Adapter\ArrayAdapter;

$psr6Cache = new ArrayAdapter(0, false, 0, 100); // 100 is the limit
$cache = new \Symfony\Component\Cache\Psr16Cache($psr6Cache);

$discord = new Discord([
    'token' => 'bot token',
    'cache' => $cache,
]);

Note the examples below uses Redis PECL

use Symfony\Component\Cache\Adapter\RedisAdapter;

$redis = new \Redis();
$redis->connect('localhost');
$psr6Cache = new RedisAdapter($redis, 'dphp', 0); // prefix is "dphp:"
$cache = new \Symfony\Component\Cache\Psr16Cache($psr6Cache);

$discord = new Discord([
    'token' => 'bot token',
    'cache' => $cache,
]);

Note the examples below uses Memcached PECL

use Symfony\Component\Cache\Adapter\MemcachedAdapter;

$memcached = new \Memcached();
$memcached->addServer('localhost', 11211);
$psr6Cache = new MemcachedAdapter($memcached, 'dphp', 0); // prefix is "dphp:"
$cache = new \Symfony\Component\Cache\Psr16Cache($psr6Cache);

$discord = new Discord([
    'token' => 'bot token',
    'cache' => $cache,
]);

Clone this wiki locally