KAFKA-9434: automated protocol for alterReplicaLogDirs#8311
Conversation
|
@mimaison would you be able to review this one? |
e154815 to
7658599
Compare
7658599 to
3c32ac4
Compare
|
Rebased for conflict. |
3c32ac4 to
b1584aa
Compare
|
Rebased for conflict. |
dajac
left a comment
There was a problem hiding this comment.
@tombentley Thanks for the PR. I have made a pass over it and I have left couple of comments.
There was a problem hiding this comment.
While we are refactoring this, could we add a unit test in KafkaApisTest?
a6d1e17 to
4cb5e42
Compare
|
@dajac thanks for the review, I've addressed all your comments. |
dajac
left a comment
There was a problem hiding this comment.
@tombentley Thanks for the updated PR. The overall logic looks good to me. I have left a bunch of small comments.
There was a problem hiding this comment.
nit: Could we rename value to something like alterReplicaLogDirs?
There was a problem hiding this comment.
Could we add a unit test for this one and the one bellow?
There was a problem hiding this comment.
Could we add a unit test for this one?
|
Thanks @dajac, there were some useful comments and good spots there. I've pushed some fixes. |
dajac
left a comment
There was a problem hiding this comment.
@tombentley Thanks for the updated PR. It looks good overall. I have left few more small comments and one question.
There was a problem hiding this comment.
assertNulls shouldn't be here but few lines bellow.
There was a problem hiding this comment.
Good catch! Sorry about that.
There was a problem hiding this comment.
@tombentley This one bugs me. I know that it was already like this in the previous implementation but I wonder if we could improve this while we are here. I am also fine keeping it as it is and improving this latter on.
I find odd that we fail all the non-realised yet futures when we discover an unknown replica in the response. From a client perspective, the behaviour is unpredictable and we leave it with potentially a partial view of the results event though the brokers may have sent back all the requested ones. Wouldn't it be better to just ignore unexpected replica and log a warning message? If a broker would ever do this, the client would continue to work as expected which is probably better. I think that it is a better behavior.
Similarly, we may want to ensure that all futures are done in case a replica would be missing in the response from the broker.
What do you think?
There was a problem hiding this comment.
Do you mind adding a unit test for this one in AlterReplicaLogDirsRequestTest for the sake of completeness?
e323868 to
1dffaa9
Compare
|
Rebased for conflict. @dajac thanks for the review. I agree about the case of the unexpected partition. The only way it could happen would be a bug in either the client or the broker, but there's no need to force that onto the user to handle. A warning log should be enough for the bug to be reported eventually. So I've made this change. About the case of the client not getting a response for a partition: I agree that could happen (again, as a bug in the broker or client). It would be a bit harder to detect though; we'd be spending CPU cycles to detect and log a case which we don't think will ever happen in practice. Maybe that's OK since altering log dirs not something done frequently. But it strikes me that there are plenty of other RPCs in the admin client that don't do this kind of second-guessing of the results. If we're prepared to go to that effort here, why not elsewhere? So personally, I think it would OK to omit this check, but I can do it if you really think it should be done. |
|
@tombentley Did you consider adding a loop in at the end of the You're right. We have few other cases in the Admin client that suffer from the same issue. If we can find an easy way to do it, I would rather prefer doing it in this PR so we can forget about it. I will try to fix some of the others myself. |
|
@dajac yes, fair point. And I notice now that create and delete topics response handlers are already doing this (though the error messages in those cases don't really make much sense). So I've added this with a slightly reworded message. |
|
@tombentley thanks for the addition. we could perhaps add a small unit test for the sake of completeness. we already cover all the other cases but this one. |
|
@dajac sure. I added tests for the create and delete topics cases too. |
dajac
left a comment
There was a problem hiding this comment.
@tombentley Thanks for the update! LGTM. I just left small cosmetic comments.
| if (!future.isDone() | ||
| && replica.brokerId() == brokerId) { |
There was a problem hiding this comment.
nit: i would bring the second part on the first line.
| /** | ||
| * Fail the given future when a response handler expected a result for an entity but no result was present. | ||
| * @param future The future to fail. | ||
| * @param message The message to fail the future with |
There was a problem hiding this comment.
nit: . at the end to stay consistent with previous line.
| * @param future The future to fail. | ||
| * @param message The message to fail the future with | ||
| */ | ||
| private void partialResponse(KafkaFutureImpl<?> future, String message) { |
There was a problem hiding this comment.
I am not entirely convinced by the name. At the end, the method complete a future with the given message. There is nothing specific to handling partial responses. I would rename it to something more generic or simply remove it as we don't gain much with it.
There was a problem hiding this comment.
I agree it's not doing much. What value it has is in trying to handle these cases in a consistent way, and being able to more easily discover/reason about the call sites. Maybe something like invalidBrokerResponse() would be a better name? But if you don't like that I'm happy to remove it.
There was a problem hiding this comment.
I see your point. I am definitely for reusing logic as much as possible for those cases. What about going an extra step and do something like this then (code not tested)? Just an idea...
public static <K, V> void completeUnrealizedFutures(
Map<K, KafkaFutureImpl<V>> futures,
Function<K, Boolean> filter,
Function<K, String> messageFormatter) {
for (Map.Entry<K, KafkaFutureImpl<V>> entry : futures.entrySet()) {
K key = entry.getKey();
KafkaFutureImpl<V> future = entry.getValue();
if (!future.isDone() && filter.apply(key)) {
future.completeExceptionally(new ApiException(messageFormatter.apply(key)));
}
}
}
public static <K, V> void completeUnrealizedFutures(
Map<K, KafkaFutureImpl<V>> futures,
unction<K, String> messageFormatter) {
completeUnrealizedFutures(futures, (key) -> true, messageFormatter);
}
It would allow the following:
completeUnrealizedFutures(topicFutures,
replica -> replica.brokerId() == brokerId,
topic -> "The response from broker " + brokerId + " did not contain a result for replica " + replica);
completeUnrealizedFutures(topicFutures,
topic -> "The server response did not contain a reference to node " + topic);
There was a problem hiding this comment.
That works for me, especially if this is something you're going to make more use of for the other response handlers in the admin client.
dajac
left a comment
There was a problem hiding this comment.
@tombentley Thanks for the update. The PR LGTM! I just left few cosmetic comments.
| } | ||
| completeUnrealizedFutures(topicFutures, | ||
| topic -> "The controller response " + | ||
| "did not contain a result for topic " + topic); |
There was a problem hiding this comment.
nit: we can bring this back on the first line.
| } | ||
| completeUnrealizedFutures(topicFutures, | ||
| topic -> "The controller response " + | ||
| "did not contain a result for topic " + topic); |
There was a problem hiding this comment.
nit: we can bring this back on the first line.
| future.completeExceptionally(error.exception()); | ||
| for (AlterReplicaLogDirTopicResult topicResult: response.data().results()) { | ||
| for (AlterReplicaLogDirPartitionResult partitionResult: topicResult.partitions()) { | ||
| TopicPartitionReplica replica = new TopicPartitionReplica(topicResult.topicName(), partitionResult.partitionIndex(), brokerId); |
There was a problem hiding this comment.
nit: We could break this long line.
|
@dajac I fixed those, and also changed the |
|
@tombentley thanks! |
|
ok to test |
|
retest this please |
| try { | ||
| topicsResult.values().get("myTopic2").get(); | ||
| fail("Expected an exception."); | ||
| } catch (ExecutionException e) { |
There was a problem hiding this comment.
We can use assertThrows() here. Same below
There was a problem hiding this comment.
I don't think we can, at least not if we want to check that topicsResult.values().get("myTopic2").get() throws an ExecutionException wrapping an ApiException. assertThrows() would only let us assert the outer exception type.
There was a problem hiding this comment.
Sorry, I meant TestUtils.assertFutureThrows()
There was a problem hiding this comment.
Ah, thanks! Now fixed.
| topicResult.topicName(), partitionResult.partitionIndex(), brokerId); | ||
| KafkaFutureImpl<Void> future = futures.get(replica); | ||
| if (future == null) { | ||
| log.warn("The partition {} in the response from broker {}} is not in the request", |
|
Thanks @tombentley for the PR. It looks good. Happy to merge once the last 2 comments are addressed |
|
retest this please |
|
@mimaison done. |
|
retest this please |
* 'trunk' of github.com:apache/kafka: (46 commits) MINOR: improve code encapsulation between StreamThread and TaskManager (apache#8819) Fixing KAFKA-10094 (apache#8797) KAFKA-9851: Revoking Connect tasks due to connectivity issues should also clear the running assignment (apache#8804) KAFKA-9840; Skip End Offset validation when the leader epoch is not reliable (apache#8486) HOT_FIX: Update javadoc since imports added (apache#8817) KAFKA-8011: Fix flaky RegexSourceIntegrationTest (apache#8799) KAFKA-9570: Define SSL configs in all worker config classes, not just distributed (apache#8135) KAFKA-10111: Make SinkTaskContext.errantRecordReporter() a default method (apache#8814) KAFKA-10110: Corrected potential NPE when null label value added to KafkaMetricsContext (apache#8811) MINOR: Change the order that Connect calls `config()` and `validate()` to avoid validating if the required ConfigDef is null (apache#8810) MINOR: fix backwards incompatibility in JmxReporter introduced by KIP-606 MINOR: Fix javadoc warnings (apache#8809) KAFKA-9441: Improve Kafka Streams task management (apache#8776) fix the broken links of streams javadoc (apache#8789) KAFKA-10040; Make computing the PreferredReplicaImbalanceCount metric more efficient (apache#8724) KAFKA-10066: TestOutputTopic should pass record headers into deserializers (apache#8759) MINOR: Add explanation for disabling forwarding from value transformers (apache#8771) KAFKA-10033: Throw UnknownTopicOrPartitionException if altering configs of non-existing topic KAFKA-9434: automated protocol for alterReplicaLogDirs (apache#8311) KAFKA-9313: Set `use_all_dns_ips` as the new default for `client.dns.lookup` (KIP-602) (apache#8644) ...
Change the alterReplicaLogDirs request and response to use the generated protocol messages.
Committer Checklist (excluded from commit message)