]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/RedisCacheDriver.php
Improve doc blocks in cache drivers
[friendica.git] / src / Core / Cache / RedisCacheDriver.php
1 <?php
2
3 namespace Friendica\Core\Cache;
4
5 use Friendica\Core\Cache;
6
7 use Exception;
8 use Redis;
9
10 /**
11  * Redis Cache Driver. This driver is based on Memcache driver
12  *
13  * @author Hypolite Petovan <hypolite@mrpetovan.com>
14  * @author Roland Haeder <roland@mxchange.org>
15  */
16 class RedisCacheDriver extends AbstractCacheDriver implements IMemoryCacheDriver
17 {
18         /**
19          * @var Redis
20          */
21         private $redis;
22
23         /**
24          * @param string $redis_host
25          * @param int    $redis_port
26          * @throws Exception
27          */
28         public function __construct($redis_host, $redis_port)
29         {
30                 if (!class_exists('Redis', false)) {
31                         throw new Exception('Redis class isn\'t available');
32                 }
33
34                 $this->redis = new Redis();
35
36                 if (!$this->redis->connect($redis_host, $redis_port)) {
37                         throw new Exception('Expected Redis server at ' . $redis_host . ':' . $redis_port . ' isn\'t available');
38                 }
39         }
40
41         /**
42          * (@inheritdoc)
43          */
44         public function get($key)
45         {
46                 $return = null;
47                 $cachekey = $this->getCacheKey($key);
48
49                 $cached = $this->redis->get($cachekey);
50                 if ($cached === false && !$this->redis->exists($cachekey)) {
51                         return null;
52                 }
53
54                 $value = unserialize($cached);
55
56                 // Only return a value if the serialized value is valid.
57                 // We also check if the db entry is a serialized
58                 // boolean 'false' value (which we want to return).
59                 if ($cached === serialize(false) || $value !== false) {
60                         $return = $value;
61                 }
62
63                 return $return;
64         }
65
66         /**
67          * (@inheritdoc)
68          */
69         public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
70         {
71                 $cachekey = $this->getCacheKey($key);
72
73                 $cached = serialize($value);
74
75                 if ($ttl > 0) {
76                         return $this->redis->setex(
77                                 $cachekey,
78                                 $ttl,
79                                 $cached
80                         );
81                 } else {
82                         return $this->redis->set(
83                                 $cachekey,
84                                 $cached
85                         );
86                 }
87         }
88
89         /**
90          * (@inheritdoc)
91          */
92         public function delete($key)
93         {
94                 $cachekey = $this->getCacheKey($key);
95                 return ($this->redis->delete($cachekey) > 0);
96         }
97
98         /**
99          * (@inheritdoc)
100          */
101         public function clear($outdated = true)
102         {
103                 if ($outdated) {
104                         return true;
105                 } else {
106                         return $this->redis->flushAll();
107                 }
108         }
109
110         /**
111          * (@inheritdoc)
112          */
113         public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
114         {
115                 $cachekey = $this->getCacheKey($key);
116                 $cached = serialize($value);
117
118                 return $this->redis->setnx($cachekey, $cached);
119         }
120
121         /**
122          * (@inheritdoc)
123          */
124         public function compareSet($key, $oldValue, $newValue, $ttl = Cache::FIVE_MINUTES)
125         {
126                 $cachekey = $this->getCacheKey($key);
127
128                 $newCached = serialize($newValue);
129
130                 $this->redis->watch($cachekey);
131                 // If the old value isn't what we expected, somebody else changed the key meanwhile
132                 if ($this->get($key) === $oldValue) {
133                         if ($ttl > 0) {
134                                 $result = $this->redis->multi()
135                                         ->setex($cachekey, $ttl, $newCached)
136                                         ->exec();
137                         } else {
138                                 $result = $this->redis->multi()
139                                         ->set($cachekey, $newValue)
140                                         ->exec();
141                         }
142                         return $result !== false;
143                 }
144                 $this->redis->unwatch();
145                 return false;
146         }
147
148         /**
149          * (@inheritdoc)
150          */
151         public function compareDelete($key, $value)
152         {
153                 $cachekey = $this->getCacheKey($key);
154
155                 $this->redis->watch($cachekey);
156                 // If the old value isn't what we expected, somebody else changed the key meanwhile
157                 if ($this->get($key) === $value) {
158                         $result = $this->redis->multi()
159                                 ->del($cachekey)
160                                 ->exec();
161                         return $result !== false;
162                 }
163                 $this->redis->unwatch();
164                 return false;
165         }
166 }