MemcachedConfiguration   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
c 1
b 0
f 0
dl 0
loc 93
ccs 28
cts 28
cp 1
rs 10
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 20 2
A getTtl() 0 6 2
A getServers() 0 10 3
A getOptions() 0 3 1
1
<?php
2
/*
3
 * This file is part of the Koded package.
4
 *
5
 * (c) Mihail Binev <[email protected]>
6
 *
7
 * Please view the LICENSE distributed with this source code
8
 * for the full copyright and license information.
9
 */
10
11
namespace Koded\Caching\Configuration;
12
13
use Koded\Caching\CacheException;
14
use Memcached;
15
use function array_filter;
16
use function array_replace;
17
use function class_exists;
18
use function getenv;
19
use function json_decode;
20
21
/**
22
 * Class MemcachedConfiguration
23
 *
24
 * @see https://github.com/kodedphp/stdlib/blob/master/Interfaces.php#L158
25
 */
26
final class MemcachedConfiguration extends CacheConfiguration
27
{
28
    /**
29
     * MemcachedConfiguration constructor.
30
     *
31
     * @param array $options [optional] Memcached options. Used here:
32
     *
33
     * OPT_DISTRIBUTION          - consistent, if one node goes down it's keys are distributed to other nodes
34
     * OPT_CONNECT_TIMEOUT       - milliseconds after server is considered dead
35
     * OPT_SERVER_FAILURE_LIMIT  - number of connection failures before server is marked as dead and removed
36
     * OPT_REMOVE_FAILED_SERVERS - (bool) to remove dead server or not
37
     * OPT_RETRY_TIMEOUT         - try a dead server after this seconds (tweak for long running processes)
38
     *
39
     * @link http://php.net/manual/en/memcached.constants.php
40
     */
41 74
    public function __construct(array $options = [])
42
    {
43
        // @codeCoverageIgnoreStart
44
        if (false === class_exists('\Memcached', false)) {
45
            throw CacheException::generic('Memcached extension is not loaded on this machine.');
46
        }
47
        // @codeCoverageIgnoreEnd
48
49 74
        parent::__construct([
50 74
            'id' => $options['id'] ?? null,
51 74
            'servers' => $options['servers'] ?? [],
52 74
            'options' => array_replace([
53 74
                Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT,
54 74
                Memcached::OPT_CONNECT_TIMEOUT => 10,
55 74
                Memcached::OPT_SERVER_FAILURE_LIMIT => 2,
56 74
                Memcached::OPT_REMOVE_FAILED_SERVERS => true,
57 74
                Memcached::OPT_RETRY_TIMEOUT => 1,
58 74
                Memcached::OPT_PREFIX_KEY => null
59 74
            ], $options['options'] ?? []),
60 74
            'ttl' => $options['ttl'] ?? null
61 74
        ]);
62
    }
63
64
    /**
65
     * Order of precedence when selecting the servers array
66
     *
67
     *  1. "servers" directive that holds an array of memcached servers
68
     *  2. environment variable "MEMCACHED_POOL" serialized as JSON [['ip', port],...]
69
     *  3. defaults to one server at localhost:11211
70
     *
71
     * @return array Memcached options.
72
     * The "MEMCACHED_POOL" is ignored if "servers" is provided in the configuration directives.
73
     *
74
     * @link http://php.net/manual/en/memcached.addservers.php
75
     */
76 73
    public function getServers(): array
77
    {
78 73
        if ($servers = $this->get('servers')) {
79 1
            return $servers;
80
        }
81 72
        if ($servers = json_decode(getenv('MEMCACHED_POOL'), true)) {
82 71
            return $servers;
83
        }
84 1
        return [
85 1
            ['127.0.0.1', 11211]
86 1
        ];
87
    }
88
89
    /**
90
     * To add Memcached options
91
     *
92
     *  - use the class constructor options argument
93
     *  - use the Config factory methods (if applicable)
94
     *  - use the class methods
95
     *
96
     * To remove options
97
     *
98
     *  - set the option(s) with NULL value
99
     *  - use the class methods
100
     *
101
     * @return array Filtered Memcached options
102
     */
103 72
    public function getOptions(): array
104
    {
105 72
        return array_filter($this->toArray()['options'], fn($value) => null !== $value);
106
    }
107
108
    /**
109
     * Returns the global TTL in seconds, or NULL for never-expire value.
110
     *
111
     * @return int|null
112
     */
113 71
    public function getTtl(): ?int
114
    {
115 71
        if (null === $ttl = $this->get('ttl')) {
116 70
            return null;
117
        }
118 2
        return (int)$ttl;
119
    }
120
}
121