OwlCyberSecurity - MANAGER
Edit File: RelayConnection.php
<?php /** * Copyright © 2019-2026 Rhubarb Tech Inc. All Rights Reserved. * * The Object Cache Pro Software and its related materials are property and confidential * information of Rhubarb Tech Inc. Any reproduction, use, distribution, or exploitation * of the Object Cache Pro Software and its related materials, in whole or in part, * is strictly forbidden unless prior permission is obtained from Rhubarb Tech Inc. * * In addition, any reproduction, use, distribution, or exploitation of the Object Cache Pro * Software and its related materials, in whole or in part, is subject to the End-User License * Agreement accessible in the included `LICENSE` file, or at: https://objectcache.pro/eula */ declare(strict_types=1); namespace RedisCachePro\Connections; use RedisCachePro\Clients\Relay; use RedisCachePro\Clients\ClientInterface; use RedisCachePro\Connectors\RelayConnector; use RedisCachePro\Configuration\Configuration; use RedisCachePro\Exceptions\ConnectionException; /** * @mixin \RedisCachePro\Clients\Relay */ class RelayConnection extends PhpRedisConnection implements ConnectionInterface { /** * The Relay client. * * @var \RedisCachePro\Clients\Relay */ protected $client; /** * Create a new Relay instance connection. * * @param \RedisCachePro\Clients\Relay $client * @param \RedisCachePro\Configuration\Configuration $config */ public function __construct(Relay $client, Configuration $config) { $this->client = $client; $this->config = $config; $this->log = $this->config->logger; $this->setSerializer(); $this->setCompression(); if (RelayConnector::supports('backoff')) { $this->setBackoff(); } if (RelayConnector::supports('get-meta')) { $this->supportsGetWithMeta = true; } $this->setRelayOptions(); } /** * Set the connection's Relay specific options. * * @return void */ protected function setRelayOptions() { if ($this->config->relay->invalidations === false) { $this->client->setOption($this->client::OPT_CLIENT_INVALIDATIONS, false); } if (is_array($this->config->relay->allowed) && RelayConnector::supports('allow-patterns')) { $this->client->setOption($this->client::OPT_ALLOW_PATTERNS, $this->config->relay->allowed); } if (is_array($this->config->relay->ignored)) { $this->client->setOption($this->client::OPT_IGNORE_PATTERNS, $this->config->relay->ignored); } } /** * Returns the connection's client. * * @return \RedisCachePro\Clients\Relay */ public function client(): ClientInterface { return $this->client; } /** * Dispatch invalidation events. * * Bypasses the `command()` method to avoid log spam. * * @return int|false */ public function dispatchEvents() { return $this->client->dispatchEvents(); } /** * Registers an event listener. * * Bypasses the `command()` method to avoid log spam. * * @param callable $callback * @return bool */ public function listen(callable $callback) { return $this->client->listen($callback); } /** * Registers an event listener for flushes. * * Bypasses the `command()` method to avoid log spam. * * @param callable $callback * @return bool */ public function onFlushed(callable $callback) { return $this->client->onFlushed($callback); } /** * Registers an event listener for invalidations. * * Bypasses the `command()` method to avoid log spam. * * @param callable $callback * @param ?string $pattern * @return bool */ public function onInvalidated(callable $callback, ?string $pattern = null) { return $this->client->onInvalidated($callback, $pattern); } /** * Returns the number of bytes allocated, or `0` in client-only mode. * * Bypasses the `command()` method to avoid log spam. * * @return int */ public function maxMemory() { return $this->client()->maxMemory(); } /** * Returns statistics about Relay. * * Bypasses the `command()` method to avoid log spam. * * @return array<mixed> */ public function stats() { return $this->client()->stats(); } /** * Returns information about the Relay license. * * Bypasses the `command()` method to avoid log spam. * * @return array<mixed> */ public function license() { return $this->client()->license(); } /** * Returns the connections endpoint identifier. * * Bypasses the `command()` method to avoid log spam. * * @return string|false */ public function endpointId() { return $this->client()->endpointId(); } /** * Returns the adaptive cache object. * * Bypasses the `command()` method to avoid log spam. * * @return \Relay\AdaptiveCache|false */ public function adaptiveCache() { return $this->client()->adaptiveCache(); } /** * Flush the selected Redis database. * * Relay will always use asynchronous flushing, regardless of * the `async_flush` configuration option or `$async` parameter. * * @param bool|null $sync * @return bool */ public function flushdb($sync = null) { if ($sync ?? ! $this->config->async_flush) { return $this->withoutTimeout(function () { return $this->command('flushdb'); }); } $asyncValue = \version_compare((string) \phpversion('relay'), '0.6.9', '<') ? true // Relay < 0.6.9 : false; // Relay >= 0.6.9 return $this->command('flushdb', [$asyncValue]); } /** * Flushes Relay's in-memory cache. * * Bypasses the `command()` method to avoid log spam. * * @param string|null $endpointId * @param int|null $db * @return mixed */ public function flushMemory(?string $endpointId = null, ?int $db = null) { return $this->client()->flushMemory($endpointId, $db); } /** * Returns the timestamp of the last in-memory cache flush. * * Bypasses the `command()` method to avoid log spam. * * @param string|null $endpointId * @param int|null $db * @return mixed */ public function lastMemoryFlush(?string $endpointId = null, ?int $db = null) { return $this->client()->lastMemoryFlush($endpointId, $db); } /** * Returns the memoized result from the given command. * * @param string $command * @return mixed */ public function memoize($command) { if ($command === 'ping') { /** @var int|false $idleTime */ $idleTime = $this->client()->idleTime(); return $idleTime > 1000 ? $this->client()->ping() : true; } return parent::memoize($command); } /** * Whether the Relay connection uses in-memory caching, or is only a client. * * @return bool */ public function hasInMemoryCache() { static $cache = null; if (is_null($cache)) { $cache = $this->config->relay->cache && $this->maxMemory() > 0; } return $cache; } /** * Returns the number of keys cached in memory for the current connection. * * @return int|float */ public function keysInMemory() { $stats = $this->memoize('stats'); $endpointId = $this->endpointId(); return array_sum(array_map(function ($connection) { return $connection['keys'][$this->config->database] ?? 0; }, $stats['endpoints'][$endpointId]['connections'] ?? [])) ?: 0; } /** * Flushes the Relay memory for the current FPM pool if needed. * * @param float $flushRequestedAt * @param int $database * @return void */ public function maybeFlushRelayMemory($flushRequestedAt, $database) { $endpoint = $this->endpointId() ?: null; $flushedAt = $this->lastMemoryFlush($endpoint, $database); if ($flushedAt < $flushRequestedAt) { $this->flushMemory($endpoint, $database); } } /** * The `CONFIG` container command for runtime configuration commands. * * @param string $command * @param string ...$args * @return mixed */ public function config($command, ...$args) { $command = strtolower($command); array_unshift($args, $command); try { return $this->command('config', $args); } catch (ConnectionException $exception) { return false; } } /** * The `SLOWLOG` container command for slowlog commands. * * @param string $command * @param string ...$args * @return mixed */ public function slowlog($command, ...$args) { $command = strtolower($command); array_unshift($args, $command); try { return $this->command('slowlog', $args); } catch (ConnectionException $exception) { return false; } } }