Skip to content

Commit bbe8f91

Browse files
author
dino2895
committed
KAFKA-20796: Fix open iterator metric for timestamped range queries
1 parent 1720948 commit bbe8f91

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

streams/src/main/java/org/apache/kafka/streams/state/internals/MeteredTimestampedKeyValueStore.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ private MeteredTimestampedKeyValueStoreIterator(final KeyValueIterator<Bytes, by
318318
this.startNs = time.nanoseconds();
319319
this.startTimestampMs = time.milliseconds();
320320
this.returnPlainValue = returnPlainValue;
321+
numOpenIterators.increment();
321322
openIterators.add(this);
322323
}
323324

@@ -351,6 +352,7 @@ public void close() {
351352
final long duration = time.nanoseconds() - startNs;
352353
sensor.record(duration);
353354
iteratorDurationSensor.record(duration);
355+
numOpenIterators.decrement();
354356
openIterators.remove(this);
355357
}
356358
}

streams/src/test/java/org/apache/kafka/streams/state/internals/MeteredTimestampedKeyValueStoreTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
import org.apache.kafka.streams.processor.internals.InternalProcessorContext;
3838
import org.apache.kafka.streams.processor.internals.ProcessorStateManager;
3939
import org.apache.kafka.streams.processor.internals.metrics.StreamsMetricsImpl;
40+
import org.apache.kafka.streams.query.PositionBound;
41+
import org.apache.kafka.streams.query.Query;
42+
import org.apache.kafka.streams.query.QueryConfig;
43+
import org.apache.kafka.streams.query.QueryResult;
44+
import org.apache.kafka.streams.query.RangeQuery;
45+
import org.apache.kafka.streams.query.TimestampedRangeQuery;
4046
import org.apache.kafka.streams.state.KeyValueIterator;
4147
import org.apache.kafka.streams.state.KeyValueStore;
4248
import org.apache.kafka.streams.state.ValueAndTimestamp;
@@ -451,6 +457,56 @@ public void shouldTrackOpenIteratorsMetric() {
451457
assertThat((Long) openIteratorsMetric.metricValue(), equalTo(0L));
452458
}
453459

460+
@Test
461+
public void shouldTrackOpenIteratorsMetricForRangeQuery() {
462+
assertTracksOpenIteratorsMetricForQuery(
463+
RangeQuery.<String, String>withNoBounds()
464+
);
465+
}
466+
467+
@Test
468+
public void shouldTrackOpenIteratorsMetricForTimestampedRangeQuery() {
469+
assertTracksOpenIteratorsMetricForQuery(
470+
TimestampedRangeQuery.<String, String>withNoBounds()
471+
);
472+
}
473+
474+
@SuppressWarnings({"rawtypes", "unchecked"})
475+
private void assertTracksOpenIteratorsMetricForQuery(final Query<?> query) {
476+
setUp();
477+
478+
final QueryResult<KeyValueIterator<Bytes, byte[]>> rawResult =
479+
QueryResult.forResult(KeyValueIterators.emptyIterator());
480+
481+
when(inner.query(
482+
any(),
483+
any(PositionBound.class),
484+
any(QueryConfig.class)
485+
)).thenReturn((QueryResult) rawResult);
486+
487+
init();
488+
489+
final KafkaMetric openIteratorsMetric = metric("num-open-iterators");
490+
assertThat(openIteratorsMetric, not(nullValue()));
491+
assertThat((Long) openIteratorsMetric.metricValue(), equalTo(0L));
492+
493+
final QueryResult<?> result = metered.query(
494+
query,
495+
PositionBound.unbounded(),
496+
new QueryConfig(false)
497+
);
498+
499+
assertTrue(result.isSuccess());
500+
501+
try (final KeyValueIterator<?, ?> unused =
502+
(KeyValueIterator<?, ?>) result.getResult()) {
503+
assertThat((Long) openIteratorsMetric.metricValue(), equalTo(1L));
504+
}
505+
506+
assertThat((Long) openIteratorsMetric.metricValue(), equalTo(0L));
507+
}
508+
509+
454510
@SuppressWarnings("unused")
455511
@Test
456512
public void shouldTimeIteratorDuration() {

0 commit comments

Comments
 (0)