@@ -15,11 +15,21 @@ public function __construct(float $rate, GeneratorInterface $generator)
15
15
$ this ->generator = $ generator ;
16
16
}
17
17
18
+ public function value (int $ sec , int $ count )
19
+ {
20
+ return (($ sec & 0xffffffff ) << 16 ) + ($ count & 0xffff );
21
+ }
22
+
23
+ public function spec (int $ value )
24
+ {
25
+ return [$ value >> 16 , $ value & 0xffff ];
26
+ }
27
+
18
28
public function doDecide (int $ tracerId , string $ operationName ): SamplerResult
19
29
{
20
30
$ key = $ this ->generator ->generate ($ tracerId , $ operationName );
21
31
$ ttl = max ((int )(1 / $ this ->rate + 1 ), 1 );
22
- if (apcu_add ($ key , sprintf ( ' %s:%d ' , microtime ( true ), 1 ), $ ttl )) {
32
+ if (apcu_add ($ key , $ this -> value ( time ( ), 1 ), $ ttl )) {
23
33
return new SamplerResult (
24
34
true , 0x01 , [
25
35
new SamplerTypeTag ('ratelimiting ' ),
@@ -35,11 +45,13 @@ public function doDecide(int $tracerId, string $operationName): SamplerResult
35
45
if (false === ($ current = apcu_fetch ($ key ))) {
36
46
return $ this ->doDecide ($ tracerId , $ operationName );
37
47
}
38
- list ($ timestamp , $ count ) = explode (': ' , $ current );
39
- if ($ this ->rate * (microtime (true ) - (float )$ timestamp ) < (int )$ count ) {
48
+ list ($ timestamp , $ count ) = $ this ->spec ((int )$ current );
49
+ $ now = time ();
50
+ $ diff = ($ now === $ timestamp ) ? 1 : $ now - $ timestamp ;
51
+ if ($ this ->rate * $ diff <= $ count ) {
40
52
return new SamplerResult (false , 0 );
41
53
}
42
- if (false === apcu_cas ($ key , $ current , sprintf ( ' %s:%d ' , $ timestamp , ( int ) $ count + 1 ))) {
54
+ if (false === apcu_cas ($ key , ( int ) $ current , $ this -> value ( $ timestamp , $ count + 1 ))) {
43
55
$ retries ++;
44
56
continue ;
45
57
}
0 commit comments