Test Failed
Pull Request — master (#43)
by
unknown
02:23
created

ApcuStorage::saveIfNotExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
eloc 2
c 2
b 0
f 2
dl 0
loc 5
rs 10
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\RateLimiter\Storage;
6
7
use InvalidArgumentException;
8
9
/**
10
 * To use this storage, the [APCu PHP extension](http://www.php.net/apcu) must be loaded,
11
 * And you should add "apc.enabled = 1" to your php.ini.
12
 * In order to enable APCu for CLI you should add "apc.enable_cli = 1" to your php.ini.
13
 */
14
final class ApcuStorage implements StorageInterface
15
{
16
    private const DEFAULT_FIX_PRECISION_RATE = 1000;
17
18
    /**
19
     * @param int $fixPrecisionRate 
20
     * Apcu_cas of ACPu does not support float,  and yet supports int.
21
     * APCu's stored value multiply by $fixPrecisionRate converts to int,
22
     * AND the getter's value divide by $fixPrecisionRate converts to float.
23
     * So use it to improve precision.
24
     */
25
    public function __construct(
26
        private int $fixPrecisionRate = self::DEFAULT_FIX_PRECISION_RATE
27
    ) {
28
    }
29
30
    public function saveIfNotExists(string $key, float $value, int $ttl): bool
31
    {
32
        $value = (int) ($value * $this->fixPrecisionRate);
33
34
        return apcu_add($key, $value, $ttl);
0 ignored issues
show
Bug Best Practice introduced by
The expression return apcu_add($key, $value, $ttl) could return the type array which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
35
    }
36
37
    public function saveCompareAndSwap(string $key, float $oldValue, float $newValue, int $ttl): bool
38
    {
39
        $oldValue = (int) ($oldValue * $this->fixPrecisionRate);
40
        $newValue = (int) ($newValue * $this->fixPrecisionRate);
41
42
        return apcu_cas($key, $oldValue, $newValue);
43
    }
44
45
    public function get(string $key): ?float
46
    {
47
        $value = apcu_fetch($key);
48
        if (!is_int($value) && !is_float($value) && $value !== false) {
49
            throw new InvalidArgumentException('The value is not supported by ApcuStorage, it must be int, float.');
50
        }
51
52
        $value = ($value !== false) ? (float)$value / $this->fixPrecisionRate : null;
53
        return $value;
54
    }
55
}
56