Skip to content

Commit 038bcbf

Browse files
committed
used otel clock instead of new class
1 parent bd1b9d0 commit 038bcbf

File tree

10 files changed

+122
-173
lines changed

10 files changed

+122
-173
lines changed

src/Sampler/Xray/src/AWSXRayRemoteSampler.php

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
namespace OpenTelemetry\Contrib\Sampler\Xray;
77

8-
use DateTimeImmutable;
98
use Exception;
9+
use OpenTelemetry\API\Common\Time\Clock;
10+
use OpenTelemetry\API\Common\Time\ClockInterface;
1011
use OpenTelemetry\Context\ContextInterface;
1112
use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
1213
use OpenTelemetry\SDK\Resource\ResourceInfo;
@@ -17,13 +18,32 @@
1718
/** @psalm-suppress UnusedClass */
1819
class AWSXRayRemoteSampler implements SamplerInterface
1920
{
21+
// 5 minute default sampling rules polling interval
22+
private const DEFAULT_RULES_POLLING_INTERVAL_SECONDS = 5 * 60;
23+
// Default endpoint for awsproxy : https://aws-otel.github.io/docs/getting-started/remote-sampling#enable-awsproxy-extension
24+
private const DEFAULT_AWS_PROXY_ENDPOINT = 'http://localhost:2000';
25+
2026
private SamplerInterface $root;
27+
28+
/**
29+
* @param ResourceInfo $resource
30+
* Must contain attributes like service.name, cloud.platform, etc.
31+
* @param string $host
32+
* X-Ray host, e.g. "xray.us-west-2.amazonaws.com"
33+
* @param int $pollingInterval
34+
* Base interval (seconds) between rule fetches (will be jittered).
35+
*/
2136
public function __construct(
2237
ResourceInfo $resource,
23-
string $host,
24-
int $rulePollingIntervalMillis = 60
38+
string $host = self::DEFAULT_AWS_PROXY_ENDPOINT,
39+
int $pollingInterval = self::DEFAULT_RULES_POLLING_INTERVAL_SECONDS
2540
) {
26-
$this->root = new ParentBased(new _AWSXRayRemoteSampler($resource, $host, $rulePollingIntervalMillis));
41+
// pollingInterval shouldn't be less than 10 seconds
42+
if ($pollingInterval < 10) {
43+
$pollingInterval = self::DEFAULT_RULES_POLLING_INTERVAL_SECONDS;
44+
}
45+
46+
$this->root = new ParentBased(new _AWSXRayRemoteSampler($resource, $host, $pollingInterval));
2747
}
2848

2949
public function shouldSample(
@@ -48,24 +68,20 @@ public function getDescription(): string
4868

4969
class _AWSXRayRemoteSampler implements SamplerInterface
5070
{
51-
// 5 minute default sampling rules polling interval
52-
private const DEFAULT_RULES_POLLING_INTERVAL_SECONDS = 5 * 60;
53-
// Default endpoint for awsproxy : https://aws-otel.github.io/docs/getting-started/remote-sampling#enable-awsproxy-extension
54-
private const DEFAULT_AWS_PROXY_ENDPOINT = 'http://localhost:2000';
55-
56-
private Clock $clock;
5771
private RulesCache $rulesCache;
5872
private FallbackSampler $fallback;
5973
private AWSXRaySamplerClient $client;
6074

61-
private int $rulePollingIntervalMillis;
75+
private int $rulePollingIntervalNanos;
6276
/** @psalm-suppress UnusedProperty */
63-
private int $targetPollingIntervalMillis;
64-
private DateTimeImmutable $nextRulesFetchTime;
65-
private DateTimeImmutable $nextTargetFetchTime;
77+
private int $targetPollingIntervalNanos;
78+
79+
// the times below are in nanoseconds
80+
private int $nextRulesFetchTime;
81+
private int $nextTargetFetchTime;
6682

67-
private int $rulePollingJitterMillis;
68-
private int $targetPollingJitterMillis;
83+
private int $rulePollingJitterNanos;
84+
private int $targetPollingJitterNanos;
6985

7086
private string $awsProxyEndpoint;
7187

@@ -79,23 +95,21 @@ class _AWSXRayRemoteSampler implements SamplerInterface
7995
*/
8096
public function __construct(
8197
ResourceInfo $resource,
82-
string $awsProxyEndpoint = self::DEFAULT_AWS_PROXY_ENDPOINT,
83-
int $pollingInterval = self::DEFAULT_RULES_POLLING_INTERVAL_SECONDS
98+
string $awsProxyEndpoint,
99+
int $pollingInterval
84100
) {
85-
$this->clock = new Clock();
86101
$this->fallback = new FallbackSampler();
87102
$this->rulesCache = new RulesCache(
88-
$this->clock,
89103
bin2hex(random_bytes(12)),
90104
$resource,
91105
$this->fallback
92106
);
93107

94-
$this->rulePollingIntervalMillis = $pollingInterval * 1000;
95-
$this->rulePollingJitterMillis = rand(1, 5000);
108+
$this->rulePollingIntervalNanos = $pollingInterval * ClockInterface::NANOS_PER_SECOND;
109+
$this->rulePollingJitterNanos = rand(1, 5000) * ClockInterface::NANOS_PER_MILLISECOND;
96110

97-
$this->targetPollingIntervalMillis = $this->rulesCache::DEFAULT_TARGET_INTERVAL_SEC * 1000;
98-
$this->targetPollingJitterMillis = rand(1, 100);
111+
$this->targetPollingIntervalNanos = $this->rulesCache::DEFAULT_TARGET_INTERVAL_SEC * ClockInterface::NANOS_PER_SECOND;
112+
$this->targetPollingJitterNanos = rand(1, 100) * ClockInterface::NANOS_PER_MILLISECOND;
99113

100114
$this->awsProxyEndpoint = $awsProxyEndpoint;
101115

@@ -110,9 +124,9 @@ public function __construct(
110124
}
111125

112126
// 2) Schedule next fetch times with jitter
113-
$now = $this->clock->now();
114-
$this->nextRulesFetchTime = $now->modify('+ ' . ($this->rulePollingJitterMillis + $this->rulePollingIntervalMillis) . ' milliseconds');
115-
$this->nextTargetFetchTime = $now->modify('+ ' . ($this->targetPollingJitterMillis + $this->targetPollingIntervalMillis) . ' milliseconds');
127+
$now = Clock::getDefault()->now();
128+
$this->nextRulesFetchTime = $now + ($this->rulePollingJitterNanos + $this->rulePollingIntervalNanos);
129+
$this->nextTargetFetchTime = $now + ($this->targetPollingJitterNanos + $this->targetPollingIntervalNanos);
116130
}
117131

118132
/**
@@ -126,7 +140,7 @@ public function shouldSample(
126140
AttributesInterface $attributes,
127141
array $links,
128142
): SamplingResult {
129-
$now = $this->clock->now();
143+
$now = Clock::getDefault()->now();
130144

131145
// 1) Refresh rules if needed
132146
if ($now >= $this->nextRulesFetchTime) {
@@ -151,7 +165,7 @@ public function shouldSample(
151165
$this->rulesCache->updateTargets($map);
152166

153167
if (isset($resp->LastRuleModification) && $resp->LastRuleModification > 0) {
154-
if ($resp->LastRuleModification > $this->rulesCache->getUpdatedAt()->getTimestamp()) {
168+
if (($resp->LastRuleModification * ClockInterface::NANOS_PER_SECOND) > $this->rulesCache->getUpdatedAt()) {
155169
$this->getAndUpdateRules($now);
156170
}
157171
}
@@ -161,15 +175,11 @@ public function shouldSample(
161175
}
162176

163177
$nextTargetFetchTime = $this->rulesCache->nextTargetFetchTime();
164-
$nextTargetFetchInterval = $nextTargetFetchTime->getTimestamp() - $this->clock->now()->getTimestamp();
178+
$nextTargetFetchInterval = $nextTargetFetchTime - Clock::getDefault()->now();
165179
if ($nextTargetFetchInterval < 0) {
166-
$nextTargetFetchInterval = $this->rulesCache::DEFAULT_TARGET_INTERVAL_SEC;
180+
$nextTargetFetchInterval = $this->rulesCache::DEFAULT_TARGET_INTERVAL_SEC * ClockInterface::NANOS_PER_SECOND;
167181
}
168-
169-
$nextTargetFetchInterval = $nextTargetFetchInterval * 1000;
170-
171-
$this->nextTargetFetchTime = $now->modify('+ ' . ($this->targetPollingJitterMillis + $nextTargetFetchInterval) . ' milliseconds');
172-
182+
$this->nextTargetFetchTime = $now + ($this->targetPollingJitterNanos + $nextTargetFetchInterval);
173183
}
174184

175185
// 3) Delegate decision to rulesCache or fallback
@@ -182,23 +192,23 @@ public function shouldSample(
182192
return $this->rulesCache->shouldSample($parentContext, $traceId, $spanName, $spanKind, $attributes, $links);
183193
}
184194

185-
private function getAndUpdateRules(DateTimeImmutable $now)
195+
private function getAndUpdateRules(int $now)
186196
{
187197
try {
188198
$rules = $this->client->getSamplingRules();
189199
$this->rulesCache->updateRules($rules);
190200
} catch (Exception $e) {
191201
// ignore error
192202
}
193-
$this->nextRulesFetchTime = $now->modify('+ ' . ($this->rulePollingJitterMillis + $this->rulePollingIntervalMillis) . ' milliseconds');
203+
$this->nextRulesFetchTime = $now + ($this->rulePollingJitterNanos + $this->rulePollingIntervalNanos);
194204
}
195205

196206
public function getDescription(): string
197207
{
198208
return sprintf(
199-
'_AWSXRayRemoteSampler{awsProxyEndpoint=%s,rulePollingIntervalMillis=%ds}',
209+
'_AWSXRayRemoteSampler{awsProxyEndpoint=%s,rulePollingIntervalNanos=%ds}',
200210
$this->awsProxyEndpoint,
201-
$this->rulePollingIntervalMillis
211+
$this->rulePollingIntervalNanos
202212
);
203213
}
204214
}

src/Sampler/Xray/src/AWSXRaySamplerClient.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?php
22

33
declare(strict_types=1);
4-
// src/Sampler/AWS/AWSXRaySamplerClient.php
54

65
namespace OpenTelemetry\Contrib\Sampler\Xray;
76

src/Sampler/Xray/src/Clock.php

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/Sampler/Xray/src/RulesCache.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
namespace OpenTelemetry\Contrib\Sampler\Xray;
77

8+
use OpenTelemetry\API\Common\Time\Clock;
9+
use OpenTelemetry\API\Common\Time\ClockInterface;
810
use OpenTelemetry\Context\ContextInterface;
911
use OpenTelemetry\SDK\Common\Attribute\AttributesInterface;
1012
use OpenTelemetry\SDK\Resource\ResourceInfo;
@@ -13,28 +15,26 @@
1315

1416
class RulesCache implements SamplerInterface
1517
{
16-
private const CACHE_TTL = 3600; // 1hr
18+
private const CACHE_TTL = 3600 * ClockInterface::NANOS_PER_SECOND; // 1hr
1719
public const DEFAULT_TARGET_INTERVAL_SEC = 10;
18-
private Clock $clock;
1920
private string $clientId;
2021
private ResourceInfo $resource;
2122
private SamplerInterface $fallbackSampler;
2223
/** @var SamplingRuleApplier[] */
2324
private array $appliers = [];
24-
private \DateTimeImmutable $updatedAt;
25+
private int $updatedAt;
2526

26-
public function __construct(Clock $clock, string $clientId, ResourceInfo $resource, SamplerInterface $fallback)
27+
public function __construct(string $clientId, ResourceInfo $resource, SamplerInterface $fallback)
2728
{
28-
$this->clock = $clock;
2929
$this->clientId = $clientId;
3030
$this->resource = $resource;
3131
$this->fallbackSampler = $fallback;
32-
$this->updatedAt = $clock->now();
32+
$this->updatedAt = Clock::getDefault()->now();
3333
}
3434

3535
public function expired(): bool
3636
{
37-
return $this->clock->now()->getTimestamp() > $this->updatedAt->getTimestamp() + self::CACHE_TTL;
37+
return Clock::getDefault()->now() > $this->updatedAt + self::CACHE_TTL;
3838
}
3939

4040
public function updateRules(array $newRules): void
@@ -51,14 +51,14 @@ public function updateRules(array $newRules): void
5151
break;
5252
}
5353
}
54-
$applier = $found ?? new SamplingRuleApplier($this->clientId, $this->clock, $rule);
54+
$applier = $found ?? new SamplingRuleApplier($this->clientId, $rule);
5555

5656
// update rule in applier
5757
$applier->setRule($rule);
5858
$newAppliers[] = $applier;
5959
}
6060
$this->appliers = $newAppliers;
61-
$this->updatedAt = $this->clock->now();
61+
$this->updatedAt = Clock::getDefault()->now();
6262
}
6363

