Completed
Push — 2.0 ( aed067...b26523 )
by Marco
04:31
created

StackManager::remove()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 7

Duplication

Lines 17
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 4.0312

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 17
loc 17
ccs 7
cts 8
cp 0.875
rs 9.2
cc 4
eloc 7
nc 3
nop 1
crap 4.0312
1
<?php namespace Comodojo\Cache\Components;
2
3
use \Comodojo\Cache\Providers\ProviderInterface;
4
use \Psr\Log\LoggerInterface;
5
use \Exception;
6
7
/**
8
 *
9
 * @package     Comodojo Spare Parts
10
 * @author      Marco Giovinazzi <[email protected]>
11
 * @license     MIT
12
 *
13
 * LICENSE:
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 * THE SOFTWARE.
22
 */
23
24
class StackManager {
25
26
    private $stack = array();
27
28
    private $weights = array();
29
30
    private $failures = array();
31
32
    private $flap_interval = 600;
33
34
    public function __construct($flap_interval) {
35
36
        $this->flap_interval = $flap_interval;
37
38
    }
39
40
    public function getFlapInterval() {
41
42
        return $this->flap_interval;
43
44
    }
45
46
    public function setFlapInterval($ttl) {
47
48
        $this->flap_interval = $ttl;
49
50
        return $this;
51
52
    }
53
54 1
    public function add(ProviderInterface $provider, $weight = 0) {
55
56 1
        $id = $provider->getCacheId();
57
58 1
        if ( array_key_exists($id, $this->stack) ) throw new CacheException("Provider $id already registered");
59
60 1
        $this->stack[$id] = $provider;
61
62 1
        $this->weights[$id] = $weight;
63
64 1
        return $id;
65
66
    }
67
68 1 View Code Duplication
    public function remove($id) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69
70 1
        if ( array_key_exists($id, $this->stack) && array_key_exists($id, $this->weights) ) {
71
72 1
            unset($this->stack[$id]);
73
74 1
            unset($this->weights[$id]);
75
76 1
            if ( array_key_exists($id, $this->failures) ) unset($this->failures[$id]);
77
78 1
        } else {
79
80
            throw new CacheException("Provider not registered");
81
82
        }
83
84 1
    }
85
86
    public function get($id) {
87
88
        if ( array_key_exists($id, $this->stack) && array_key_exists($id, $this->weights) ) {
89
90
            return $this->stack[$id];
91
92
        }
93
94
        throw new CacheException("Provider not registered");
95
96
    }
97
98
    public function disable($id) {
99
100
        if ( array_key_exists($id, $this->stack) && array_key_exists($id, $this->weights) ) {
101
102
            $this->stack[$id]->disable();
103
104
            $this->failures[$id] = time();
105
106
        } else {
107
108
            throw new CacheException("Provider not registered");
109
110
        }
111
112
    }
113
114 View Code Duplication
    public function enable($id) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
116
        if ( array_key_exists($id, $this->stack) && array_key_exists($id, $this->weights) ) {
117
118
            $this->stack[$id]->enable();
119
120
            if ( array_key_exists($id, $this->failures) ) unset($this->failures[$id]);
121
122
        } else {
123
124
            throw new CacheException("Provider not registered");
125
126
        }
127
128
    }
129
130 53
    public function getAll($enabled=true) {
131
132 53
        return $enabled ? $this->getEnabled() : $this->stack;
133
134
    }
135
136 7
    public function getRandom() {
137
138 7
        return $this->stack[array_rand($this->getEnabled())];
139
140
    }
141
142 7 View Code Duplication
    public function getFirst() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143
144 7
        $providers = $this->getEnabled();
145
146 7
        if ( empty($providers) ) return null;
147
148 7
        reset($providers);
149
150 7
        return current($providers);
151
152
    }
153
154 7 View Code Duplication
    public function getLast() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
156 7
        $providers = $this->getEnabled();
157
158 7
        if ( empty($providers) ) return null;
159
160 7
        reset($providers);
161
162 7
        return end($providers);
163
164
    }
165
166 7
    public function getByWeight() {
167
168 7
        $providers = $this->getEnabled();
169
170 7
        $weights = array_intersect_key($this->weights, $providers);
171
172 7
        asort($weights);
173
174 7
        end($weights);
175
176 7
        return $providers[key($weights)];
177
178
    }
179
180 47
    private function checkCacheFlap($cache_id, $cache) {
181
182 47
        if ( $cache->isEnabled() === false && array_key_exists($cache_id, $this->failures) ) {
183
184
            if ( $this->failures[$cache_id] < time() + $this->flap_interval ) {
185
                $cache->enable();
186
                unset($this->failures[$cache_id]);
187
            }
188
189
        }
190
191 47
    }
192
193 47
    private function getEnabled() {
194
195 47
        $return = array();
196
197 47
        foreach ($this->stack as $id => $cache) {
198 47
            $this->checkCacheFlap($id, $cache);
199 47
            if ( $cache->isEnabled() ) $return[$id] = $cache;
200 47
        }
201
202 47
        return $return;
203
204
    }
205
206
}
207