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

ApcuStorage::saveCompareAndSwap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
eloc 3
c 2
b 0
f 2
dl 0
loc 6
rs 10
cc 1
nc 1
nop 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\RateLimiter\Storage;
6
7
use InvalidArgumentException;
8
use Yiisoft\Yii\RateLimiter\Exception\CannotUseException;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Yii\RateLimiter\...tion\CannotUseException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
/**
11
 * To use this storage, the [APCu PHP extension](http://www.php.net/apcu) must be loaded,
12
 * And you should add "apc.enabled = 1" to your php.ini.
13
 * In order to enable APCu for CLI you should add "apc.enable_cli = 1" to your php.ini.
14
 */
15
final class ApcuStorage implements StorageInterface
16
{
17
    private const DEFAULT_FIX_PRECISION_RATE = 1000;
18
19
    /**
20
     * @param int $fixPrecisionRate 
21
     * Apcu_cas of ACPu does not support float,  and yet supports int.
22
     * APCu's stored value multiply by $fixPrecisionRate converts to int,
23
     * AND the getter's value divide by $fixPrecisionRate converts to float.
24
     * So use it to improve precision.
25
     */
26
    public function __construct(
27
        private int $fixPrecisionRate = self::DEFAULT_FIX_PRECISION_RATE
28
    ) {
29
    }
30
31
    public function saveIfNotExists(string $key, int|float $value, int $ttl): bool
32
    {
33
        $value = (int) ($value * $this->fixPrecisionRate);
34
35
        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...
36
    }
37
38
    public function saveCompareAndSwap(string $key, int|float $oldValue, int|float $newValue, int $ttl): bool
39
    {
40
        $oldValue = (int) ($oldValue * $this->fixPrecisionRate);
41
        $newValue = (int) ($newValue * $this->fixPrecisionRate);
42
43
        return apcu_cas($key, $oldValue, $newValue);
44
    }
45
46
    public function get(string $key): ?float
47
    {
48
        $value = apcu_fetch($key);
49
        if (!is_int($value) && !is_float($value) && $value !== false) {
50
            throw new InvalidArgumentException('The value is not supported by ApcuStorage, it must be int, float.');
51
        }
52
53
        if ($value !== false) {
54
            $value = (float)$value / $this->fixPrecisionRate;
55
        } else {
56
            $value = null;
57
        }
58
        return $value;
59
    }
60
}
61