-
Notifications
You must be signed in to change notification settings - Fork 15.1k
KAFKA-16047: Leverage the fenceProducers timeout in the InitProducerId #15078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| */ | ||
| package org.apache.kafka.clients.admin.internals; | ||
|
|
||
| import org.apache.kafka.clients.admin.FenceProducersOptions; | ||
| import org.apache.kafka.common.Node; | ||
| import org.apache.kafka.common.errors.ClusterAuthorizationException; | ||
| import org.apache.kafka.common.errors.TransactionalIdAuthorizationException; | ||
|
|
@@ -38,12 +39,15 @@ | |
| public class FenceProducersHandler extends AdminApiHandler.Unbatched<CoordinatorKey, ProducerIdAndEpoch> { | ||
| private final Logger log; | ||
| private final AdminApiLookupStrategy<CoordinatorKey> lookupStrategy; | ||
| private final FenceProducersOptions options; | ||
|
|
||
| public FenceProducersHandler( | ||
| FenceProducersOptions options, | ||
| LogContext logContext | ||
| ) { | ||
| this.log = logContext.logger(FenceProducersHandler.class); | ||
| this.lookupStrategy = new CoordinatorStrategy(FindCoordinatorRequest.CoordinatorType.TRANSACTION, logContext); | ||
| this.options = options; | ||
| } | ||
|
|
||
| public static AdminApiFuture.SimpleAdminApiFuture<CoordinatorKey, ProducerIdAndEpoch> newFuture( | ||
|
|
@@ -82,9 +86,10 @@ InitProducerIdRequest.Builder buildSingleRequest(int brokerId, CoordinatorKey ke | |
| .setProducerEpoch(ProducerIdAndEpoch.NONE.epoch) | ||
| .setProducerId(ProducerIdAndEpoch.NONE.producerId) | ||
| .setTransactionalId(key.idValue) | ||
| // Set transaction timeout to 1 since it's only being initialized to fence out older producers with the same transactional ID, | ||
| // and shouldn't be used for any actual record writes | ||
| .setTransactionTimeoutMs(1); | ||
| // Set transaction timeout to the equivalent as the fenceProducers request since it's only being initialized to fence out older producers with the same transactional ID, | ||
| // and shouldn't be used for any actual record writes. This has been changed to match the fenceProducers request timeout from one as some brokers may be slower than expected | ||
| // and we need a safe timeout that allows the transaction init to finish. | ||
| .setTransactionTimeoutMs(this.options.timeoutMs()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The timeoutMs is nullable, and is always null when using the default FenceProducersOptions.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please recheck @gharris1727 ? 🙏 |
||
| return new InitProducerIdRequest.Builder(data); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7031,6 +7031,7 @@ public void testFenceProducers() throws Exception { | |
| try (AdminClientUnitTestEnv env = mockClientEnv()) { | ||
| String transactionalId = "copyCat"; | ||
| Node transactionCoordinator = env.cluster().nodes().iterator().next(); | ||
| final FenceProducersOptions options = new FenceProducersOptions().timeoutMs(10000); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't test the null-default case which is going to be more common, and doesn't seem necessary for the correctness of the test either. I think instead, we should change the |
||
|
|
||
| // fail to find the coordinator at first with a retriable error | ||
| env.kafkaClient().prepareResponse(prepareFindCoordinatorResponse(Errors.COORDINATOR_NOT_AVAILABLE, transactionalId, transactionCoordinator)); | ||
|
|
@@ -7060,7 +7061,7 @@ public void testFenceProducers() throws Exception { | |
| transactionCoordinator | ||
| ); | ||
|
|
||
| FenceProducersResult result = env.adminClient().fenceProducers(Collections.singleton(transactionalId)); | ||
| FenceProducersResult result = env.adminClient().fenceProducers(Collections.singleton(transactionalId), options); | ||
| assertNull(result.all().get()); | ||
| assertEquals(4761, result.producerId(transactionalId).get()); | ||
| assertEquals((short) 489, result.epochId(transactionalId).get()); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's best if we don't mutate the options if the user passed it in. If someone were to log the options somewhere else, they would see our injected default instead of the fact that no value was provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the good comment.
The main reason i mutated the options was to pass the same timeout value in both the
FenceProducersHandlerand in theinvokeDriver.I just noticed that this is already true as the calcDeadlineMs that is used by the
invokeDriveris already returning thedefaultApiTimeoutMsin the case of null timeout.