Completed
Push — master ( a46738...071d43 )
by Nikola
14s queued 11s
created

InMemoryRateLimiter::key()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RateLimit;
6
7
use RateLimit\Exception\LimitExceeded;
8
9
final class InMemoryRateLimiter implements RateLimiter, SilentRateLimiter
10
{
11
    /** @var array */
12
    private $store = [];
13
14 2
    public function limit(string $identifier, Rate $rate): void
15
    {
16 2
        $key = $this->key($identifier, $rate->getInterval());
17
18 2
        $current = $this->hit($key, $rate);
19
20 2
        if ($current > $rate->getOperations()) {
21 2
            throw LimitExceeded::for($identifier, $rate);
22
        }
23 2
    }
24
25 3
    public function limitSilently(string $identifier, Rate $rate): Status
26
    {
27 3
        $key = $this->key($identifier, $rate->getInterval());
28
29 3
        $current = $this->hit($key, $rate);
30
31 3
        return Status::from(
32 3
            $identifier,
33 3
            $current,
34 3
            $rate->getOperations(),
35 3
            $this->store[$key]['reset_time']
36
        );
37
    }
38
39 5
    private function key(string $identifier, int $interval): string
40
    {
41 5
        return "$identifier:$interval:" . floor(time() / $interval);
42
    }
43
44 5
    private function hit(string $key, Rate $rate): int
45
    {
46 5
        if (!isset($this->store[$key])) {
47 5
            $this->store[$key] = [
48 5
                'current' => 1,
49 5
                'reset_time' => time() + $rate->getInterval(),
50
            ];
51 4
        } elseif ($this->store[$key]['current'] <= $rate->getOperations()) {
52 4
            $this->store[$key]['current']++;
53
        }
54
55 5
        return $this->store[$key]['current'];
56
    }
57
}
58