Passed
Push — master ( 4006b8...c871f9 )
by Georges
02:32 queued 21s
created

ClusterPoolAbstract::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 *
5
 * This file is part of Phpfastcache.
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For full copyright and license information, please see the docs/CREDITS.txt file.
10
 *
11
 * @author  Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Cluster;
18
19
use Phpfastcache\Cluster\Drivers\FullReplication\Driver as FullReplicationCluster;
20
use Phpfastcache\Cluster\Drivers\MasterSlaveReplication\Driver as MasterSlaveReplicationCluster;
21
use Phpfastcache\Cluster\Drivers\RandomReplication\Driver as RandomReplicationCluster;
22
use Phpfastcache\Cluster\Drivers\SemiReplication\Driver as SemiReplicationCluster;
23
use Phpfastcache\Config\ConfigurationOption;
24
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
25
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
26
use Phpfastcache\Core\Pool\TaggableCacheItemPoolTrait;
27
use Phpfastcache\Entities\DriverIO;
28
use Phpfastcache\Entities\DriverStatistic;
29
use Phpfastcache\Event\EventManagerInterface;
30
use Phpfastcache\EventManager;
31
use Phpfastcache\Exceptions\PhpfastcacheCoreException;
32
use Phpfastcache\Exceptions\PhpfastcacheDriverCheckException;
33
use Phpfastcache\Exceptions\PhpfastcacheDriverConnectException;
34
use Phpfastcache\Exceptions\PhpfastcacheDriverException;
35
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
36
use Phpfastcache\Exceptions\PhpfastcacheIOException;
37
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
38
use Psr\Cache\CacheItemInterface;
39
use Psr\Cache\InvalidArgumentException;
40
41
abstract class ClusterPoolAbstract implements ClusterPoolInterface
42
{
43
    use TaggableCacheItemPoolTrait;
44
    use ClusterPoolTrait {
45
        TaggableCacheItemPoolTrait::__construct as private __parentConstruct;
46
    }
47
48
    public const STRATEGY = [
49
        AggregatorInterface::STRATEGY_FULL_REPLICATION => FullReplicationCluster::class,
50
        AggregatorInterface::STRATEGY_SEMI_REPLICATION => SemiReplicationCluster::class,
51
        AggregatorInterface::STRATEGY_MASTER_SLAVE => MasterSlaveReplicationCluster::class,
52
        AggregatorInterface::STRATEGY_RANDOM_REPLICATION => RandomReplicationCluster::class,
53
    ];
54
55
    /**
56
     * @var ExtendedCacheItemPoolInterface[]
57
     */
58
    protected array $clusterPools;
59
60
    /**
61
     * ClusterPoolAbstract constructor.
62
     * @param string $clusterName
63
     * @param EventManagerInterface $em
64
     * @param ExtendedCacheItemPoolInterface ...$driverPools
65
     * @throws PhpfastcacheDriverCheckException
66
     * @throws PhpfastcacheDriverConnectException
67
     * @throws PhpfastcacheInvalidArgumentException
68
     * @throws PhpfastcacheCoreException
69
     * @throws PhpfastcacheDriverException
70
     * @throws PhpfastcacheIOException
71
     */
72
    public function __construct(string $clusterName, EventManagerInterface $em, ExtendedCacheItemPoolInterface ...$driverPools)
73
    {
74
        if (count($driverPools) < 2) {
75
            throw new PhpfastcacheInvalidArgumentException('A cluster requires at least two pools to be working.');
76
        }
77
        $this->clusterPools = $driverPools;
78
        $this->__parentConstruct(new ConfigurationOption(), $clusterName, $em);
79
        $this->setEventManager(EventManager::getInstance());
80
    }
81
82
    /**
83
     * @inheritDoc
84
     */
85
    public function getIO(): DriverIO
86
    {
87
        $io = new DriverIO();
88
        foreach ($this->clusterPools as $clusterPool) {
89
            $io->setReadHit($io->getReadHit() + $clusterPool->getIO()->getReadHit())
90
                ->setReadMiss($io->getReadMiss() + $clusterPool->getIO()->getReadMiss())
91
                ->setWriteHit($io->getWriteHit() + $clusterPool->getIO()->getWriteHit());
92
        }
93
        return $io;
94
    }
95
96
    /**
97
     * @inheritDoc
98
     */
99
    public function getClusterPools(): array
100
    {
101
        return $this->clusterPools;
102
    }
103
104
    /**
105
     * @inheritDoc
106
     */
107
    public function getConfigs(): array
108
    {
109
        $configs = [];
110
111
        foreach ($this->getClusterPools() as $clusterPool) {
112
            $configs[$clusterPool->getDriverName()] = $clusterPool->getConfig();
113
        }
114
115
        return $configs;
116
    }
117
118
    /**
119
     * @inheritDoc
120
     */
121
    public function getItems(array $keys = []): iterable
122
    {
123
        $items = [];
124
125
        foreach ($keys as $key) {
126
            $items[$key] = $this->getItem($key);
127
        }
128
129
        return $items;
130
    }
131
    /**
132
     * Shared method used by All Clusters
133
     */
134
135
    /**
136
     * @inheritDoc
137
     */
138
    public function deleteItems(array $keys): bool
139
    {
140
        $hasDeletedOnce = false;
141
        foreach ($this->clusterPools as $driverPool) {
142
            if ($result = $driverPool->deleteItems($keys)) {
143
                $hasDeletedOnce = $result;
144
            }
145
        }
146
        // Return true only if at least one backend confirmed the "clear" operation
147
        return $hasDeletedOnce;
148
    }
149
150
    /**
151
     * @param CacheItemInterface $item
152
     * @return bool
153
     * @throws InvalidArgumentException
154
     * @throws PhpfastcacheLogicException
155
     */
156
    public function saveDeferred(CacheItemInterface $item): bool
157
    {
158
        /** @var ExtendedCacheItemInterface $item */
159
        $hasSavedOnce = false;
160
        foreach ($this->clusterPools as $driverPool) {
161
            $poolItem = $this->getStandardizedItem($item, $driverPool);
162
            if ($result = $driverPool->saveDeferred($poolItem)) {
163
                $hasSavedOnce = $result;
164
            }
165
        }
166
        // Return true only if at least one backend confirmed the "commit" operation
167
        return $hasSavedOnce;
168
    }
169
170
    /**
171
     * @param ExtendedCacheItemInterface $item
172
     * @param ExtendedCacheItemPoolInterface $driverPool
173
     * @return ExtendedCacheItemInterface
174
     * @throws InvalidArgumentException
175
     * @throws PhpfastcacheLogicException
176
     */
177
    protected function getStandardizedItem(ExtendedCacheItemInterface $item, ExtendedCacheItemPoolInterface $driverPool): ExtendedCacheItemInterface
178
    {
179
        if (!$item->doesItemBelongToThatDriverBackend($driverPool)) {
180
            /**
181
             * Avoid infinite loop
182
             */
183
            if ($driverPool === $this) {
0 ignored issues
show
introduced by
The condition $driverPool === $this is always false.
Loading history...
184
                /** @var ExtendedCacheItemInterface $itemPool */
185
                $itemClass = $driverPool::getItemClass();
186
                $itemPool = new $itemClass($this, $item->getKey(), $this->getEventManager());
187
                $item->cloneInto($itemPool, $driverPool);
188
189
                return $itemPool;
190
            }
191
192
            $itemPool = $driverPool->getItem($item->getKey());
193
            $item->cloneInto($itemPool, $driverPool);
194
195
            return $itemPool;
196
        }
197
198
        return $item->setEventManager($this->getEventManager());
199
    }
200
201
    /**
202
     * @return DriverStatistic
203
     */
204
    public function getStats(): DriverStatistic
205
    {
206
        $stats = new DriverStatistic();
207
        $stats->setInfo(
208
            sprintf(
209
                'Using %d pool(s): %s',
210
                \count($this->clusterPools),
211
                \implode(
212
                    ', ',
213
                    \array_map(
214
                        static fn (ExtendedCacheItemPoolInterface $pool) => \get_class($pool),
215
                        $this->clusterPools
216
                    )
217
                )
218
            )
219
        );
220
221
        $stats->setSize(
222
            (int)\array_sum(
223
                \array_map(
224
                    static fn (ExtendedCacheItemPoolInterface $pool) => $pool->getStats()->getSize(),
225
                    $this->clusterPools
226
                )
227
            )
228
        );
229
230
        $stats->setData(
231
            \implode(
232
                ', ',
233
                \array_map(
234
                    static fn (ExtendedCacheItemPoolInterface $pool) => $pool->getStats()->getData(),
235
                    $this->clusterPools
236
                )
237
            )
238
        );
239
240
        return $stats;
241
    }
242
}
243