6464
public function shouldSample(
@@ -79,17 +79,17 @@ public function shouldSample(
7979
return $this->fallbackSampler->shouldSample($parentContext, $traceId, $spanName, $spanKind, $attributes, $links);
8080
}
8181

82-
public function nextTargetFetchTime(): \DateTimeImmutable
82+
public function nextTargetFetchTime(): int
8383
{
84-
$defaultPollingTime = $this->clock->now()->add(new \DateInterval('PT' . self::DEFAULT_TARGET_INTERVAL_SEC . 'S'));
84+
$defaultPollingTime = Clock::getDefault()->now() + (self::DEFAULT_TARGET_INTERVAL_SEC * ClockInterface::NANOS_PER_SECOND);
8585

8686
if (empty($this->appliers)) {
8787
return $defaultPollingTime;
8888
}
8989
$times = array_map(fn ($a) => $a->getNextSnapshotTime(), $this->appliers);
9090
$min = min($times);
9191

92-
return $min < $this->clock->now()
92+
return $min < Clock::getDefault()->now()
9393
? $defaultPollingTime
9494
: $min;
9595
}
@@ -101,7 +101,7 @@ public function updateTargets(array $targets): void
101101
foreach ($this->appliers as $applier) {
102102
$name = $applier->getRuleName();
103103
if (isset($targets[$name])) {
104-
$new[] = $applier->withTarget($targets[$name], $this->clock->now());
104+
$new[] = $applier->withTarget($targets[$name], Clock::getDefault()->now());
105105
} else {
106106
$new[] = $applier;
107107
}
@@ -119,7 +119,7 @@ public function getDescription(): string
119119
return 'RulesCache';
120120
}
121121

122-
public function getUpdatedAt(): \DateTimeImmutable
122+
public function getUpdatedAt(): int
123123
{
124124
return $this->updatedAt;
125125
}

src/Sampler/Xray/src/SamplingRule.php

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,23 @@
55

66
namespace OpenTelemetry\Contrib\Sampler\Xray;
77

8+
/** @psalm-suppress PossiblyUnusedProperty */
89
class SamplingRule implements \JsonSerializable
910
{
10-
public string $RuleName;
11-
public int $Priority;
12-
public float $FixedRate;
13-
public int $ReservoirSize;
14-
public string $Host;
15-
public string $HttpMethod;
16-
public string $ResourceArn;
17-
public string $ServiceName;
18-
public string $ServiceType;
19-
public string $UrlPath;
20-
/** @psalm-suppress PossiblyUnusedProperty */
21-
public int $Version;
22-
public array $Attributes;
23-
2411
public function __construct(
25-
string $ruleName,
26-
int $priority,
27-
float $fixedRate,
28-
int $reservoirSize,
29-
string $host,
30-
string $httpMethod,
31-
string $resourceArn,
32-
string $serviceName,
33-
string $serviceType,
34-
string $urlPath,
35-
int $version,
36-
array $attributes = []
12+
public string $RuleName,
13+
public int $Priority,
14+
public float $FixedRate,
15+
public int $ReservoirSize,
16+
public string $Host,
17+
public string $HttpMethod,
18+
public string $ResourceArn,
19+
public string $ServiceName,
20+
public string $ServiceType,
21+
public string $UrlPath,
22+
public int $Version,
23+
public array $Attributes,
3724
) {
38-
$this->RuleName = $ruleName;
39-
$this->Priority = $priority;
40-
$this->FixedRate = $fixedRate;
41-
$this->ReservoirSize= $reservoirSize;
42-
$this->Host = $host;
43-
$this->HttpMethod = $httpMethod;
44-
$this->ResourceArn = $resourceArn;
45-
$this->ServiceName = $serviceName;
46-
$this->ServiceType = $serviceType;
47-
$this->UrlPath = $urlPath;
48-
$this->Version = $version;
49-
$this->Attributes = $attributes;
5025
}
5126

5227
public function jsonSerialize(): array

0 commit comments

Comments
 (0)