stevenschlansker commented on code in PR #18771: URL: https://github.com/apache/kafka/pull/18771#discussion_r1938120110
########## streams/src/main/java/org/apache/kafka/streams/state/internals/MeteredKeyValueStore.java: ########## @@ -156,11 +156,8 @@ private void registerMetrics() { (config, now) -> numOpenIterators.sum()); StateStoreMetrics.addOldestOpenIteratorGauge(taskId.toString(), metricsScope, name(), streamsMetrics, (config, now) -> { - try { - return openIterators.isEmpty() ? null : openIterators.first().startTimestamp(); - } catch (final NoSuchElementException ignored) { - return null; - } + final Iterator<MeteredIterator> openIteratorsIterator = openIterators.iterator(); + return openIteratorsIterator.hasNext() ? openIteratorsIterator.next().startTimestamp() : null; Review Comment: Thanks for considering this PR @mjsax . I admit I do not have too much experience with `ConcurrentSkipListSet` (and the `ConcurrentSkipListMap` underlying it), but they promise: > Iterators and spliterators are weakly consistent. where weakly consistent is defined: > Most concurrent Collection implementations (including most Queues) also differ from the usual java.util conventions in that their Iterators and Spliterators provide weakly consistent rather than fast-fail traversal: > they may proceed concurrently with other operations > they will never throw ConcurrentModificationException > they are guaranteed to traverse elements as they existed upon construction exactly once, and may (but are not guaranteed to) reflect any modifications subsequent to construction. I take this to mean that by taking a single `openIterators.iterator()` we then get a weakly consistent handle on the structure, and will either observe an element or not, but such an iterator should never run into the case where `hasNext()` returns `true` but then `next()` throws (which would not be "consistent" to me). I admit the docs stating "they may proceed concurrently with other operations" "won't throw CME" isn't 100% clear on this point about the slightly different NoSuchElementException. Assuming my analysis is correct, this is an improvement because the old code `isEmpty() + first()` is taking two "weak snapshots" of the data structure that are not consistent, but `iterator() { hasNext() + next() }` takes a single weak snapshot. If this isn't sufficiently convincing, I'm fine to drop this PR and move on with life :) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: jira-unsubscr...@kafka.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org