Completed
Push — master ( 7353e9...0c9da4 )
by BENOIT
01:14
created

ThrottleMiddleware::getRemainingTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
3
namespace BenTools\GuzzleHttp\Middleware;
4
5
use BenTools\GuzzleHttp\Middleware\Storage\Adapter\ArrayAdapter;
6
use BenTools\GuzzleHttp\Middleware\Storage\Counter;
7
use BenTools\GuzzleHttp\Middleware\Storage\ThrottleStorageInterface;
8
use Psr\Http\Message\RequestInterface;
9
10
class ThrottleMiddleware
11
{
12
    /**
13
     * @var ThrottleConfiguration[]
14
     */
15
    private $configurations = [];
16
    /**
17
     * @var ThrottleStorageInterface
18
     */
19
    private $storage;
20
21
    /**
22
     * ThrottleMiddleware constructor.
23
     * @param ThrottleStorageInterface $storage
24
     */
25
    public function __construct(ThrottleStorageInterface $storage = null)
26
    {
27
        $this->storage = $storage ?? new ArrayAdapter();
28
    }
29
30
    /**
31
     * @param ThrottleConfiguration $configuration
32
     */
33
    public function registerConfiguration(ThrottleConfiguration $configuration)
34
    {
35
        $this->configurations[$configuration->getStorageKey()] = $configuration;
36
    }
37
38
39
    public function __invoke(callable $handler)
40
    {
41
        return function (RequestInterface $request, array $options) use ($handler) {
42
            foreach ($this->configurations as $configuration) {
43
                // Request match - Check if we need to throttle
44
                if ($configuration->matchRequest($request)) {
45
                    if (!$this->storage->hasCounter($configuration->getStorageKey())) {
46
                        $counter = new Counter($configuration->getDuration());
47
                        $counter->increment();
48
                        $this->storage->saveCounter($configuration->getStorageKey(), $counter, $configuration->getDuration());
49
                    } else {
50
                        $counter = $this->storage->getCounter($configuration->getStorageKey());
51
52
                        if ($counter->count() >= $configuration->getMaxRequests()) {
53
                            usleep($counter->getRemainingTime() * 1000000);
54
                        } else {
55
                            $counter->increment();
56
                            $this->storage->saveCounter($configuration->getStorageKey(), $counter);
57
                        }
58
                    }
59
                    break;
60
                }
61
            }
62
            return $handler($request, $options);
63
        };
64
    }
65
}
66