Skip to content

KAFKA-20443: Move RequestChannel Requests to server module#22075

Merged
chia7712 merged 5 commits into
apache:trunkfrom
mimaison:kafka-20443
May 15, 2026
Merged

KAFKA-20443: Move RequestChannel Requests to server module#22075
chia7712 merged 5 commits into
apache:trunkfrom
mimaison:kafka-20443

Conversation

@mimaison

@mimaison mimaison commented Apr 16, 2026

Copy link
Copy Markdown
Member

Rewrite in Java and move to server module

Reviewers: Ken Huang s7133700@gmail.com, Chia-Ping Tsai
chia7712@gmail.com

@mimaison mimaison marked this pull request as ready for review April 16, 2026 11:43
@github-actions github-actions Bot added core Kafka Broker performance labels Apr 16, 2026

@m1a2st m1a2st left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this patch, one nit comment

buffer,
requestChannelMetrics,
Some(envelope)
Optional.ofNullable(envelope)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Optional.of() is preferable to Optional.ofNullable(), since envelope should never be null.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, not need for ofNullable() here. Updated, thanks

@mimaison mimaison force-pushed the kafka-20443 branch 2 times, most recently from 72ed87e to 65e8328 Compare April 21, 2026 16:05

@m1a2st m1a2st left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM

@mimaison mimaison force-pushed the kafka-20443 branch 2 times, most recently from 0a753b4 to d9cac70 Compare May 7, 2026 09:12
@mimaison

mimaison commented May 7, 2026

Copy link
Copy Markdown
Member Author

@showuon can you take a look?

@chia7712 chia7712 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mimaison thanks for this rewrite!


private volatile OptionalLong callbackRequestDequeueTimeNanos = OptionalLong.empty();
private volatile OptionalLong callbackRequestCompleteTimeNanos = OptionalLong.empty();
private volatile Optional<Consumer<Long>> recordNetworkThreadTimeCallback = Optional.empty();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private volatile LongConsumer recordNetworkThreadTimeCallback = __ -> {};

import java.util.Objects;
import java.util.function.Consumer;

public final class CallbackRequest implements BaseRequest {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like a good candidate for a record class. WDYT?

* to the nearest long.
*/
private static double nanosToMs(long nanos) {
long positiveNanos = Math.max(nanos, 0);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    private static double nanosToMs(long nanos) {
        return (double) TimeUnit.NANOSECONDS.toMicros(nanos) / 1000.0;
    }

*/
package org.apache.kafka.network;

public final class ShutdownRequest implements BaseRequest {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public enum ShutdownRequest implements BaseRequest { 
    INSTANCE; 
}

*/
package org.apache.kafka.network;

public final class WakeupRequest implements BaseRequest {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@mimaison

Copy link
Copy Markdown
Member Author

Thanks @chia7712 for the review. All your suggestions made sense, so I applied them all.

@chia7712 chia7712 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mimaison thanks for the updates. overall LGTM

* to the nearest long.
*/
private static double nanosToMs(long nanos) {
return (double) TimeUnit.NANOSECONDS.toMicros(nanos) / 1000;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ugh, my previous comment missed the protection Math.max(0L, nanos). Would you please add it back?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not entirely clear if nanos can ever be negative here but I think it's probably best to be safe and keep this protection. I pushed an update

double messageConversionsTimeMs = nanosToMs(messageConversionsTimeNanos);
double totalTimeMs = nanosToMs(endTimeNanos - startTimeNanos);

List<String> overrideMetricNames;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using switch expression ?

List<String> overrideMetricNames = switch (header().apiKey()) {
    case FETCH -> {
        String specifiedMetricName = body(FetchRequest.class).isFromFollower()
            ? RequestMetrics.FOLLOW_FETCH_METRIC_NAME
            : RequestMetrics.CONSUMER_FETCH_METRIC_NAME;
        yield List.of(specifiedMetricName, ApiKeys.FETCH.name);
    }

    case ADD_PARTITIONS_TO_TXN -> body(AddPartitionsToTxnRequest.class).allVerifyOnlyRequest()
        ? List.of(RequestMetrics.VERIFY_PARTITIONS_IN_TXN_METRIC_NAME)
        : List.of(ApiKeys.ADD_PARTITIONS_TO_TXN.name);

    case LIST_CONFIG_RESOURCES -> (header().apiVersion() == 0)
        ? List.of(RequestMetrics.LIST_CLIENT_METRICS_RESOURCES_METRIC_NAME, ApiKeys.LIST_CONFIG_RESOURCES.name)
        : List.of(ApiKeys.LIST_CONFIG_RESOURCES.name);

    default -> List.of(header().apiKey().name);
};

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea that's slightly more elegant

@chia7712

Copy link
Copy Markdown
Member

@mimaison would you mind fixing the conflicts?

@mimaison

Copy link
Copy Markdown
Member Author

Rebased on trunk

@chia7712 chia7712 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

expectedNode.set("isForwarded", if (req.isForwarded) BooleanNode.TRUE else BooleanNode.FALSE)
expectedNode.set("requestHeader", RequestConvertToJson.requestHeaderNode(req.header))
expectedNode.set("request", req.requestLog.getOrElse(new TextNode("")))
expectedNode.set("request", req.requestLog.orElse(new TextNode("")))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is orthogonal to the PR, but it appears NullNode.getInstance() is more suitable than new TextNode("") if the filed is non-existent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've opened a PR(#22295) to address this.

@chia7712 chia7712 merged commit dc3fcbb into apache:trunk May 15, 2026
23 checks passed
chia7712 pushed a commit that referenced this pull request May 15, 2026
…ponse fields (#22295)

See #22075 (comment) ,
use `NullNode.getInstance()` instead of `new TextNode("")` as the
fallback for missing `request`/`response` fields.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
JiayaoS pushed a commit to JiayaoS/kafka that referenced this pull request May 21, 2026
Rewrite in Java and move to server module

Reviewers: Ken Huang <s7133700@gmail.com>, Chia-Ping Tsai
 <chia7712@gmail.com>
JiayaoS pushed a commit to JiayaoS/kafka that referenced this pull request May 21, 2026
…ponse fields (apache#22295)

See apache#22075 (comment) ,
use `NullNode.getInstance()` instead of `new TextNode("")` as the
fallback for missing `request`/`response` fields.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
};

for (String metricName : overrideMetricNames) {
RequestMetrics m = metrics.apply(metricName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The apply naming wasn't migrated to follow Java conventions

I'll label this as a 'good first issue' :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mimaison mimaison deleted the kafka-20443 branch July 9, 2026 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants