Status::isOpen()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace NiR\CircuitBreaker\Service;
6
7
/**
8
 * Represents the current status of a service.
9
 *
10
 * @author Albin Kerouanton <[email protected]>
11
 *
12
 * @internal
13
 */
14
/* final */ class Status
15
{
16
    const CLOSED = 'closed';
17
    const HALF_OPEN = 'half_open';
18
    const OPEN = 'open';
19
20
    /** @var Configuration Configuration of the related service. */
21
    private $config;
22
23
    /** @var int Current number of failures. */
24
    private $failures;
25
26
    /** @var int Last time status has been updated. */
27
    private $lastUpdate;
28
29
    /**
30
     * @param Configuration $config     Configuration of the related service.
31
     * @param int           $failures   Current number of failures.
32
     * @param int           $lastUpdate Last time status has been updated, as timezone-independent unix timestamp (default to current time).
33
     */
34
    public function __construct(Configuration $config, int $failures = 0, int $lastUpdate = 0)
35
    {
36
        $this->config = $config;
37
        $this->failures = $failures;
38
        $this->lastUpdate = $lastUpdate ?: time();
39
    }
40
41
    /**
42
     * Creates a new Status with cleared failures and update timestamp.
43
     *
44
     * @return Status
45
     */
46
    public function close(): self
47
    {
48
        return new Status($this->config);
49
    }
50
51
    /**
52
     * Creates a new Status with the number of failures incremented.
53
     *
54
     * @return Status
55
     */
56
    public function failed(): self
57
    {
58
        return new Status($this->config, $this->failures + 1, time());
59
    }
60
61
    /**
62
     * Is the service circuit close?
63
     *
64
     * @return bool
65
     */
66
    public function isClose(): bool
67
    {
68
        return $this->getStatus() === self::CLOSED;
69
    }
70
71
    /**
72
     * Is the service circuit half open?
73
     *
74
     * @return bool
75
     */
76
    public function isHalfOpen(): bool
77
    {
78
        return $this->getStatus() === self::HALF_OPEN;
79
    }
80
81
    /**
82
     * Is the service circuit open?
83
     *
84
     * @return bool
85
     */
86
    public function isOpen(): bool
87
    {
88
        return $this->getStatus() === self::OPEN;
89
    }
90
91
    /**
92
     * Get the current number of failures.
93
     *
94
     * @return int
95
     */
96
    public function getFailures(): int
97
    {
98
        return $this->failures;
99
    }
100
101
    /**
102
     * Get the timestamp of the last update.
103
     *
104
     * @return int
105
     */
106
    public function getLastUpdate(): int
107
    {
108
        return $this->lastUpdate;
109
    }
110
111
    private function getStatus(): string
112
    {
113
        if ($this->failures < $this->config->getOpeningThreshold()) {
114
            return self::CLOSED;
115
        } elseif ($this->lastUpdate + $this->config->getClosingDelay() < time()) {
116
            return self::HALF_OPEN;
117
        }
118
119
        return self::OPEN;
120
    }
121
}
122