Skip to content

Commit dd4d335

Browse files
Fix #376: AwsXrayRemoteSampler doesn’t poll for update (#377)
In the default configuration `pollingIntervalNanos = 3 * 10^11` so `pollingIntervalMillis / 100 > Integer.MAX_VALUE`. Switch to storing the jitter in a `long` as well.
1 parent 82d0178 commit dd4d335

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
import io.opentelemetry.sdk.trace.samplers.Sampler;
1818
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
1919
import java.io.Closeable;
20+
import java.time.Duration;
2021
import java.time.Instant;
2122
import java.util.Date;
23+
import java.util.Iterator;
2224
import java.util.List;
2325
import java.util.Map;
2426
import java.util.Random;
@@ -49,7 +51,7 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable {
4951
// Unique per-sampler client ID, generated as a random string.
5052
private final String clientId;
5153
private final long pollingIntervalNanos;
52-
private final int jitterNanos;
54+
private final Iterator<Long> jitterNanos;
5355

5456
@Nullable private volatile ScheduledFuture<?> pollFuture;
5557
@Nullable private volatile ScheduledFuture<?> fetchTargetsFuture;
@@ -94,8 +96,8 @@ public static AwsXrayRemoteSamplerBuilder newBuilder(Resource resource) {
9496
sampler = initialSampler;
9597

9698
this.pollingIntervalNanos = pollingIntervalNanos;
97-
// Add ~1% of jitter. Truncating to int is safe for any practical polling interval.
98-
jitterNanos = (int) (pollingIntervalNanos / 100);
99+
// Add ~1% of jitter
100+
jitterNanos = RANDOM.longs(0, pollingIntervalNanos / 100).iterator();
99101

100102
// Execute first update right away on the executor thread.
101103
executor.execute(this::getAndUpdateSampler);
@@ -148,10 +150,25 @@ private void getAndUpdateSampler() {
148150
}
149151

150152
private void scheduleSamplerUpdate() {
151-
long delay = pollingIntervalNanos + RANDOM.nextInt(jitterNanos);
153+
long delay = pollingIntervalNanos + jitterNanos.next();
152154
pollFuture = executor.schedule(this::getAndUpdateSampler, delay, TimeUnit.NANOSECONDS);
153155
}
154156

157+
/**
158+
* returns the duration until the next scheduled sampler update or null if no next update is
159+
* scheduled yet.
160+
*
161+
* <p>only used for testing.
162+
*/
163+
@Nullable
164+
Duration getNextSamplerUpdateScheduledDuration() {
165+
ScheduledFuture<?> pollFuture = this.pollFuture;
166+
if (pollFuture == null) {
167+
return null;
168+
}
169+
return Duration.ofNanos(pollFuture.getDelay(TimeUnit.NANOSECONDS));
170+
}
171+
155172
private void fetchTargets() {
156173
if (!(sampler instanceof XrayRulesSampler)) {
157174
throw new IllegalStateException("Programming bug.");

aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,25 @@ void defaultInitialSampler() {
168168
}
169169
}
170170

171+
// https://github.com/open-telemetry/opentelemetry-java-contrib/issues/376
172+
@Test
173+
void testJitterTruncation() {
174+
try (AwsXrayRemoteSampler samplerWithLongerPollingInterval =
175+
AwsXrayRemoteSampler.newBuilder(Resource.empty())
176+
.setInitialSampler(Sampler.alwaysOn())
177+
.setEndpoint(server.httpUri().toString())
178+
.setPollingInterval(Duration.ofMinutes(5))
179+
.build()) {
180+
assertThat(samplerWithLongerPollingInterval.getNextSamplerUpdateScheduledDuration()).isNull();
181+
await()
182+
.untilAsserted(
183+
() -> {
184+
assertThat(samplerWithLongerPollingInterval.getNextSamplerUpdateScheduledDuration())
185+
.isCloseTo(Duration.ofMinutes(5), Duration.ofSeconds(10));
186+
});
187+
}
188+
}
189+
171190
private static SamplingDecision doSample(Sampler sampler, String name) {
172191
return sampler
173192
.shouldSample(

0 commit comments

Comments
 (0)