@@ -333,7 +333,7 @@ index 00000000..dc5b7a01
333333+ }
334334+ }
335335diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java
336- index ad9b72a2..31d5a293 100644
336+ index ad9b72a2..2de038c9 100644
337337--- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java
338338+++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java
339339@@ -9,16 +9,22 @@ import io.opentelemetry.api.common.Attributes;
@@ -442,7 +442,7 @@ index ad9b72a2..31d5a293 100644
442442 previousRulesResponse = response;
443443 ScheduledFuture<?> existingFetchTargetsFuture = fetchTargetsFuture;
444444 if (existingFetchTargetsFuture != null) {
445- @@ -172,25 +217,41 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable {
445+ @@ -172,25 +217,51 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable {
446446 }
447447
448448 private void fetchTargets() {
@@ -464,14 +464,24 @@ index ad9b72a2..31d5a293 100644
464464+ statisticsSnapshot.stream()
465465+ .forEach(
466466+ snapshot -> {
467- + if (snapshot.getStatisticsDocument() != null) {
467+ + if (snapshot.getStatisticsDocument() != null
468+ + && snapshot.getStatisticsDocument().getRequestCount() > 0) {
468469+ statistics.add(snapshot.getStatisticsDocument());
469470+ }
470471+ if (snapshot.getBoostStatisticsDocument() != null
471472+ && snapshot.getBoostStatisticsDocument().getTotalCount() > 0) {
472473+ boostStatistics.add(snapshot.getBoostStatisticsDocument());
473474+ }
474475+ });
476+ +
477+ + // If there are no statistics to report, skip the request and schedule next update
478+ + if (statistics.isEmpty() && boostStatistics.isEmpty()) {
479+ + fetchTargetsFuture =
480+ + executor.schedule(
481+ + this::fetchTargets, DEFAULT_TARGET_INTERVAL_NANOS, TimeUnit.NANOSECONDS);
482+ + return;
483+ + }
484+ +
475485 Set<String> requestedTargetRuleNames =
476486 statistics.stream()
477487 .map(SamplingStatisticsDocument::getRuleName)
@@ -490,7 +500,7 @@ index ad9b72a2..31d5a293 100644
490500 } catch (Throwable t) {
491501 // Might be a transient API failure, try again after a default interval.
492502 fetchTargetsFuture =
493- @@ -226,11 +287 ,6 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable {
503+ @@ -226,11 +297 ,6 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable {
494504 return new String(clientIdChars);
495505 }
496506
@@ -1064,7 +1074,7 @@ index 1d97c4ae..dd369f5f 100644
10641074 }
10651075 }
10661076diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java
1067- index 75977dc0..48bdeb0f 100644
1077+ index 75977dc0..944d4e45 100644
10681078--- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java
10691079+++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java
10701080@@ -5,42 +5,81 @@
@@ -1321,7 +1331,7 @@ index 75977dc0..48bdeb0f 100644
13211331+ ruleToReportTo = applier;
13221332+ break;
13231333+ }
1324- + if (applier.matches(spanData.getAttributes(), resource)) {
1334+ + if (matchedRule == null && applier.matches(spanData.getAttributes(), resource)) {
13251335+ matchedRule = applier;
13261336+ }
13271337+ }
@@ -1593,7 +1603,7 @@ index 75977dc0..48bdeb0f 100644
15931603 }
15941604 }
15951605diff --git a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerTest.java b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerTest.java
1596- index 4e5cd13b..5af11a25 100644
1606+ index 4e5cd13b..42e490ef 100644
15971607--- a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerTest.java
15981608+++ b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerTest.java
15991609@@ -7,7 +7,10 @@ package io.opentelemetry.contrib.awsxray;
@@ -1607,7 +1617,7 @@ index 4e5cd13b..5af11a25 100644
16071617
16081618 import com.google.common.io.ByteStreams;
16091619 import com.linecorp.armeria.common.HttpResponse;
1610- @@ -21,6 +24,9 @@ import io.opentelemetry.api.trace.SpanKind;
1620+ @@ -21,12 +24,16 @@ import io.opentelemetry.api.trace.SpanKind;
16111621 import io.opentelemetry.api.trace.TraceId;
16121622 import io.opentelemetry.context.Context;
16131623 import io.opentelemetry.sdk.resources.Resource;
@@ -1617,7 +1627,90 @@ index 4e5cd13b..5af11a25 100644
16171627 import io.opentelemetry.sdk.trace.samplers.Sampler;
16181628 import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
16191629 import java.io.IOException;
1620- @@ -169,21 +175,28 @@ class AwsXrayRemoteSamplerTest {
1630+ import java.io.UncheckedIOException;
1631+ import java.time.Duration;
1632+ import java.util.Collections;
1633+ + import java.util.concurrent.atomic.AtomicInteger;
1634+ import java.util.concurrent.atomic.AtomicReference;
1635+ import org.junit.jupiter.api.AfterEach;
1636+ import org.junit.jupiter.api.BeforeEach;
1637+ @@ -37,6 +44,7 @@ class AwsXrayRemoteSamplerTest {
1638+
1639+ private static final byte[] RULE_RESPONSE_1;
1640+ private static final byte[] RULE_RESPONSE_2;
1641+ + private static final byte[] RULE_RESPONSE_3;
1642+ private static final byte[] TARGETS_RESPONSE;
1643+
1644+ static {
1645+ @@ -51,6 +59,11 @@ class AwsXrayRemoteSamplerTest {
1646+ requireNonNull(
1647+ AwsXrayRemoteSamplerTest.class.getResourceAsStream(
1648+ "/test-sampling-rules-response-2.json")));
1649+ + RULE_RESPONSE_3 =
1650+ + ByteStreams.toByteArray(
1651+ + requireNonNull(
1652+ + AwsXrayRemoteSamplerTest.class.getResourceAsStream(
1653+ + "/test-sampling-rules-response-3.json")));
1654+ TARGETS_RESPONSE =
1655+ ByteStreams.toByteArray(
1656+ requireNonNull(
1657+ @@ -63,6 +76,7 @@ class AwsXrayRemoteSamplerTest {
1658+
1659+ private static final AtomicReference<byte[]> rulesResponse = new AtomicReference<>();
1660+ private static final AtomicReference<byte[]> targetsResponse = new AtomicReference<>();
1661+ + private static final AtomicInteger samplingTargetsCallCount = new AtomicInteger(0);
1662+
1663+ private static final String TRACE_ID = TraceId.fromLongs(1, 2);
1664+
1665+ @@ -86,6 +100,7 @@ class AwsXrayRemoteSamplerTest {
1666+ sb.service(
1667+ "/SamplingTargets",
1668+ (ctx, req) -> {
1669+ + samplingTargetsCallCount.incrementAndGet();
1670+ byte[] response = AwsXrayRemoteSamplerTest.targetsResponse.get();
1671+ if (response == null) {
1672+ // Error out until the test configures a response, the sampler will use the
1673+ @@ -114,6 +129,7 @@ class AwsXrayRemoteSamplerTest {
1674+ void tearDown() {
1675+ sampler.close();
1676+ rulesResponse.set(null);
1677+ + samplingTargetsCallCount.set(0);
1678+ }
1679+
1680+ @Test
1681+ @@ -155,6 +171,31 @@ class AwsXrayRemoteSamplerTest {
1682+ assertThat(doSample(sampler, "dog-service"))
1683+ .isEqualTo(SamplingDecision.RECORD_AND_SAMPLE);
1684+ });
1685+ + await()
1686+ + .untilAsserted(
1687+ + () -> {
1688+ + assertThat(samplingTargetsCallCount.get()).isGreaterThan(0);
1689+ + });
1690+ + }
1691+ +
1692+ + @Test
1693+ + void getAndUpdateSamplerOnlyDropping() {
1694+ + // Initial Sampler allows all.
1695+ + assertThat(doSample(sampler, "cat-service")).isEqualTo(SamplingDecision.RECORD_AND_SAMPLE);
1696+ + assertThat(doSample(sampler, "dog-service")).isEqualTo(SamplingDecision.RECORD_AND_SAMPLE);
1697+ +
1698+ + rulesResponse.set(RULE_RESPONSE_3);
1699+ +
1700+ + // Should always drop now
1701+ + await()
1702+ + .untilAsserted(
1703+ + () -> {
1704+ + assertThat(doSample(sampler, "cat-service")).isEqualTo(SamplingDecision.DROP);
1705+ + assertThat(doSample(sampler, "dog-service")).isEqualTo(SamplingDecision.DROP);
1706+ + });
1707+ +
1708+ + // Verify /SamplingTargets was never called
1709+ + assertThat(samplingTargetsCallCount.get()).isEqualTo(0);
1710+ }
1711+
1712+ @Test
1713+ @@ -169,21 +210,28 @@ class AwsXrayRemoteSamplerTest {
16211714 }
16221715
16231716 @Test
@@ -1661,7 +1754,7 @@ index 4e5cd13b..5af11a25 100644
16611754 }
16621755 }
16631756
1664- @@ -206,6 +219 ,16 @@ class AwsXrayRemoteSamplerTest {
1757+ @@ -206,6 +254 ,16 @@ class AwsXrayRemoteSamplerTest {
16651758 }
16661759 }
16671760
@@ -3359,6 +3452,55 @@ index 00000000..4ba3013a
33593452+ "Version": 1,
33603453+ "Attributes": {}
33613454+ }
3455+ diff --git a/aws-xray/src/test/resources/test-sampling-rules-response-3.json b/aws-xray/src/test/resources/test-sampling-rules-response-3.json
3456+ new file mode 100644
3457+ index 00000000..8672b2e1
3458+ --- /dev/null
3459+ +++ b/aws-xray/src/test/resources/test-sampling-rules-response-3.json
3460+ @@ -0,0 +1,42 @@
3461+ + {
3462+ + "SamplingRuleRecords": [
3463+ + {
3464+ + "SamplingRule": {
3465+ + "RuleName": "Test",
3466+ + "RuleARN": "arn:aws:xray:us-east-1:595986152929:sampling-rule/Test",
3467+ + "ResourceARN": "*",
3468+ + "Priority": 1,
3469+ + "FixedRate": 0.0,
3470+ + "ReservoirSize": 0,
3471+ + "ServiceName": "*",
3472+ + "ServiceType": "*",
3473+ + "Host": "*",
3474+ + "HTTPMethod": "*",
3475+ + "URLPath": "*",
3476+ + "Version": 1,
3477+ + "Attributes": {}
3478+ + },
3479+ + "CreatedAt": "2021-06-18T17:28:15+09:00",
3480+ + "ModifiedAt": "2021-06-18T17:28:15+09:00"
3481+ + },
3482+ + {
3483+ + "SamplingRule": {
3484+ + "RuleName": "Default",
3485+ + "RuleARN": "arn:aws:xray:us-east-1:595986152929:sampling-rule/Default",
3486+ + "ResourceARN": "*",
3487+ + "Priority": 10000,
3488+ + "FixedRate": 1.0,
3489+ + "ReservoirSize": 1,
3490+ + "ServiceName": "*",
3491+ + "ServiceType": "*",
3492+ + "Host": "*",
3493+ + "HTTPMethod": "*",
3494+ + "URLPath": "*",
3495+ + "Version": 1,
3496+ + "Attributes": {}
3497+ + },
3498+ + "CreatedAt": "1970-01-01T09:00:00+09:00",
3499+ + "ModifiedAt": "1970-01-01T09:00:00+09:00"
3500+ + }
3501+ + ]
3502+ + }
3503+ \ No newline at end of file
33623504diff --git a/disk-buffering/build.gradle.kts b/disk-buffering/build.gradle.kts
33633505index 8250c1bd..74a1a24c 100644
33643506--- a/disk-buffering/build.gradle.kts
0 commit comments