Passed
Push — master ( 5a87d9...5af04f )
by Mihail
03:04
created

MemcachedConfiguration   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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