Skip to content

Commit 03b59bb

Browse files
committed
Added rate limiting sampler
1 parent 9394e05 commit 03b59bb

4 files changed

Lines changed: 90 additions & 0 deletions

File tree

src/Sampler/ConstGenerator.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Sampler;
5+
6+
class ConstGenerator implements GeneratorInterface
7+
{
8+
public function generate(int $traceId, string $operationName): string
9+
{
10+
return 'const';
11+
}
12+
}

src/Sampler/GeneratorInterface.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Sampler;
5+
6+
interface GeneratorInterface
7+
{
8+
public function generate(int $traceId, string $operationName) : string;
9+
}

src/Sampler/OperationGenerator.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Sampler;
5+
6+
class OperationGenerator implements GeneratorInterface
7+
{
8+
public function generate(int $traceId, string $operationName): string
9+
{
10+
return $operationName;
11+
}
12+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Sampler;
5+
6+
class RateLimitingSampler extends AbstractSampler
7+
{
8+
private $rate;
9+
10+
private $generator;
11+
12+
public function __construct(float $rate, GeneratorInterface $generator)
13+
{
14+
$this->rate = $rate;
15+
$this->generator = $generator;
16+
}
17+
18+
public function doDecide(int $traceId, string $operationName): SamplerResult
19+
{
20+
$key = $this->generator->generate($traceId, $operationName);
21+
if (false !== ($current = apcu_add($key, sprintf('%s:%d', time(), 1), 1 / $this->rate))) {
22+
return new SamplerResult(
23+
true, 0x01, [
24+
new SamplerTypeTag('ratelimiting'),
25+
new SamplerDecisionTag(true),
26+
new SamplerFlagsTag(0x01),
27+
new SamplerParamTag((string)$this->rate)
28+
]
29+
);
30+
}
31+
32+
while (true) {
33+
if (false === ($current = apcu_fetch($key))) {
34+
return $this->doDecide($traceId, $operationName);
35+
}
36+
list ($timestamp, $count) = explode(':', $current);
37+
if ($count / (time() - $timestamp) > $this->rate) {
38+
return new SamplerResult(false, 0);
39+
}
40+
if (false === apcu_cas($key, $current, sprintf('%s:%d', $timestamp, $count + 1))) {
41+
continue;
42+
}
43+
44+
return new SamplerResult(
45+
true, 0x01, [
46+
new SamplerTypeTag('ratelimiting'),
47+
new SamplerDecisionTag(true),
48+
new SamplerFlagsTag(0x01),
49+
new SamplerParamTag($key),
50+
new SamplerParamTag((string)$this->rate)
51+
]
52+
);
53+
}
54+
55+
return new SamplerResult(false, 0);
56+
}
57+
}

0 commit comments

Comments
 (0)