Passed
Push — master ( 876065...f10f6d )
by Kevin
01:15
created

Throttle   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 7
eloc 15
c 2
b 0
f 1
dl 0
loc 63
rs 10
ccs 17
cts 17
cp 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A acquire() 0 13 3
A status() 0 3 1
A hit() 0 3 1
A reset() 0 3 1
1
<?php
2
3
namespace Zenstruck\Governator;
4
5
use Zenstruck\Governator\Exception\QuotaExceeded;
6
7
/**
8
 * @author Kevin Bond <[email protected]>
9
 */
10
final class Throttle
11
{
12
    private Store $store;
13
    private Key $key;
14
15 112
    public function __construct(Store $store, Key $key)
16
    {
17 112
        $this->store = $store;
18 112
        $this->key = $key;
19 112
    }
20
21
    /**
22
     * "Hits" the throttle, increasing its hit count by 1. If the throttle's quota is exceeded and
23
     * it resets in less than or equal to the passed time, block the process until the throttle is reset,
24
     * then "hit" it again.
25
     *
26
     * DOES NOT BLOCK the process if the throttle's quota is exceeded and its time until reset is greater
27
     * than the passed time.
28
     *
29
     * @param int $blockFor max number of seconds to block the process waiting for the throttle to reset
30
     *
31
     * @return Quota Information on the current state of the throttle
32
     *
33
     * @throws QuotaExceeded If the current hit exceeds the throttle's limit and the passed time
34
     *                       is less then the throttle's "time to live"
35
     */
36 92
    public function acquire(int $blockFor = 0): Quota
37
    {
38
        try {
39 92
            return $this->hit()->check();
40 38
        } catch (QuotaExceeded $exception) {
41 38
            if ($exception->resetsIn() > $blockFor) {
42 20
                throw $exception;
43
            }
44
        }
45
46 18
        sleep($exception->resetsIn());
47
48 18
        return $this->hit()->check();
49
    }
50
51
    /**
52
     * "Hits" the throttle, increasing its hit count by 1.
53
     */
54 103
    public function hit(): Quota
55
    {
56 103
        return new Quota($this->key, $this->store->hit($this->key));
57
    }
58
59
    /**
60
     * Fetches the current state of the throttle without increasing its hit count.
61
     */
62 29
    public function status(): Quota
63
    {
64 29
        return new Quota($this->key, $this->store->status($this->key));
65
    }
66
67
    /**
68
     * Resets the throttle.
69
     */
70 101
    public function reset(): void
71
    {
72 101
        $this->store->reset($this->key);
73 101
    }
74
}
75