KAFKA-13846: Adding overloaded addMetricIfAbsent method#12121
KAFKA-13846: Adding overloaded addMetricIfAbsent method#12121guozhangwang merged 8 commits intoapache:trunkfrom
Conversation
clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Would it be useful to know if the metric is created vs. already existed?
There was a problem hiding this comment.
Yeah currently, metricOrElseCreate hides that fact. I can add a log line here is needed. Also, I guess the addMetric method(s) already can be used to answer the created v/s already existed question.
There was a problem hiding this comment.
@jolshan I added a log line for the case where there's no exception to be thrown.
There was a problem hiding this comment.
I am wonder if this change is really necessary. Is it?
There was a problem hiding this comment.
Hey @vamossagar12 @jolshan @dajac , since registerMetric is a package private function I'm thinking about modifying its signature to return the already existed metric (null if it does not exist, not null means no changes to the underlying registry since there's already a metric), hence indicating if the register-metric succeeded or not. And let the caller (addMetric or metricOrElseCreate) to react accordingly: e.g. the former would still throw exception if it gets a non-null return value, while the latter just returns the metric. WDYT?
There was a problem hiding this comment.
@guozhangwang i think yeah that could be done. I have made the changes.
There was a problem hiding this comment.
registerMetric is also called from the Sensor class so we have to check if that works there as well.
There was a problem hiding this comment.
There were a couple of test failures because of this usage. I updated the code to throw an IllegalArgumentException for backward compatibility reasons.
|
I was also wondering -- is this file (clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java) considered part of the public apis? |
I am not sure of that.. @guozhangwang can answer that probably.. |
@jolshan my guess is it is. But i am not 100% sure. |
|
@guozhangwang , could you plz review this whenever you get the chance? |
dajac
left a comment
There was a problem hiding this comment.
Thanks for the PR. I left a few comments.
From a public API point of view, Metrics is in a gray area. It is not officially part of our public API however we have a few interfaces leaking it. That being said, we should be careful with the changes that we do here.
There was a problem hiding this comment.
I wonder if we really need all these overloads. Do we have use cases for all of them? I have the impression that the last one would be sufficient.
There was a problem hiding this comment.
I removed the other 2. I had added them to be at par with the addMetric method and it's overloads.
clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
I am wonder if this change is really necessary. Is it?
Thank you for the review. Just wanted to know if it's a public API, does it mean we need a KIP for this? And I totally agree with being careful. |
guozhangwang
left a comment
There was a problem hiding this comment.
@vamossagar12 Thanks for the PR! I left a couple comments, aiming to make the newly added function to be atomic with just a single operation on the underlying registry.
There was a problem hiding this comment.
Hey @vamossagar12 @jolshan @dajac , since registerMetric is a package private function I'm thinking about modifying its signature to return the already existed metric (null if it does not exist, not null means no changes to the underlying registry since there's already a metric), hence indicating if the register-metric succeeded or not. And let the caller (addMetric or metricOrElseCreate) to react accordingly: e.g. the former would still throw exception if it gets a non-null return value, while the latter just returns the metric. WDYT?
clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java
Outdated
Show resolved
Hide resolved
I agree with @dajac as well, what I was thinking is that we can modify the private |
Sure thing... Even I am neutral about KIP. |
|
|
|
Do we also have concrete examples of usages of this new API? It would be helpful to update one or two metrics which would benefits from this change. This would be a good illustration. |
guozhangwang
left a comment
There was a problem hiding this comment.
Do we also have concrete examples of usages of this new API? It would be helpful to update one or two metrics which would benefits from this change. This would be a good illustration.
Yes, there are quite many places where multiple threads tried to create the same metric and has to follow the pattern I described in the JIRA ticket. If we just search for the usage of the metric(metricName) function, we can found a bunch of them, e.g. in Fetcher, ConnectMetrics, TaskMetricsGroup, etc.
Metrics is actually published in our javadoc. This suggests that changing it would require a KIP, no?
Sounds good. Let's create a tiny KIP to add the function.
There was a problem hiding this comment.
nit: maybeMetric => existingMetric?
clients/src/main/java/org/apache/kafka/common/metrics/Metrics.java
Outdated
Show resolved
Hide resolved
Sure. I made following updates in ConnectMetrics: Note that, IlegalArguementExeception is still possible through metricName() method so I didn't remove that from the javadoc. Also, I created a small KIP for the same: https://cwiki.apache.org/confluence/display/KAFKA/KIP-843%3A+Adding+metricOrElseCreate+method+to+Metrics |
|
@dajac , @guozhangwang The KIP has been approved. Also, as per one of the suggestions on the KIP, metricOrElseCreate has been renamed to getMetricOrElseCreate. |
Thanks! Let's wait and see what people like as the final name of the function :) |
Makes sense. :) |
…ception for backward compatibility. Also, replaced addMetric with metricOrElseCreate in ConnectMetrics for illustrative purposes
|
@guozhangwang/ @dajac I have updated the name of the function now. I sent out a note 2-3 days ago and didn't notice any resistance. Plz review |
|
@vamossagar12 could you close the VOTE thread before we can review and merge? |
|
@guozhangwang done. |
guozhangwang
left a comment
There was a problem hiding this comment.
LGTM! @vamossagar12 could you file a follow-up PR that update the web docs on 3.3 release new API changes, as well as a couple of nit comments above?
| config == null ? this.config : config, | ||
| time); | ||
| registerMetric(m); | ||
| KafkaMetric existingMetric = registerMetric(m); |
There was a problem hiding this comment.
Could we clarify in the javadoc above that if the metric already exists, an exception would be thrown?
| * When a metric is newly registered, this method returns null | ||
| * | ||
| * @param metric The KafkaMetric to register | ||
| * @return KafkaMetric if the metric already exists, null otherwise |
There was a problem hiding this comment.
nit: we can just say "the existing metric with the same name"
|
The PR title and commit title seem wrong since the method we introduced is not |
| MetricName metricName = metric.metricName(); | ||
| if (this.metrics.containsKey(metricName)) | ||
| throw new IllegalArgumentException("A metric named '" + metricName + "' already exists, can't register another one."); | ||
| if (this.metrics.containsKey(metricName)) { |
There was a problem hiding this comment.
It's not efficient to do contains and then get. We should do the get and check if the result is null. That halves the cost of the operations.
There was a problem hiding this comment.
Or even better, call putIfAbsent, if available.
CONFLUENT: Sync from apache/kafka trunk to confluentinc/kafka master (13 Jun 2022) apache/trunk: (7 commits) KAFKA-13891: reset generation when syncgroup failed with REBALANCE_IN…(apache#12140) KAFKA-10000: Exactly-once source tasks (apache#11780) KAFKA-13436: Omitted BrokerTopicMetrics metrics in the documentation (apache#11473) MINOR: Use Exit.addShutdownHook instead of directly adding hooks to R…(apache#12283) KAFKA-13846: Adding overloaded metricOrElseCreate method (apache#12121) KAFKA-13935 Fix static usages of IBP in KRaft mode (apache#12250) HOTFIX: null check keys of ProducerRecord when computing sizeInBytes (apache#12288) Conflicts: None
|
@ijuma ., i updated the PR name. Also, created a follow up PR to address some of the comments: #12297 |
Here: https://github.com/apache/kafka/blob/trunk/docs/upgrade.html. You can find earlier PRs how they update the upgrade guide / API changes in upcoming releases. |
More detailed description of your change,
if necessary. The PR title and PR message become
the squashed commit message, so use a separate
comment to ping reviewers.
Summary of testing strategy (including rationale)
for the feature or bug fix. Unit and/or integration
tests are expected for any behaviour change and
system tests should be considered for larger changes.
Committer Checklist (excluded from commit message)