GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

CircuitBreaker   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 6
dl 0
loc 178
ccs 56
cts 56
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getLastTest() 0 4 1
A __construct() 0 7 2
A getCacheKey() 0 4 1
A getService() 0 7 2
A getFailures() 0 4 1
A setFailures() 0 5 1
A trackService() 0 7 2
B isAvailable() 0 26 4
A reportFailure() 0 9 2
A reportSuccess() 0 17 4
1
<?php
2
3
namespace Cmp\CircuitBreaker;
4
5
use Cmp\CircuitBreaker\Exception\ServiceAlreadyTrackedException;
6
use Cmp\CircuitBreaker\Exception\ServiceNotTrackedException;
7
use Psr\Log\NullLogger;
8
use Psr\SimpleCache\CacheInterface;
9
use Psr\Log\LoggerInterface;
10
11
/**
12
 * Class CircuitBreaker
13
 *
14
 * @package Cmp\CircuitBreaker
15
 */
16
class CircuitBreaker
17
{
18
    /**
19
     * @var CacheInterface
20
     */
21
    protected $cache;
22
23
    /**
24
     * @var LoggerInterface
25
     */
26
    protected $logger;
27
28
    /**
29
     * @var Service[]
30
     */
31
    protected $services    = [];
32
33
    /**
34
     * @var string
35
     */
36
    protected $cachePrefix = 'cb';
37
38
    /**
39
     * @var int
40
     */
41
    protected $ttl         = 3360;
42
43
    /**
44
     * CircuitBreaker constructor.
45
     *
46
     * @param CacheInterface       $cache       Cache to store the failures and times
47
     * @param LoggerInterface|null $logger      To log stuff
48
     */
49 1
    public function __construct(
50
        CacheInterface $cache,
51
        LoggerInterface $logger
52
    ) {
53 1
        $this->cache       = $cache;
54 1
        $this->logger      = $logger instanceof LoggerInterface ? $logger : new NullLogger();
55 1
    }
56
57
    /**
58
     * @param string $serviceName Name of the service
59
     * @param string $field       Field you want to fetch
60
     *
61
     * @return string
62
     */
63 1
    protected function getCacheKey($serviceName, $field)
64
    {
65 1
        return $this->cachePrefix.'-'.$serviceName.'-'.$field;
66
    }
67
68
    /**
69
     * @param $serviceName
70
     * @return Service|null
71
     */
72 1
    protected function getService($serviceName)
73
    {
74 1
        if (array_key_exists($serviceName, $this->services)) {
75 1
            return $this->services[$serviceName];
76
        }
77 1
        return null;
78
    }
79
80
    /**
81
     * @param string $serviceName Name of the service
82
     *
83
     * @return int
84
     */
85 1
    protected function getFailures($serviceName)
86
    {
87 1
        return (int) $this->cache->get($this->getCacheKey($serviceName, 'failures'));
88
    }
89
90
    /**
91
     * @param string $serviceName Name of the service
92
     *
93
     * @return int
94
     */
95 1
    protected function getLastTest($serviceName)
96
    {
97 1
        return (int) $this->cache->get($this->getCacheKey($serviceName, 'lastTest'));
98
    }
99
100
    /**
101
     * @param string $serviceName Name of the service
102
     * @param int    $newValue    New value to store
103
     */
104 1
    protected function setFailures($serviceName, $newValue)
105
    {
106 1
        $this->cache->set($this->getCacheKey($serviceName, 'failures'), $newValue, $this->ttl);
107 1
        $this->cache->set($this->getCacheKey($serviceName, 'lastTest'), time(), $this->ttl);
108 1
    }
109
110
    /**
111
     * @param Service $service Service to track
112
     *
113
     * @throws ServiceAlreadyTrackedException
114
     */
115 1
    public function trackService(Service $service)
116
    {
117 1
        if ($this->getService($service->getName()) !== null) {
118 1
            throw new ServiceAlreadyTrackedException($service->getName());
119
        }
120 1
        $this->services[$service->getName()] = $service;
121 1
    }
122
123
    /**
124
     * @param string $serviceName Name of the service
125
     *
126
     * @return bool
127
     * @throws ServiceNotTrackedException
128
     */
129 1
    public function isAvailable($serviceName)
130
    {
131 1
        $service = $this->getService($serviceName);
132 1
        if ($service == null) {
133 1
            throw new ServiceNotTrackedException($serviceName);
134
        }
135
136 1
        $failures    = $this->getFailures($serviceName);
137 1
        $maxFailures = $service->getMaxFailures();
138
139 1
        if ($failures < $maxFailures) {
140 1
            return true;
141
        }
142
143 1
        $lastTest     = $this->getLastTest($serviceName);
144 1
        $retryTimeout = $service->getRetryTimeout();
145
146 1
        if (($lastTest + $retryTimeout) < time()) {
147 1
            $this->setFailures($serviceName, $failures);
148 1
            $this->logger->info('Attempting service '.$serviceName.' one more time');
149
150 1
            return true;
151
        }
152
153 1
        return false;
154
    }
155
156
    /**
157
     * @param string $serviceName Name of the service
158
     *
159
     * @throws ServiceNotTrackedException
160
     */
161 1
    public function reportFailure($serviceName)
162
    {
163 1
        if ($this->getService($serviceName) == null) {
164 1
            throw new ServiceNotTrackedException($serviceName);
165
        }
166
167 1
        $this->setFailures($serviceName, $this->getFailures($serviceName) + 1);
168 1
        $this->logger->warning('Service '.$serviceName.' is shaky');
169 1
    }
170
171
    /**
172
     * @param string $serviceName Name of the service
173
     *
174
     * @throws ServiceNotTrackedException
175
     */
176 1
    public function reportSuccess($serviceName)
177
    {
178 1
        $service = $this->getService($serviceName);
179 1
        if ($service == null) {
180 1
            throw new ServiceNotTrackedException($serviceName);
181
        }
182
183 1
        $failures    = $this->getFailures($serviceName);
184 1
        $maxFailures = $service->getMaxFailures();
185
186 1
        if ($failures > $maxFailures) {
187 1
            $this->setFailures($serviceName, $maxFailures - 1);
188 1
            $this->logger->alert('Service '.$serviceName.' is down');
189 1
        } elseif ($failures > 0) {
190 1
            $this->setFailures($serviceName, $failures - 1);
191
        }
192 1
    }
193
}
194