Current state: "Accepted"
Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).
Concurrent thread may try to access the Metrics registry to create the same, instance-level metric, however it's get/create APIs are not well suited for it. A common pattern that users follow today is:
Here's an example on how the AK codebase uses the above pattern:
The above process basically consists of 2 steps:
- Check if a Metric of interest exists or not.
- If yes, an IllegalArgumentException would be thrown which could be due to race conditions as well. We might just want to catch this exception and swallow it - as long as the metric gets created.
- Else, create the metric.
The main motivation of this KIP is to expose an API which would make these operations atomic. That ways, users won't need to remember these steps and can just focus on having a metric created.
A new public facing method getMetricOrElseCreate would be exposed. This would create a non-existing metric or create a return the Metric if it already exists. This way, users don't need to add extra logic to take respective actions in case of presence/absence of metrics. Note that this method takes care of synchronisation while updating/accessing metrics by concurrent threads.
Adding a new function above to the Metrics API. As part of this change, the
registerMetricmethod's return type would be changed from
KafkaMetric. It would return a KafkaMetric object if the requested metric already exists or return null if not after creating/registering the metric. For backward compatibility reasons, any place currently which relied on
IllegalArgumentExceptionwould now instead check the output of
registerMetricand throw an
IllegalArguementExceptionwhen the returned value of
registerMetricis non-null. This change would happen in =>
Sensor.addmethods. On the other hand, getMetricOrElseCreate method would simply return the object returned by
registerMetric if not null.
Compatibility, Deprecation, and Migration Plan
The changes are backward compatible and needs no deprecation/migration.