KAFKA-15995: Initial API + make Producer/Consumer plugins Monitorable#17511
KAFKA-15995: Initial API + make Producer/Consumer plugins Monitorable#17511mimaison merged 3 commits intoapache:trunkfrom
Conversation
showuon
left a comment
There was a problem hiding this comment.
Thanks for the PR. Left some comments.
| @Override | ||
| public void close() throws Exception { | ||
| if (pluginMetrics.isPresent()) pluginMetrics.get().close(); | ||
| if (instance instanceof AutoCloseable) ((AutoCloseable) instance).close(); |
There was a problem hiding this comment.
In the KIP, we said:
The goal is allow this feature to be used by all plugins that are Closeable, AutoCloseable or have a close() methods.
But here, we only close if it's Closeable/AutoCloseable instance. Are we sure all the interfaces having close() method is Closeable/AutoCloseable?
There was a problem hiding this comment.
So far the only plugins that support this feature are all AutoCloseable. When we'll add support to plugin that don't implement Closeable/AutoCloseable, we'll need to adjust this method. But I think for now it's fine.
There was a problem hiding this comment.
If someday we missed the "new added plugin without AutoCloseable", it might cause the resource leak. I think we should either update the KIP and say "we only support plugins are Closeable, AutoCloseable", or we fix the issue here, with reflection or something else.
|
cc @tombentley @C0urante since you also voted on the KIP. Thanks |
|
I rebased on trunk to resolve the conflicts. |
|
Pinging @gharris1727 as you were also involved in the discussion thread. |
gharris1727
left a comment
There was a problem hiding this comment.
Thanks for the PR @mimaison!
|
|
||
| @Override | ||
| public void close() throws Exception { | ||
| if (pluginMetrics.isPresent()) pluginMetrics.get().close(); |
There was a problem hiding this comment.
Is there a way for the plugin metrics to throw on close? If so, the instance itself wouldn't get closed, leaking it.
I think propagating the exception from the actual instance close is a good idea.
There was a problem hiding this comment.
Yes I change the logic to capture exceptions thrown by the plugin or the PluginMetrics instance and rethrow the first one.
| } | ||
|
|
||
| @Override | ||
| public void close() throws Exception { |
There was a problem hiding this comment.
The close order here has some trade-offs.
If we close metrics first, the plugin close() method can't ever emit metrics. I can think of some useful examples that we should permit:
- is a close operation ongoing
- how many records were processed during the instance lifetime
- how long was the plugin open
- how long did operation X take during closing
Also if there are background threads within a plugin, those threads may want to emit metrics concurrent with the close() call. The close() call may leave that background thread running, intentionally or accidentally. I think that once the close() call completes, we can throw away any further metrics from the plugin, making all of the calls no-ops, or maybe throw exceptions if we want to be harsh.
If we close the plugin first, the MetricValueProvider interface may have an undefined value during and after closing. If the plugin needs to be open in order to provide real data, they MetricValueProvider instance may throw an exception, or provide junk or stale data.
I think we should close the plugin first, and mention that the MetricValueProviders may be called at any time, including after the metric is removed or the plugin is closed.
There was a problem hiding this comment.
That's a good point! And thanks for taking the time to consider the alternatives and suggest solutions.
I agree that the plugin instance should be closed first. This allows the plugin close() method to update metrics. Also when closing the PluginMetrics instance afterwards, this allows to "lock" it as in theory it should not receive further calls.
I've opted to use Utils.closeQuietly() so we can capture if any of the plugin or PluginMetrics instance fail closing.
|
Rebased to resolve the conflicts. |
| private final Metrics metrics; | ||
| private final Map<String, String> tags; | ||
| private final Set<MetricName> metricNames = new HashSet<>(); | ||
| private final Set<String> sensors = new HashSet<>(); | ||
| private boolean closing = false; |
There was a problem hiding this comment.
I think that this implementation should be thread-safe, at minimum the closing variable should be volatile, but maybe the Sets need to be thread-safe as well.
There was a problem hiding this comment.
Thanks for the review, I pushed an update.
|
@showuon @gharris1727 Thanks for the reviews! Can you take another look? |
|
@mimaison I don't have any more comments, I think i'm ready to approve this. Can you check the build failures? I've rerun it several times and the ClientUtilsTest seems to be consistently failing, but i'm not sure how your changes could be causing it. |
|
I think that ClientUtilsTest issue has been fixed in #18549. |
|
We still have a bunch of failures in the CI but these all look unrelated to this PR. |
gharris1727
left a comment
There was a problem hiding this comment.
LGTM.
I was having pretty good luck earlier this month with green builds, so builds seem less reliable than usual. We can merge and monitor trunk, unblocking the next PR.
Thanks @mimaison for the KIP and implementation! So happy to see this change.
…apache#17511) Reviewers: Greg Harris <gharris1727@gmail.com>, Luke Chen <showuon@gmail.com>
…apache#17511) Reviewers: Greg Harris <gharris1727@gmail.com>, Luke Chen <showuon@gmail.com>
First part of KIP-877.
This adds the public APIs and enables the following plugins:
which are all the Producer and Consumer specific plugins.
Committer Checklist (excluded from commit message)