CircuitBreaker::markAsFailure()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 17
rs 9.9
1
<?php
2
3
/**
4
 * This file is part of the bugloos/fault-tolerance-bundle project.
5
 * (c) Bugloos <https://bugloos.com/>
6
 * For the full copyright and license information, please view
7
 * the LICENSE file that was distributed with this source code.
8
 */
9
10
namespace Bugloos\FaultToleranceBundle\CircuitBreaker;
11
12
use Bugloos\FaultToleranceBundle\CircuitBreaker\Storage\Storage;
13
use Psr\Cache\InvalidArgumentException;
14
15
/**
16
 * @author Mojtaba Gheytasi <[email protected]>
17
 */
18
class CircuitBreaker
19
{
20
    private Storage $storage;
21
22
    private string $commandKey;
23
24
    private array $config;
25
26
    public function __construct(
27
        string $commandKey,
28
        Storage $storage,
29
        array $config
30
    ) {
31
        $this->commandKey = $commandKey;
32
        $this->storage = $storage;
33
        $this->config = $config;
34
    }
35
36
    /**
37
     * @throws InvalidArgumentException
38
     */
39
    private function isOpen(): bool
40
    {
41
        if ($this->storage->isOpen($this->commandKey)) {
42
            return true;
43
        }
44
45
        if (
46
            $this->storage->failureCount($this->commandKey) >= $this->config['failureRateThreshold']
47
        ) {
48
            $this->storage->setOpenCircuit(
49
                $this->commandKey,
50
                $this->config['timeWindow']
51
            );
52
            $this->storage->setHalfOpenCircuit(
53
                $this->commandKey,
54
                $this->config['timeWindow'],
55
                $this->config['intervalToHalfOpen']
56
            );
57
58
            return true;
59
        }
60
61
        return false;
62
    }
63
64
    /**
65
     * @throws InvalidArgumentException
66
     */
67
    public function allowRequest(): bool
68
    {
69
        if ($this->config['forceOpen']) {
70
            return false;
71
        }
72
73
        if ($this->config['forceClosed']) {
74
            return true;
75
        }
76
77
        return ! $this->isOpen();
78
    }
79
80
    /**
81
     * @throws InvalidArgumentException
82
     */
83
    public function markAsSuccess()
84
    {
85
        $this->storage->setSuccess($this->commandKey);
86
    }
87
88
    /**
89
     * @throws InvalidArgumentException
90
     */
91
    public function markAsFailure(): void
92
    {
93
        if ($this->storage->isHalfOpen($this->commandKey)) {
94
            $this->storage->setOpenCircuit(
95
                $this->commandKey,
96
                $this->config['timeWindow']
97
            );
98
            $this->storage->setHalfOpenCircuit(
99
                $this->commandKey,
100
                $this->config['timeWindow'],
101
                $this->config['intervalToHalfOpen']
102
            );
103
        }
104
105
        $this->storage->incrementFailure(
106
            $this->commandKey,
107
            $this->config['timeWindow']
108
        );
109
    }
110
}
111