Completed
Push — master ( f6ae37...a4455e )
by Timo
9s
created

RequestLimitGroup::addRules()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 3
dl 0
loc 9
ccs 7
cts 7
cp 1
crap 2
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace hamburgscleanest\GuzzleAdvancedThrottle;
4
5
use hamburgscleanest\GuzzleAdvancedThrottle\Cache\Interfaces\StorageInterface;
6
use Psr\Http\Message\RequestInterface;
7
use SplObjectStorage;
8
9
/**
10
 * Class RequestLimitGroup
11
 * @package hamburgscleanest\GuzzleAdvancedThrottle
12
 */
13
class RequestLimitGroup
14
{
15
16
    /** @var SplObjectStorage */
17
    private $_requestLimiters;
18
19
    /** @var int */
20
    private $_retryAfter = 0;
21
22
    /**
23
     * RequestLimitGroup constructor.
24
     */
25 16
    public function __construct()
26
    {
27 16
        $this->_requestLimiters = new SplObjectStorage();
28 16
    }
29
30
    /**
31
     * @return RequestLimitGroup
32
     */
33 5
    public static function create() : self
34
    {
35 5
        return new static();
36
    }
37
38
    /**
39
     * @return int
40
     */
41 10
    public function getRetryAfter() : int
42
    {
43 10
        return $this->_retryAfter;
44
    }
45
46
    /**
47
     * We have to cycle through all the limiters (no early return).
48
     * The timers of each limiter have to be updated despite of another limiter already preventing the request.
49
     *
50
     * @param RequestInterface $request
51
     * @param array $options
52
     * @return bool
53
     * @throws \Exception
54
     */
55 12
    public function canRequest(RequestInterface $request, array $options = []) : bool
56
    {
57 12
        $groupCanRequest = true;
58 12
        $this->_requestLimiters->rewind();
59 12
        while ($this->_requestLimiters->valid())
60
        {
61
            /** @var RequestLimiter $requestLimiter */
62 12
            $requestLimiter = $this->_requestLimiters->current();
63
64 12
            $canRequest = $requestLimiter->canRequest($request, $options);
65 12
            if ($groupCanRequest && !$canRequest)
66
            {
67 11
                $groupCanRequest = false;
68 11
                $this->_retryAfter = $requestLimiter->getRemainingSeconds();
69
            }
70
71 12
            $this->_requestLimiters->next();
72
        }
73
74 12
        return $groupCanRequest;
75
    }
76
77
    /**
78
     * @param RequestLimiter $requestLimiter
79
     * @return RequestLimitGroup
80
     */
81 14
    public function addRequestLimiter(RequestLimiter $requestLimiter) : self
82
    {
83 14
        $this->_requestLimiters->attach($requestLimiter);
84
85 14
        return $this;
86
    }
87
88
    /**
89
     * @param RequestLimiter $requestLimiter
90
     * @return RequestLimitGroup
91
     */
92 1
    public function removeRequestLimiter(RequestLimiter $requestLimiter) : self
93
    {
94 1
        $this->_requestLimiters->detach($requestLimiter);
95
96 1
        return $this;
97
    }
98
99
    /**
100
     * @return int
101
     */
102 2
    public function getRequestLimiterCount() : int
103
    {
104 2
        return $this->_requestLimiters->count();
105
    }
106
107
    /**
108
     * @param string $host
109
     * @param array $rules
110
     * @param StorageInterface $storage
111
     * @throws \Exception
112
     */
113 10
    public function addRules(string $host, array $rules, StorageInterface $storage) : void
114
    {
115 10
        foreach ($rules as $rule)
116
        {
117 10
            $this->addRequestLimiter(
118 10
                RequestLimiter::createFromRule(
119 10
                    $host,
120 10
                    $rule,
121 10
                    $storage
122
                )
123
            );
124
        }
125
    }
126
}