Driver::save()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 12
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\Drivers\FullReplication;
18
19
use Phpfastcache\Cluster\ClusterPoolAbstract;
20
use Phpfastcache\Config\ConfigurationOption;
21
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
22
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
23
use Psr\Cache\CacheItemInterface;
24
25
class Driver extends ClusterPoolAbstract
26
{
27
    /**
28
     * @inheritDoc
29
     */
30
    public function getItem(string $key): ExtendedCacheItemInterface
31
    {
32
        /** @var ExtendedCacheItemPoolInterface[] $poolsToResync */
33
        $poolsToResync = [];
34
        /** @var ?ExtendedCacheItemInterface $item */
35
        $item = null;
36
37
        foreach ($this->clusterPools as $driverPool) {
38
            $poolItem = $driverPool->getItem($key);
39
            if ($poolItem->isHit()) {
40
                if (!$item) {
41
                    $item = $poolItem;
42
                    continue;
43
                }
44
45
                $itemData = $item->get();
46
                $poolItemData = $poolItem->get();
47
48
                if (\is_object($itemData)) {
49
                    if ($item->get() != $poolItemData) {
50
                        $poolsToResync[] = $driverPool;
51
                    }
52
                } else {
53
                    if ($item->get() !== $poolItemData) {
54
                        $poolsToResync[] = $driverPool;
55
                    }
56
                }
57
            } else {
58
                $poolsToResync[] = $driverPool;
59
            }
60
        }
61
62
        $this->resynchronizePool($poolsToResync, $key, $item);
63
64
        if ($item === null) {
65
            $item = new Item($this, $key, $this->getEventManager());
66
            $item->expiresAfter((int) abs($this->getConfig()->getDefaultTtl()));
67
        }
68
69
        return $this->getStandardizedItem($item, $this);
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75
    public function hasItem(string $key): bool
76
    {
77
        foreach ($this->clusterPools as $driverPool) {
78
            $poolItem = $driverPool->getItem($key);
79
            if ($poolItem->isHit()) {
80
                return true;
81
            }
82
        }
83
84
        return false;
85
    }
86
87
    /**
88
     * @inheritDoc
89
     */
90
    public function clear(): bool
91
    {
92
        $hasClearedOnce = false;
93
        foreach ($this->clusterPools as $driverPool) {
94
            if ($result = $driverPool->clear()) {
95
                $hasClearedOnce = $result;
96
            }
97
        }
98
        // Return true only if at least one backend confirmed the "clear" operation
99
        return $hasClearedOnce;
100
    }
101
102
    /**
103
     * @inheritDoc
104
     */
105
    public function deleteItem(string $key): bool
106
    {
107
        $hasDeletedOnce = false;
108
        foreach ($this->clusterPools as $driverPool) {
109
            if ($result = $driverPool->deleteItem($key)) {
110
                $hasDeletedOnce = $result;
111
            }
112
        }
113
        // Return true only if at least one backend confirmed the "clear" operation
114
        return $hasDeletedOnce;
115
    }
116
117
    /**
118
     * @inheritDoc
119
     */
120
    public function save(CacheItemInterface $item): bool
121
    {
122
        /** @var ExtendedCacheItemInterface $item */
123
        $hasSavedOnce = false;
124
        foreach ($this->clusterPools as $driverPool) {
125
            $poolItem = $this->getStandardizedItem($item, $driverPool);
126
            if ($result = $driverPool->save($poolItem)) {
127
                $hasSavedOnce = $result;
128
            }
129
        }
130
        // Return true only if at least one backend confirmed the "commit" operation
131
        return $hasSavedOnce;
132
    }
133
134
    /**
135
     * @inheritDoc
136
     */
137
    public function saveDeferred(CacheItemInterface $item): bool
138
    {
139
        /** @var ExtendedCacheItemInterface $item */
140
        $hasSavedOnce = false;
141
        foreach ($this->clusterPools as $driverPool) {
142
            $poolItem = $this->getStandardizedItem($item, $driverPool);
143
            if ($result = $driverPool->saveDeferred($poolItem)) {
144
                $hasSavedOnce = $result;
145
            }
146
        }
147
        // Return true only if at least one backend confirmed the "commit" operation
148
        return $hasSavedOnce;
149
    }
150
151
    /**
152
     * @inheritDoc
153
     */
154
    public function commit(): bool
155
    {
156
        $hasCommitOnce = false;
157
        foreach ($this->clusterPools as $driverPool) {
158
            if ($result = $driverPool->commit()) {
159
                $hasCommitOnce = $result;
160
            }
161
        }
162
        // Return true only if at least one backend confirmed the "commit" operation
163
        return $hasCommitOnce;
164
    }
165
166
    /**
167
     * @param ExtendedCacheItemPoolInterface[] $poolsToResynchronize
168
     * @param string $key
169
     * @param ?ExtendedCacheItemInterface $item
170
     * @return void
171
     * @throws \Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException
172
     */
173
    protected function resynchronizePool(array $poolsToResynchronize, string $key, ?ExtendedCacheItemInterface $item): void
174
    {
175
        if ($item && $item->isHit() && \count($poolsToResynchronize) < \count($this->clusterPools)) {
176
            foreach ($poolsToResynchronize as $poolToResynchronize) {
177
                $poolItem = $poolToResynchronize->getItem($key);
178
                $poolItem->setEventManager($this->getEventManager())
179
                    ->set($item->get())
180
                    ->setHit($item->isHit())
181
                    ->setTags($item->getTags())
182
                    ->expiresAt($item->getExpirationDate())
183
                    ->setDriver($poolToResynchronize);
184
                $poolToResynchronize->save($poolItem);
185
            }
186
        }
187
    }
188
}
189