lib/Phpfastcache/Cluster/Drivers/MasterSlaveReplication/Driver.php
<?php /** * * This file is part of Phpfastcache. * * @license MIT License (MIT) * * For full copyright and license information, please see the docs/CREDITS.txt file. * * @author Georges.L (Geolim4) <contact@geolim4.com> * */ declare(strict_types=1); namespace Phpfastcache\Cluster\Drivers\MasterSlaveReplication; use Phpfastcache\Cluster\AggregatablePoolInterface;use Phpfastcache\Cluster\ClusterPoolAbstract;use Phpfastcache\Core\Item\ExtendedCacheItemInterface;use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;use Phpfastcache\Event\Event;use Phpfastcache\Event\EventManagerInterface;use Phpfastcache\Exceptions\PhpfastcacheCoreException;use Phpfastcache\Exceptions\PhpfastcacheDriverCheckException;use Phpfastcache\Exceptions\PhpfastcacheDriverConnectException;use Phpfastcache\Exceptions\PhpfastcacheDriverException;use Phpfastcache\Exceptions\PhpfastcacheExceptionInterface;use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;use Phpfastcache\Exceptions\PhpfastcacheIOException;use Phpfastcache\Exceptions\PhpfastcacheReplicationException;use Psr\Cache\CacheItemInterface; class Driver extends ClusterPoolAbstract{ /** * MasterSlaveReplicationCluster constructor. * @param string $clusterName * @param EventManagerInterface $em * @param AggregatablePoolInterface ...$driverPools * @throws PhpfastcacheDriverCheckException * @throws PhpfastcacheDriverConnectException * @throws PhpfastcacheInvalidArgumentException * @throws PhpfastcacheCoreException * @throws PhpfastcacheDriverException * @throws PhpfastcacheIOException */ public function __construct(string $clusterName, EventManagerInterface $em, AggregatablePoolInterface ...$driverPools) { if (\count($driverPools) !== 2) { throw new PhpfastcacheInvalidArgumentException('A "master/slave" cluster requires exactly two pools to be working.'); } parent::__construct($clusterName, $em, ...$driverPools); } /** * @inheritDoc */ public function getItem(string $key): ExtendedCacheItemInterface { return $this->getStandardizedItem( $this->makeOperation(static function (ExtendedCacheItemPoolInterface $pool) use ($key) { return $pool->getItem($key); }) ?? (new Item($this, $key, $this->getEventManager()))->expiresAfter((int) abs($this->getConfig()->getDefaultTtl())), $this ); } /** * @param callable $operation * @return mixed * @throws PhpfastcacheReplicationException */ protected function makeOperation(callable $operation) { try { return $operation($this->getMasterPool()); } catch (PhpfastcacheExceptionInterface $e) { try { $this->eventManager->dispatch( Event::CACHE_REPLICATION_SLAVE_FALLBACK, $this, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['function'] ); return $operation($this->getSlavePool()); } catch (PhpfastcacheExceptionInterface $e) { throw new PhpfastcacheReplicationException('Master and Slave thrown an exception !'); } } } /** * @return AggregatablePoolInterface */ protected function getMasterPool(): AggregatablePoolInterface { return $this->clusterPools[0]; } /** * @return AggregatablePoolInterface */ protected function getSlavePool(): AggregatablePoolInterface { return $this->clusterPools[1]; } /** * @inheritDoc */ public function hasItem(string $key): bool { return $this->makeOperation( static fn (ExtendedCacheItemPoolInterface $pool) => $pool->hasItem($key) ); } /** * @inheritDoc */ public function clear(): bool { return $this->makeOperation( static fn (ExtendedCacheItemPoolInterface $pool) => $pool->clear() ); } /** * @inheritDoc */ public function deleteItem(string $key): bool { return $this->makeOperation( static fn (ExtendedCacheItemPoolInterface $pool) => $pool->deleteItem($key) ); } /** * @inheritDoc */ public function save(CacheItemInterface $item): bool { return $this->makeOperation( function (ExtendedCacheItemPoolInterface $pool) use ($item) { /** @var ExtendedCacheItemInterface $item */ $item->setHit(true); return $pool->save($this->getStandardizedItem($item, $pool)); } ); } /** * @inheritDoc */ public function commit(): bool { return $this->makeOperation( static fn (ExtendedCacheItemPoolInterface $pool) => $pool->commit() ); }}