Passed
Branch master (dc39ff)
by Liam
03:01
created

AbstractStorage   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 33
c 1
b 0
f 0
dl 0
loc 130
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A reportFailure() 0 26 3
A getStorage() 0 3 1
A setStorage() 0 3 1
A __construct() 0 6 1
A isOpen() 0 9 2
1
<?php
2
3
/**
4
 * Base abstract adapter implementation for php-hystrix.
5
 *
6
 * PHP version 7.2
7
 *
8
 * @category Adapter
9
 * @package  Storage
10
 * @author   Liam Sorsby <[email protected]>
11
 * @license  https://www.apache.org/licenses/LICENSE-2.0 Apache
12
 * @link     https://github.org/liamsorsby/php-hystrix
13
 *
14
 * For the full copyright and license information, please view the LICENSE file.
15
 */
16
17
namespace liamsorsby\Hystrix\Storage\Adapter;
18
19
use liamsorsby\Hystrix\Storage\StorageInterface;
20
use Cache\Adapter\Common\AbstractCachePool;
21
use Psr\SimpleCache\InvalidArgumentException;
22
23
/**
24
 * Class AbstractStorage
25
 *
26
 * @category Adapter
27
 * @package  Storage
28
 * @author   Liam Sorsby <[email protected]>
29
 * @license  https://www.apache.org/licenses/LICENSE-2.0 Apache
30
 * @link     https://github.org/liamsorsby/php-hystrix
31
 */
32
abstract class AbstractStorage implements StorageInterface
33
{
34
    /**
35
     * Current storage in use.
36
     *
37
     * @var mixed
38
     */
39
    protected $storage;
40
41
    /**
42
     * Failure Prefix
43
     *
44
     * @var string
45
     */
46
    protected $failurePrefix;
47
48
    /**
49
     * Open Prefix
50
     *
51
     * @var string
52
     */
53
    protected $openPrefix;
54
55
    /**
56
     * Circuit Breaker Threshold
57
     *
58
     * @var int
59
     */
60
    protected $threshold;
61
62
    /**
63
     * Circuit Breaker Duration
64
     *
65
     * @var int
66
     */
67
    protected $duration;
68
69
    /**
70
     * AbstractStorage constructor.
71
     *
72
     * @param string $prefix    String to prefix fail count to prevent collision
73
     * @param int    $threshold Max number of failures in given time
74
     * @param int    $duration  Duration for threshold to be appended to
75
     */
76
    public function __construct(string $prefix, int $threshold, int $duration)
77
    {
78
        $this->failurePrefix = $prefix . 'failcount';
79
        $this->openPrefix = $prefix . 'open';
80
        $this->duration = $duration;
81
        $this->threshold = $threshold;
82
    }
83
84
    /**
85
     * Abstract function for returning the storage instance
86
     *
87
     * @param AbstractCachePool $storage Storage name to set the storage too.
88
     *
89
     * @return void
90
     */
91
    public function setStorage(AbstractCachePool $storage): void
92
    {
93
        $this->storage = $storage;
94
    }
95
96
    /**
97
     * Abstract function for returning the storage instance
98
     *
99
     * @return AbstractCachePool
100
     */
101
    public function getStorage(): AbstractCachePool
102
    {
103
        return $this->storage;
104
    }
105
    /**
106
     * Report a failed state to storage
107
     *
108
     * @param string $service Name of the lock
109
     * @param string $value   String to set the lock too
110
     *
111
     * @return void
112
     */
113
    public function reportFailure(string $service, string $value): void
114
    {
115
        $currentCount = $this->getStorage()->get(
116
            $this->failurePrefix . $service
117
        );
118
119
        $newTotal = ((int)$currentCount)+1;
120
121
        if (!(bool) $currentCount) {
122
            $this->getStorage()->set(
123
                $this->failurePrefix . $service,
124
                1,
125
                $this->duration
126
            );
127
        } else {
128
            $this->getStorage()->set(
129
                $this->failurePrefix . $service,
130
                $newTotal
131
            );
132
        }
133
134
        if ($newTotal >= $this->threshold) {
135
            $this->getStorage()->set(
136
                $this->openPrefix . $service,
137
                1,
138
                $this->duration
139
            );
140
        }
141
    }
142
143
144
    /**
145
     * Check if circuit breaker is open
146
     *
147
     * @param string $service Name of service being checked
148
     *
149
     * @throws InvalidArgumentException
150
     *
151
     * @return bool
152
     */
153
    public function isOpen(string $service): bool
154
    {
155
        try {
156
            return (bool) $this->getStorage()->get(
157
                $this->openPrefix.$service,
158
                false
159
            );
160
        } catch (\Exception $e) {
161
            return false;
162
        }
163
    }
164
}
165