Completed
Pull Request — master (#340)
by
unknown
34:53
created

PredisCache::doFetchAtomic()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.7085

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
nc 2
nop 3
dl 0
loc 16
ccs 4
cts 7
cp 0.5714
crap 3.7085
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
namespace Doctrine\Common\Cache;
4
5
use Predis\ClientInterface;
6
use RuntimeException;
7
use function array_combine;
8
use function array_filter;
9
use function array_map;
10
use function call_user_func_array;
11
use function class_exists;
12
use function serialize;
13
use function unserialize;
14
15
/**
16
 * Predis cache provider.
17
 */
18
class PredisCache extends CacheProvider
19
{
20
    /** @var ClientInterface */
21 78
    private $client;
22
23 78
    public function __construct(ClientInterface $client)
24 78
    {
25
        $this->client = $client;
26
    }
27
28
    /**
29 74
     * {@inheritdoc}
30
     */
31 74
    protected function doFetch($id)
32 74
    {
33 64
        $result = $this->client->get($id);
34
        if ($result === null) {
35
            return false;
36 69
        }
37
38
        return unserialize($result);
39
    }
40
41
    /**
42 2
     * {@inheritdoc}
43
     */
44 2
    protected function doFetchAtomic(string $id, callable $generator, int $ttl)
45
    {
46 2
        if (! class_exists('\Predis\Pipeline\Atomic', false)) {
47
            throw new RuntimeException('Atomic fetch (atomic pipeline) is not supported by this version of Predis');
48
        }
49
50
        return $this->client->pipeline(['atomic'], static function ($pipe) use ($id, $generator, $ttl) {
0 ignored issues
show
introduced by
Expected 1 lines after "return", found 0.
Loading history...
51
                $pipelineCache = new static($pipe);
52 1
                if ($pipelineCache->contains($id)) {
53
                    return $pipelineCache->fetch($id);
54 1
                }
55
56
                $data = $generator($id);
57
                $pipelineCache->save($id, $data, $ttl);
58
59
                return $data;
60
            }
0 ignored issues
show
Coding Style introduced by
Closing brace indented incorrectly; expected 8 spaces, found 12
Loading history...
61
        );
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    protected function doFetchMultiple(array $keys)
68
    {
69
        $fetchedItems = call_user_func_array([$this->client, 'mget'], $keys);
70
71
        return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems)));
0 ignored issues
show
Bug introduced by
It seems like array_combine($keys, $fetchedItems) can also be of type false; however, parameter $input of array_filter() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
        return array_map('unserialize', array_filter(/** @scrutinizer ignore-type */ array_combine($keys, $fetchedItems)));
Loading history...
72
    }
73 1
74 1
    /**
75
     * {@inheritdoc}
76 1
     */
77
    protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
78
    {
79
        if ($lifetime) {
80
            $success = true;
81
82 69
            // Keys have lifetime, use SETEX for each of them
83
            foreach ($keysAndValues as $key => $value) {
84 69
                $response = (string) $this->client->setex($key, $lifetime, serialize($value));
85
86
                if ($response == 'OK') {
87
                    continue;
88
                }
89
90 72
                $success = false;
91
            }
92 72
93 72
            return $success;
94 3
        }
95
96 70
        // No lifetime, use MSET
97
        $response = $this->client->mset(array_map(static function ($value) {
98
            return serialize($value);
99 72
        }, $keysAndValues));
100
101
        return (string) $response == 'OK';
102
    }
103
104
    /**
105 43
     * {@inheritdoc}
106
     */
107 43
    protected function doContains($id)
108
    {
109
        return (bool) $this->client->exists($id);
110
    }
111
112
    /**
113 1
     * {@inheritdoc}
114
     */
115 1
    protected function doSave($id, $data, $lifeTime = 0)
116
    {
117
        $data = serialize($data);
118
        if ($lifeTime > 0) {
119
            $response = $this->client->setex($id, $lifeTime, $data);
120
        } else {
121 2
            $response = $this->client->set($id, $data);
122
        }
123 2
124
        return $response === true || $response == 'OK';
125 2
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    protected function doDelete($id)
131 2
    {
132
        return $this->client->del($id) >= 0;
133 2
    }
134
135
    /**
136 2
     * {@inheritdoc}
137 2
     */
138 2
    protected function doDeleteMultiple(array $keys)
139 2
    {
140
        return $this->client->del($keys) >= 0;
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146
    protected function doFlush()
147
    {
148
        $response = $this->client->flushdb();
149
150
        return $response === true || $response == 'OK';
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    protected function doGetStats()
157
    {
158
        $info = $this->client->info();
159
160
        return [
161
            Cache::STATS_HITS              => $info['Stats']['keyspace_hits'],
162
            Cache::STATS_MISSES            => $info['Stats']['keyspace_misses'],
163
            Cache::STATS_UPTIME            => $info['Server']['uptime_in_seconds'],
164
            Cache::STATS_MEMORY_USAGE      => $info['Memory']['used_memory'],
165
            Cache::STATS_MEMORY_AVAILABLE  => false,
166
        ];
167
    }
168
}
169