[feat][client] Support null value messages#563
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class “null value” (tombstone) support to the Pulsar C++ client so producers can emit tombstones on compacted topics and consumers can distinguish null vs empty payloads, including correct handling for batched messages and C bindings.
Changes:
- Introduces
MessageBuilder::setNullValue()andMessage::hasNullValue()(plus C API equivalents) to represent/inspect tombstone messages. - Preserves
null_valuethrough batch message serialization/deserialization. - Adds unit + integration tests covering null value behavior across Message, batch parsing, TableView, and Reader scenarios.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/TableViewTest.cc | Adds integration tests validating TableView tombstone behavior and empty-vs-null scenarios. |
| tests/ReaderTest.cc | Adds integration tests for reading compacted topics with tombstones and tombstone property preservation. |
| tests/MessageTest.cc | Adds unit tests for basic null value vs empty message semantics. |
| tests/BatchMessageTest.cc | Adds unit test ensuring null_value survives batch serialize/deserialize. |
| lib/c/c_Message.cc | Exposes C API wrappers to set/check null value. |
| lib/MessageBuilder.cc | Implements MessageBuilder::setNullValue(). |
| lib/Message.cc | Implements Message::hasNullValue() and copies null_value from SingleMessageMetadata for batch entries. |
| lib/Commands.cc | Serializes null_value into SingleMessageMetadata for batch payloads. |
| include/pulsar/c/message.h | Declares/document C API for null value. |
| include/pulsar/MessageBuilder.h | Declares/documents setNullValue(). |
| include/pulsar/Message.h | Declares/documents hasNullValue(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
BewareMyPower
left a comment
There was a problem hiding this comment.
Overall LGTM, please fix the code format and address comments from copilot
d23945b to
59a61ab
Compare
Made-with: Cursor
6faed02 to
1975c1b
Compare
|
There are some tests that are very flaky, I will take a look first |
|
#564 I'm working on the broken CI currently |
Sure @BewareMyPower, please let me know once its done from your end. |
|
The fix is here: #565 |
great @BewareMyPower Could you please provide approval to run CI checks for this PR once your fix is merged. |
The test was triggering compaction but reading immediately without waiting for it to complete. Since compaction is asynchronous, the reader might read uncompacted data. Added polling of the compaction status endpoint to wait until compaction completes before reading. Made-with: Cursor
1975c1b to
f099d70
Compare
|
Please merge this branch to the latest main branch to have the fix included |
Done |
|
@BewareMyPower |
|
Looks like, the failure is again due to transient networking issue. |
Fixes #489
Motivation
Currently the producer cannot send a null value message, which is used as a tombstone for a specific key on a compacted topic.
In addition, the consumer cannot differentiate empty values from null values, because all these values are presented as empty std::strings.
Modifications
Verifying this change
Unit Tests (no broker required):
MessageTest.testNullValueMessage - Basic null value API functionality
MessageTest.testEmptyMessage - Verifies empty message is NOT a null value
MessageTest.testEmptyStringNotNullValue - Verifies empty string "" is NOT the same as null value
BatchMessageTest.testParseMessageBatchEntryWithNullValue - Verifies null value survives batch serialization/deserialization
Integration Tests (require Pulsar broker):
TableViewTest.testNullValueTombstone - Send tombstone, verify key removed from TableView
TableViewTest.testNullValueVsEmptyString - Compare empty string vs null value behavior
ReaderTest.testReadCompactedWithNullValue - Reader detects tombstones with hasNullValue()
ReaderTest.testNullValueMessageProperties - Null value message preserves properties
Documentation
doc-required(Your PR needs to update docs and you will update later)
doc-not-needed(Please explain why)
doc(Your PR contains doc changes)
doc-complete(Docs have been already added)