Couchbase::loadLastFailureTime()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * Couchbase Adapter for ackintosh/ganesha
4
 */
5
namespace GaneshaPlugin\Adapter;
6
7
use RuntimeException;
8
9
use Ackintosh\Ganesha;
10
use Ackintosh\Ganesha\Exception\StorageException;
11
use Ackintosh\Ganesha\Configuration;
12
use Ackintosh\Ganesha\Storage\AdapterInterface;
13
use Ackintosh\Ganesha\Storage\Adapter\TumblingTimeWindowInterface;
14
use Couchbase\Bucket;
15
use Couchbase\Exception as CBException;
16
17
/**
18
 * Adapter class using Couchbase
19
 *
20
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
21
 */
22
class Couchbase implements AdapterInterface, TumblingTimeWindowInterface
23
{
24
    /**
25
     * @var \Couchbase\Bucket $bucket Couchbase bucket to manage data
26
     */
27
    private $bucket;
28
29
    /**
30
     * @var \Ackintosh\Ganesha\Configuration $configuration circuit breaker configuration
31
     */
32
    private $configuration;
33
34
    /**
35
     * constructor
36
     *
37
     * @param \Couchbase\Bucket $bucket Couchbase bucket to manage data
38
     */
39 1
    public function __construct(Bucket $bucket)
40
    {
41 1
        $this->bucket = $bucket;
42
    }
43
44
    /**
45
     * return wwhether the adapter supports counting strategy
46
     *
47
     * @return bool
48
     */
49 1
    public function supportCountStrategy()
50
    {
51 1
        return true;
52
    }
53
54
    /**
55
     * return whether the adapter supports rating strategy
56
     *
57
     * @return bool
58
     */
59 1
    public function supportRateStrategy()
60
    {
61 1
        return true;
62
    }
63
64
    /**
65
     * set circuit breaker configuration
66
     *
67
     * @param \Ackintosh\Ganesha\Configuration $configuration circuit breaker configuration
68
     * @return void
69
     */
70 1
    public function setConfiguration(Configuration $configuration)
71
    {
72 1
        $this->configuration = $configuration;
73
    }
74
75
    /**
76
     * load success / failure / rejection count
77
     *
78
     * @param  string $service name of the service
79
     * @return int
80
     * @throws \Ackintosh\Ganesha\Exception\StorageException
81
     */
82 3
    public function load($service)
83
    {
84 3
        return $this->get($service, 0);
85
    }
86
87
    /**
88
     * save success / failure / rejection count
89
     *
90
     * @param  string $service name of the service
91
     * @param  int    $count   success / failure / rejection count of the service
92
     * @return void
93
     * @throws \Ackintosh\Ganesha\Exception\StorageException
94
     */
95 2
    public function save($service, $count)
96
    {
97 2
        $this->upsert($service, $count);
98
    }
99
100
    /**
101
     * increment success / failure / rejection count
102
     *
103
     * @param  string $service name of the service
104
     * @return void
105
     * @throws \Ackintosh\Ganesha\Exception\StorageException
106
     */
107 2
    public function increment($service)
108
    {
109 2
        $this->counter($service, 1);
110
    }
111
112
    /**
113
     * decrement failure count
114
     *
115
     * If the operation would decrease the value below 0, the new value must be 0.
116
     *
117
     * @param  string $service name of the service
118
     * @return void
119
     * @throws \Ackintosh\Ganesha\Exception\StorageException
120
     */
121 2
    public function decrement($service)
122
    {
123 2
        $this->counter($service, -1);
124
    }
125
126
    /**
127
     * sets last failure time
128
     *
129
     * @param  string $service         name of the service
130
     * @param  int    $lastFailureTime last failure time (unix time)
131
     * @return void
132
     * @throws \Ackintosh\Ganesha\Exception\StorageException
133
     */
134 2
    public function saveLastFailureTime($service, $lastFailureTime)
135
    {
136 2
        $this->upsert($service, $lastFailureTime);
137
    }
138
139
    /**
140
     * returns last failure time
141
     *
142
     * @param string $service name of the service
143
     * @return int | null
144
     * @throws \Ackintosh\Ganesha\Exception\StorageException
145
     */
146 3
    public function loadLastFailureTime($service)
147
    {
148 3
        return $this->get($service, null);
149
    }
150
151
    /**
152
     * sets status
153
     *
154
     * @param  string $service name of the service
155
     * @param  int    $status  status of the service
156
     * @return void
157
     * @throws \Ackintosh\Ganesha\Exception\StorageException
158
     */
159 2
    public function saveStatus($service, $status)
160
    {
161 2
        $this->upsert($service, $status);
162
    }
163
164
    /**
165
     * returns status
166
     *
167
     * @param  string $service name of the service
168
     * @return int
169
     * @throws \Ackintosh\Ganesha\Exception\StorageException
170
     */
171 3
    public function loadStatus($service)
172
    {
173 3
        return $this->get($service, Ganesha::STATUS_CALMED_DOWN);
174
    }
175
176
    /**
177
     * resets all counts
178
     *
179
     * @return void
180
     * @throws \Ackintosh\Ganesha\Exception\StorageException
181
     */
182 1
    public function reset()
183
    {
184 1
        throw new RuntimeException('not implemented');
185
    }
186
187
    /**
188
     * return option parameters for Couchbase operation
189
     *
190
     * @param array $additional additional option
191
     * @return array
192
     */
193 10
    private function getOptions(array $additional = [])
194
    {
195 10
        $expiry = isset($this->configuration['timeWindow']) ?
196 10
                $this->configuration['timeWindow'] * 2 : // current + previous
197 10
                0;
198
        $initial = [
199 10
            'expiry' => $expiry,
200
        ];
201 10
        return array_merge($initial, $additional);
202
    }
203
204
    /**
205
     * get data from couchbase bucket
206
     *
207
     * @param string $key     key of the document
208
     * @param mixed  $default default value for missing document
209
     * @return mixed
210
     * @throws \Ackintosh\Ganesha\Exception\StorageException
211
     */
212 11
    private function get($key, $default)
213
    {
214
        try {
215 11
            $doc = $this->bucket->get($key, []);
216 6
        } catch (CBException $e) {
217 6
            if ($e->getCode() === COUCHBASE_KEY_ENOENT) {
218 3
                return $default;
219
            }
220 3
            throw new StorageException($e->getMessage(), $e->getCode(), $e);
221
        }
222 5
        return $doc->value;
223
    }
224
225
    /**
226
     * update or insert value for given key
227
     *
228
     * @param string $key   id of the document
229
     * @param mixed  $value value of the document
230
     * @return void
231
     * @throws \Ackintosh\Ganesha\Exception\StorageException
232
     */
233 7
    private function upsert($key, $value)
234
    {
235
        try {
236 7
            $this->bucket->upsert($key, $value, $this->getOptions());
237 3
        } catch (CBException $e) {
238 3
            throw new StorageException($e->getMessage(), $e->getCode(), $e);
239
        }
240
    }
241
242
    /**
243
     * increment / decrement counter for given key
244
     *
245
     * @param string $key   key of the counter
246
     * @param int    $delta increment / decrement delta
247
     * @return void
248
     * @throws \Ackintosh\Ganesha\Exception\StorageException
249
     */
250 4
    private function counter($key, $delta)
251
    {
252
        try {
253 4
            $this->bucket->counter($key, $delta, $this->getOptions(['initial' => 0]));
254 2
        } catch (\Couchbase\Exception $e) {
255 2
            throw new StorageException($e->getMessage(), $e->getCode(), $e);
256
        }
257
    }
258
}
259