lib/Phpfastcache/Cluster/Drivers/FullReplication/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\FullReplication;
use Phpfastcache\Cluster\ClusterPoolAbstract;
use Phpfastcache\Config\ConfigurationOption;
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
use Psr\Cache\CacheItemInterface;
class Driver extends ClusterPoolAbstract
{
/**
* @inheritDoc
*/
public function getItem(string $key): ExtendedCacheItemInterface
{
/** @var ExtendedCacheItemPoolInterface[] $poolsToResync */
$poolsToResync = [];
/** @var ?ExtendedCacheItemInterface $item */
$item = null;
foreach ($this->clusterPools as $driverPool) {
$poolItem = $driverPool->getItem($key);
if ($poolItem->isHit()) {
if (!$item) {
$item = $poolItem;
continue;
}
$itemData = $item->get();
$poolItemData = $poolItem->get();
if (\is_object($itemData)) {
if ($item->get() != $poolItemData) {
$poolsToResync[] = $driverPool;
}
} else {
if ($item->get() !== $poolItemData) {
$poolsToResync[] = $driverPool;
}
}
} else {
$poolsToResync[] = $driverPool;
}
}
$this->resynchronizePool($poolsToResync, $key, $item);
if ($item === null) {
$item = new Item($this, $key, $this->getEventManager());
$item->expiresAfter((int) abs($this->getConfig()->getDefaultTtl()));
}
return $this->getStandardizedItem($item, $this);
}
/**
* @inheritDoc
*/
public function hasItem(string $key): bool
{
foreach ($this->clusterPools as $driverPool) {
$poolItem = $driverPool->getItem($key);
if ($poolItem->isHit()) {
return true;
}
}
return false;
}
/**
* @inheritDoc
*/
public function clear(): bool
{
$hasClearedOnce = false;
foreach ($this->clusterPools as $driverPool) {
if ($result = $driverPool->clear()) {
$hasClearedOnce = $result;
}
}
// Return true only if at least one backend confirmed the "clear" operation
return $hasClearedOnce;
}
/**
* @inheritDoc
*/
public function deleteItem(string $key): bool
{
$hasDeletedOnce = false;
foreach ($this->clusterPools as $driverPool) {
if ($result = $driverPool->deleteItem($key)) {
$hasDeletedOnce = $result;
}
}
// Return true only if at least one backend confirmed the "clear" operation
return $hasDeletedOnce;
}
/**
* @inheritDoc
*/
public function save(CacheItemInterface $item): bool
{
/** @var ExtendedCacheItemInterface $item */
$hasSavedOnce = false;
foreach ($this->clusterPools as $driverPool) {
$poolItem = $this->getStandardizedItem($item, $driverPool);
if ($result = $driverPool->save($poolItem)) {
$hasSavedOnce = $result;
}
}
// Return true only if at least one backend confirmed the "commit" operation
return $hasSavedOnce;
}
/**
* @inheritDoc
*/
public function saveDeferred(CacheItemInterface $item): bool
{
/** @var ExtendedCacheItemInterface $item */
$hasSavedOnce = false;
foreach ($this->clusterPools as $driverPool) {
$poolItem = $this->getStandardizedItem($item, $driverPool);
if ($result = $driverPool->saveDeferred($poolItem)) {
$hasSavedOnce = $result;
}
}
// Return true only if at least one backend confirmed the "commit" operation
return $hasSavedOnce;
}
/**
* @inheritDoc
*/
public function commit(): bool
{
$hasCommitOnce = false;
foreach ($this->clusterPools as $driverPool) {
if ($result = $driverPool->commit()) {
$hasCommitOnce = $result;
}
}
// Return true only if at least one backend confirmed the "commit" operation
return $hasCommitOnce;
}
/**
* @param ExtendedCacheItemPoolInterface[] $poolsToResynchronize
* @param string $key
* @param ?ExtendedCacheItemInterface $item
* @return void
* @throws \Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException
*/
protected function resynchronizePool(array $poolsToResynchronize, string $key, ?ExtendedCacheItemInterface $item): void
{
if ($item && $item->isHit() && \count($poolsToResynchronize) < \count($this->clusterPools)) {
foreach ($poolsToResynchronize as $poolToResynchronize) {
$poolItem = $poolToResynchronize->getItem($key);
$poolItem->setEventManager($this->getEventManager())
->set($item->get())
->setHit($item->isHit())
->setTags($item->getTags())
->expiresAt($item->getExpirationDate())
->setDriver($poolToResynchronize);
$poolToResynchronize->save($poolItem);
}
}
}
}