Skip to content

KAFKA-10818: Skip conversion to Struct when serializing generated requests/responses#7409

Merged
ijuma merged 59 commits intoapache:trunkfrom
ijuma:skip-to-struct-for-generated-requests
Dec 7, 2020
Merged

KAFKA-10818: Skip conversion to Struct when serializing generated requests/responses#7409
ijuma merged 59 commits intoapache:trunkfrom
ijuma:skip-to-struct-for-generated-requests

Conversation

@ijuma
Copy link
Copy Markdown
Member

@ijuma ijuma commented Sep 29, 2019

Generated request/response classes have code to serialize/deserialize directly to
ByteBuffer so the intermediate conversion to Struct can be skipped for them.
We have recently completed the transition to generated request/response classes,
so we can also remove the Struct based fallbacks.

Additional noteworthy changes:

  • AbstractRequest.parseRequest has a more efficient computation of request size that
    relies on the received buffer instead of the parsed Struct.
  • Use SendBuilder for AbstractRequest/Response toSend, made the superclass
    implementation final and removed the overrides that are no longer necessary.
  • Removed request/response constructors that assume latest version as they are unsafe
    outside of tests.
  • Removed redundant version fields in requests/responses.
  • Removed unnecessary work in OffsetFetchResponse's constructor when version >= 2.
  • Made AbstractResponse.throttleTimeMs() abstract.
  • Using toSend in SaslClientAuthenticator instead of serialize.
  • Various changes in Request/Response classes to make them more consistent and to
    rely on the Data classes as much as possible when it comes to their state.
  • Remove the version argument from AbstractResponse.toString.
  • Fix getErrorResponse for ProduceRequest and DescribeClientQuotasRequest to
    use ApiError which processes the error message sent back to the clients. This was
    uncovered by an accidental fix to a RequestResponseTest test (it was calling
    AbstractResponse.toString instead of AbstractResponse.toString(short)).

Rely on existing protocol tests to ensure this refactoring does not change
observed behavior (aside from improved performance).

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@ijuma ijuma requested a review from cmccabe September 29, 2019 03:30
@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Sep 29, 2019

@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Sep 30, 2019

retest this please

@ijuma ijuma force-pushed the skip-to-struct-for-generated-requests branch from d4e4903 to a009123 Compare September 30, 2019 03:31
@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Sep 30, 2019

Scala 2.13 build passed, Scala 2.12 timed out, 2.11 failed due to H40 slave being offline.

@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Sep 30, 2019

retest this please

@ijuma ijuma force-pushed the skip-to-struct-for-generated-requests branch from a44558e to 3106e35 Compare September 30, 2019 12:47
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.

Need to verify that this condition is equivalent to the previous behavior of checking if the field exists.

@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Oct 2, 2019

retest this please

@ijuma ijuma force-pushed the skip-to-struct-for-generated-requests branch 2 times, most recently from 211d9e0 to 47a197b Compare October 3, 2019 14:59
@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Oct 3, 2019

retest this please

ijuma added 14 commits December 3, 2020 09:53
…t-for-generated-requests

