-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Count.php
106 lines (88 loc) · 2.86 KB
/
Count.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
namespace Ackintosh\Ganesha\Strategy;
use Ackintosh\Ganesha;
use Ackintosh\Ganesha\Configuration;
use Ackintosh\Ganesha\Exception\StorageException;
use Ackintosh\Ganesha\Storage;
use Ackintosh\Ganesha\StrategyInterface;
class Count implements StrategyInterface
{
/**
* @var Configuration
*/
private $configuration;
/**
* @var Storage
*/
private $storage;
private function __construct(Configuration $configuration, Storage $storage)
{
$this->configuration = $configuration;
$this->storage = $storage;
}
public static function create(Storage\AdapterInterface $adapter, Configuration $configuration): StrategyInterface
{
return new self(
$configuration,
new Storage(
$adapter,
$configuration->storageKeys(),
null
)
);
}
public function recordFailure(string $service): int
{
$this->storage->setLastFailureTime($service, time());
$this->storage->incrementFailureCount($service);
if ($this->storage->getFailureCount($service) >= $this->configuration->failureCountThreshold()
&& $this->storage->getStatus($service) === Ganesha::STATUS_CALMED_DOWN
) {
$this->storage->setStatus($service, Ganesha::STATUS_TRIPPED);
return Ganesha::STATUS_TRIPPED;
}
return Ganesha::STATUS_CALMED_DOWN;
}
public function recordSuccess(string $service): ?int
{
$this->storage->decrementFailureCount($service);
$status = $this->storage->getStatus($service);
if ($this->storage->getFailureCount($service) === 0
&& $status === Ganesha::STATUS_TRIPPED
) {
$this->storage->setStatus($service, Ganesha::STATUS_CALMED_DOWN);
return Ganesha::STATUS_CALMED_DOWN;
}
return null;
}
public function reset(): void
{
$this->storage->reset();
}
public function isAvailable(string $service): bool
{
return $this->isClosed($service) || $this->isHalfOpen($service);
}
/**
* @throws StorageException
*/
private function isClosed(string $service): bool
{
return $this->storage->getFailureCount($service) < $this->configuration->failureCountThreshold();
}
/**
* @throws StorageException
*/
private function isHalfOpen(string $service): bool
{
if (is_null($lastFailureTime = $this->storage->getLastFailureTime($service))) {
return false;
}
if ((time() - $lastFailureTime) > $this->configuration->intervalToHalfOpen()) {
$this->storage->setFailureCount($service, $this->configuration->failureCountThreshold());
$this->storage->setLastFailureTime($service, time());
return true;
}
return false;
}
}