Skip to content

Commit 17aa757

Browse files
committed
Adding a test for low-resolution clock.
1 parent 03104e7 commit 17aa757

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

consistent-sampling/src/main/java/io/opentelemetry/contrib/sampler/consistent56/ConsistentRateLimitingSampler.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,23 +187,26 @@ private static double determineProbabilitySmoothingFactor(
187187
}
188188

189189
private State updateState(State oldState, long currentNanoTime, double delegateProbability) {
190-
if (currentNanoTime <= oldState.lastNanoTime) {
190+
double currentAverageProbability =
191+
oldState.effectiveDelegateProbability * (1.0 - probabilitySmoothingFactor)
192+
+ delegateProbability * probabilitySmoothingFactor;
193+
194+
long nanoTimeDelta = currentNanoTime - oldState.lastNanoTime;
195+
if (nanoTimeDelta <= 0.0) {
196+
// Low clock resolution or clock jumping backwards.
197+
// Assume time delta equal to zero.
191198
return new State(
192199
oldState.effectiveWindowCount + 1,
193200
oldState.effectiveWindowNanos,
194201
oldState.lastNanoTime,
195-
oldState.effectiveDelegateProbability);
202+
currentAverageProbability);
196203
}
197-
long nanoTimeDelta = currentNanoTime - oldState.lastNanoTime;
204+
198205
double decayFactor = Math.exp(-nanoTimeDelta * inverseAdaptationTimeNanos);
199206
double currentEffectiveWindowCount = oldState.effectiveWindowCount * decayFactor + 1;
200207
double currentEffectiveWindowNanos =
201208
oldState.effectiveWindowNanos * decayFactor + nanoTimeDelta;
202209

203-
double currentAverageProbability =
204-
oldState.effectiveDelegateProbability * (1.0 - probabilitySmoothingFactor)
205-
+ delegateProbability * probabilitySmoothingFactor;
206-
207210
return new State(
208211
currentEffectiveWindowCount,
209212
currentEffectiveWindowNanos,

consistent-sampling/src/test/java/io/opentelemetry/contrib/sampler/consistent56/ConsistentRateLimitingSamplerTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ConsistentRateLimitingSamplerTest {
2929

3030
private long[] nanoTime;
3131
private LongSupplier nanoTimeSupplier;
32+
private LongSupplier lowResolutionTimeSupplier;
3233
private Context parentContext;
3334
private String name;
3435
private SpanKind spanKind;
@@ -40,6 +41,7 @@ class ConsistentRateLimitingSamplerTest {
4041
void init() {
4142
nanoTime = new long[] {0L};
4243
nanoTimeSupplier = () -> nanoTime[0];
44+
lowResolutionTimeSupplier = () -> (nanoTime[0] / 1000000) * 1000000; // 1ms resolution
4345
parentContext = Context.root();
4446
name = "name";
4547
spanKind = SpanKind.SERVER;
@@ -97,6 +99,47 @@ void testConstantRate() {
9799
.isCloseTo(targetSpansPerSecondLimit, Percentage.withPercentage(5));
98100
}
99101

102+
@Test
103+
void testConstantRateLowResolution() {
104+
105+
double targetSpansPerSecondLimit = 1000;
106+
double adaptationTimeSeconds = 5;
107+
108+
ComposableSampler delegate =
109+
new CoinFlipSampler(ConsistentSampler.alwaysOff(), ConsistentSampler.probabilityBased(0.8));
110+
ConsistentSampler sampler =
111+
ConsistentSampler.rateLimited(
112+
delegate, targetSpansPerSecondLimit, adaptationTimeSeconds, lowResolutionTimeSupplier);
113+
114+
long nanosBetweenSpans = TimeUnit.MICROSECONDS.toNanos(100);
115+
int numSpans = 1000000;
116+
117+
List<Long> spanSampledNanos = new ArrayList<>();
118+
119+
for (int i = 0; i < numSpans; ++i) {
120+
advanceTime(nanosBetweenSpans);
121+
SamplingResult samplingResult =
122+
sampler.shouldSample(
123+
parentContext,
124+
generateRandomTraceId(random),
125+
name,
126+
spanKind,
127+
attributes,
128+
parentLinks);
129+
if (SamplingDecision.RECORD_AND_SAMPLE.equals(samplingResult.getDecision())) {
130+
spanSampledNanos.add(getCurrentTimeNanos());
131+
}
132+
}
133+
134+
long numSampledSpansInLast5Seconds =
135+
spanSampledNanos.stream()
136+
.filter(x -> x > TimeUnit.SECONDS.toNanos(95) && x <= TimeUnit.SECONDS.toNanos(100))
137+
.count();
138+
139+
assertThat(numSampledSpansInLast5Seconds / 5.)
140+
.isCloseTo(targetSpansPerSecondLimit, Percentage.withPercentage(5));
141+
}
142+
100143
@Test
101144
void testRateIncrease() {
102145

0 commit comments

Comments
 (0)