]> git.mxchange.org Git - friendica.git/blob - src/Core/Cache/MemcachedCache.php
Merge pull request #7754 from annando/aria
[friendica.git] / src / Core / Cache / MemcachedCache.php
1 <?php
2
3 namespace Friendica\Core\Cache;
4
5 use Exception;
6 use Friendica\Core\Config\Configuration;
7 use Memcached;
8 use Psr\Log\LoggerInterface;
9
10 /**
11  * Memcached Cache
12  *
13  * @author Hypolite Petovan <hypolite@mrpetovan.com>
14  */
15 class MemcachedCache extends Cache implements IMemoryCache
16 {
17         use TraitCompareSet;
18         use TraitCompareDelete;
19         use TraitMemcacheCommand;
20
21         /**
22          * @var \Memcached
23          */
24         private $memcached;
25
26         /**
27          * @var LoggerInterface
28          */
29         private $logger;
30
31         /**
32          * Due to limitations of the INI format, the expected configuration for Memcached servers is the following:
33          * array {
34          *   0 => "hostname, port(, weight)",
35          *   1 => ...
36          * }
37          *
38          * @param array $memcached_hosts
39          *
40          * @throws \Exception
41          */
42         public function __construct(string $hostname, Configuration $config, LoggerInterface $logger)
43         {
44                 if (!class_exists('Memcached', false)) {
45                         throw new Exception('Memcached class isn\'t available');
46                 }
47
48                 parent::__construct($hostname);
49
50                 $this->logger = $logger;
51
52                 $this->memcached = new Memcached();
53
54                 $memcached_hosts = $config->get('system', 'memcached_hosts');
55
56                 array_walk($memcached_hosts, function (&$value) {
57                         if (is_string($value)) {
58                                 $value = array_map('trim', explode(',', $value));
59                         }
60                 });
61
62                 $this->server = $memcached_hosts[0][0] ?? 'localhost';
63                 $this->port = $memcached_hosts[0][1] ?? 11211;
64
65                 $this->memcached->addServers($memcached_hosts);
66
67                 if (count($this->memcached->getServerList()) == 0) {
68                         throw new Exception('Expected Memcached servers aren\'t available, config:' . var_export($memcached_hosts, true));
69                 }
70         }
71
72         /**
73          * (@inheritdoc)
74          */
75         public function getAllKeys($prefix = null)
76         {
77                 $keys = $this->getOriginalKeys($this->getMemcacheKeys());
78
79                 return $this->filterArrayKeysByPrefix($keys, $prefix);
80         }
81
82         /**
83          * (@inheritdoc)
84          */
85         public function get($key)
86         {
87                 $return   = null;
88                 $cachekey = $this->getCacheKey($key);
89
90                 // We fetch with the hostname as key to avoid problems with other applications
91                 $value = $this->memcached->get($cachekey);
92
93                 if ($this->memcached->getResultCode() === Memcached::RES_SUCCESS) {
94                         $return = $value;
95                 } else {
96                         $this->logger->debug('Memcached \'get\' failed', ['result' => $this->memcached->getResultMessage()]);
97                 }
98
99                 return $return;
100         }
101
102         /**
103          * (@inheritdoc)
104          */
105         public function set($key, $value, $ttl = Cache::FIVE_MINUTES)
106         {
107                 $cachekey = $this->getCacheKey($key);
108
109                 // We store with the hostname as key to avoid problems with other applications
110                 if ($ttl > 0) {
111                         return $this->memcached->set(
112                                 $cachekey,
113                                 $value,
114                                 $ttl
115                         );
116                 } else {
117                         return $this->memcached->set(
118                                 $cachekey,
119                                 $value
120                         );
121                 }
122         }
123
124         /**
125          * (@inheritdoc)
126          */
127         public function delete($key)
128         {
129                 $cachekey = $this->getCacheKey($key);
130                 return $this->memcached->delete($cachekey);
131         }
132
133         /**
134          * (@inheritdoc)
135          */
136         public function clear($outdated = true)
137         {
138                 if ($outdated) {
139                         return true;
140                 } else {
141                         return $this->memcached->flush();
142                 }
143         }
144
145         /**
146          * (@inheritdoc)
147          */
148         public function add($key, $value, $ttl = Cache::FIVE_MINUTES)
149         {
150                 $cachekey = $this->getCacheKey($key);
151                 return $this->memcached->add($cachekey, $value, $ttl);
152         }
153
154         /**
155          * {@inheritDoc}
156          */
157         public function getName()
158         {
159                 return self::TYPE_MEMCACHED;
160         }
161 }