* apache-github/trunk:
MINOR: Fix flaky test shouldQueryOnlyActivePartitionStoresByDefault
(apache#9681)
  KAFKA-10799 AlterIsr utilizes ReplicaManager ISR metrics (apache#9677)
  MINOR: Fix KTable-KTable foreign-key join example (apache#9683)
KAFKA-10473: Add docs on partition size-on-disk, and other log-related
metrics (apache#9276)
  KAFKA-10739; Replace EpochEndOffset with automated protocol (apache#9630)
KAFKA-10460: ReplicaListValidator format checking is incomplete
(apache#9326)
KAFKA-10554; Perform follower truncation based on diverging epochs in
Fetch response (apache#9382)
  MINOR: Align the UID inside/outside container (apache#9652)
KAFKA-10794 Replica leader election is too slow in the case of too
many partitions (apache#9675)
KAFKA-10090 Misleading warnings: The configuration was supplied but i…
(apache#8826)

clients/src/main/java/org/apache/kafka/common/requests/OffsetsForLeaderEpochResponse.java
clients/src/test/java/org/apache/kafka/clients/consumer/internals/FetcherTest.java
core/src/test/scala/unit/kafka/server/epoch/util/ReplicaFetcherMockBlockingSend.scala
Also consolidate and clean-up.
AbstractResponse response = AbstractResponse.parseResponse(apiKey, buffer, apiVersion);

// We correlate after parsing the response to avoid spurious correlation errors when receiving malformed
// responses
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.

TODO: Handle this better.

@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Dec 4, 2020

Looks like the failures are unrelated, so this is ready for review @chia7712. The PR description needs a few tweaks, I will do that tomorrow.

@ijuma ijuma requested a review from chia7712 December 4, 2020 14:42
@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Dec 4, 2020

Actually, I went ahead and updated the PR description.

Copy link
Copy Markdown
Member

@chia7712 chia7712 left a comment

Choose a reason for hiding this comment

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

@ijuma Thanks for this huge patch. Some minor comments are left. Please take a look.

}

// Visible for testing
public final ByteBuffer serializeWithHeader(RequestHeader header) {
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 moving this method to test code? MessageTestUtil could be a good place.

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 for following "Visible for testing" code

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.

BTW, this method is duplicate to TestUtils#serializeRequestHeader

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.

This method serializes the request with the header while the test method serializes the header only. So, not a duplicate, right? Personally, I think it's useful for the class to be symmetric: it can parse from a buffer and serialize to a buffer. Do you have a concern that it may be misused?

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.

There is a reasonable argument that serializeBody is the counterpart to parse though and this particular method doesn't have to be here. I can buy that.

Copy link
Copy Markdown
Member

@chia7712 chia7712 Dec 4, 2020

Choose a reason for hiding this comment

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

Do you have a concern that it may be misused?

yes. Also the various serialization methods are a bit chaos to me :(

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.

Maybe we should move all testing-only serialization to a single utils (in test scope). I grep "static ByteBuffer" + "request/response" and MessageUtils, MessageTestUtil, RequestUtils and TestUtils have similar method interface.

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.

I have a refactoring that consolidates the logic around Send. But I think that would be best done in a separate PR since this PR is really massive. Since these methods are all in internal classes and are only used by tests, I suggest we keep them as they are for now and tackle these nits in the follow up PR.

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.

I have these changes locally, so I can submit them immediately after.


public String toString(boolean verbose) {
return toStruct().toString();
return data().toString();
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.

Is this toString variety still useful?

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.

I think so. Do you think it's not?

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.

Sorry, what do you mean by variety? The verbose boolean? Yes, that is useful for things like fetch and produce.

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.

It seems only ProduceRequest does produce verbose string. Maybe we can remove the toString(boolean verbose) as most requests does not generate verbose string. Also, ProduceRequest should override toString() to generate a verbose string always.

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.

The verbosity flag is used for request logging. Produce and fetch are the most important ones. The rest can be ignored. I don't see the benefit in removing this functionality.

return data;
}

public void write(ByteBuffer buffer, ObjectSerializationCache serializationCache) {
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 is used by testing only. Maybe we can move it to test scope.

Copy link
Copy Markdown
Member

@chia7712 chia7712 left a comment

Choose a reason for hiding this comment

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

+1 to this great cleanup and improvement. Please merge it to trunk and then we can address the TODOs in separate PRs :)

@ijuma ijuma changed the title MINOR: Skip conversion to Struct when serializing generated requests/responses KAFKA-10818: Skip conversion to Struct when serializing generated requests/responses Dec 7, 2020
@ijuma ijuma merged commit 6f27bb0 into apache:trunk Dec 7, 2020
@ijuma ijuma deleted the skip-to-struct-for-generated-requests branch December 7, 2020 23:40
@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Dec 7, 2020

Thanks for the review! Will post the follow up in a bit.

@dajac
Copy link
Copy Markdown
Member

dajac commented Dec 8, 2020

Nice one @ijuma!

@ijuma
Copy link
Copy Markdown
Member Author

ijuma commented Dec 9, 2020

Follow up PR submitted #9714

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants