Skip to content

[fix][client-cpp] Fix TypedMessageTest to use receiveAsync<T> template overload with decoder#580

Open
geniusjoe wants to merge 2 commits into
apache:mainfrom
geniusjoe:bugfix/TypedMessageTest.testReceive
Open

[fix][client-cpp] Fix TypedMessageTest to use receiveAsync<T> template overload with decoder#580
geniusjoe wants to merge 2 commits into
apache:mainfrom
geniusjoe:bugfix/TypedMessageTest.testReceive

Conversation

@geniusjoe
Copy link
Copy Markdown

Fixes #466

Master Issue: #149

Motivation

The TypedMessageTest.testReceive test was using receiveAsync incorrectly. It called the untyped receiveAsync(const ReceiveCallback&) overload (where ReceiveCallback is std::function<void(Result, const Message&)>), but the lambda's parameter was declared as const TypedMessage<int>& — a derived class reference. Since the actual argument passed at runtime is const Message&, this relies on an implicit downcast from base to derived, which is not guaranteed to work across compilers.

GCC 11+ happens to be permissive about this implicit conversion when constructing std::function from a lambda (it does not strictly enforce contravariance on parameter types during type erasure), so the code compiled successfully. However, GCC 8.x does not accept this conversion, causing a compilation failure (see #466).

The fix is to use the proper typed template overload consumer.receiveAsync<int>(callback, intDecoder), which internally constructs TypedMessage<int>{msg, decoder} and passes it to the callback. This is both the intended API usage and portable across all GCC versions.

Modifications

  • Changed consumer.receiveAsync(...) to consumer.receiveAsync<int>(..., intDecoder) to use the correct typed template overload.
  • Simplified the callback by directly assigning msg = receivedMsg instead of manually constructing TypedMessage<int>{receivedMsg, intDecoder}, since the decoder is now passed to receiveAsync<T> and applied internally.

Verifying this change

This change is already covered by existing tests, such as TypedMessageTest.testReceive which validates the typed message receive flow including receiveAsync<int>.

Documentation

  • doc-not-needed
    (This is a test fix only, no public API changes.)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes TypedMessageTest.testReceive to use the correct typed Consumer::receiveAsync<T>(callback, decoder) overload so the callback receives a TypedMessage<T> without relying on non-portable implicit downcasting behavior (fixes build issues on GCC 8.x as described in #466).

Changes:

  • Update TypedMessageTest.testReceive to call consumer.receiveAsync<int>(..., intDecoder) instead of the untyped overload.
  • Simplify the async receive callback to assign the already-decoded TypedMessage<int> directly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/TypedMessageTest.cc Outdated
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.

[Bug] TypedMessageTest.cc build failed in gcc8.3.1

2 participants