RequestLimitGroup   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 12
eloc 27
c 2
b 0
f 1
dl 0
loc 72
ccs 31
cts 31
cp 1
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A canRequest() 0 19 4
A __construct() 0 3 1
A addRequestLimiter() 0 5 1
A getRequestLimiterCount() 0 3 1
A getRetryAfter() 0 3 1
A create() 0 3 1
A removeRequestLimiter() 0 5 1
A addRules() 0 8 2
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
class RequestLimitGroup
10
{
11
    private SplObjectStorage $_requestLimiters;
12
    private int $_retryAfter = 0;
13
14 30
    public function __construct()
15
    {
16 30
        $this->_requestLimiters = new SplObjectStorage();
17 30
    }
18
19 5
    public static function create(): self
20
    {
21 5
        return new static();
22
    }
23
24 20
    public function getRetryAfter(): int
25
    {
26 20
        return $this->_retryAfter;
27
    }
28
29
    /**
30
     * We have to cycle through all the limiters (no early return).
31
     * The timers of each limiter have to be updated despite of another limiter already preventing the request.
32
     */
33 22
    public function canRequest(RequestInterface $request, array $options = []): bool
34
    {
35 22
        $groupCanRequest = true;
36 22
        $this->_requestLimiters->rewind();
37 22
        while ($this->_requestLimiters->valid()) {
38
            /** @var RequestLimiter $requestLimiter */
39 22
            $requestLimiter = $this->_requestLimiters->current();
40
41 22
            $canRequest = $requestLimiter->canRequest($request, $options);
42
43 22
            if ($groupCanRequest && !$canRequest) {
44 21
                $groupCanRequest = false;
45 21
                $this->_retryAfter = $requestLimiter->getRemainingSeconds();
46
            }
47
48 22
            $this->_requestLimiters->next();
49
        }
50
51 22
        return $groupCanRequest;
52
    }
53
54 24
    public function addRequestLimiter(RequestLimiter $requestLimiter): self
55
    {
56 24
        $this->_requestLimiters->attach($requestLimiter);
57
58 24
        return $this;
59
    }
60
61 1
    public function removeRequestLimiter(RequestLimiter $requestLimiter): self
62
    {
63 1
        $this->_requestLimiters->detach($requestLimiter);
64
65 1
        return $this;
66
    }
67
68 2
    public function getRequestLimiterCount(): int
69
    {
70 2
        return $this->_requestLimiters->count();
71
    }
72
73 20
    public function addRules(string $host, array $rules, StorageInterface $storage): void
74
    {
75 20
        foreach ($rules as $rule) {
76 20
            $this->addRequestLimiter(
77 20
                RequestLimiter::createFromRule(
78 20
                    $host,
79
                    $rule,
80
                    $storage
81
                )
82
            );
83
        }
84 20
    }
85
}
86