feat: support null value messages (tombstones) for compacted topics#304
feat: support null value messages (tombstones) for compacted topics#304grishaf wants to merge 3 commits into
Conversation
024c74c to
dbe4502
Compare
Add support for sending and detecting null value messages, which are used as tombstones on compacted topics to delete entries for specific keys. This wraps the C++ client's MessageBuilder::setNullValue() and Message::hasNullValue() APIs added in pulsar-client-cpp#563. Changes: - Bump pulsar-cpp dependency to 4.2.0 - Add pybind11 bindings for set_null_value and has_null_value - Allow Producer.send(None) to produce a null value message - Add Message.has_null_value() to detect tombstone messages - Skip schema encoding when content is None (mirrors Java client) - Add integration tests for null values, compaction, and table view Requires pulsar-client-cpp >= 4.2.0 (not yet released). Co-authored-by: Cursor <cursoragent@cursor.com>
dbe4502 to
d293511
Compare
|
Blocked on two upstream dependencies:
|
4.2.0 is not yet released on archive.apache.org, so CI fails downloading the C++ client .deb. Revert to the released 4.1.0 to unblock CI until pulsar-client-cpp 4.2.0 ships. Co-authored-by: Cursor <cursoragent@cursor.com>
4.2.2 is the latest 4.x release and includes the null-value compaction fix (apache/pulsar#25817, shipped in release/4.2.2). This lets test_null_value_compaction pass; 4.0.0 predated the fix. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Update: both blockers from my earlier comment are now resolved on this branch.
With these two commits the PR should be fully green. CI for the latest commit is currently in |
Motivation
Currently the Python client cannot send null value messages, which are needed as tombstones on compacted topics to delete entries for specific keys. Attempting to call
producer.send(None, ...)raises aTypeErrorbecauseBytesSchema.encode()rejectsNone, and_build_msghas a second_check_type(bytes, data, 'data')guard.The C++ client added
MessageBuilder::setNullValue()andMessage::hasNullValue()in apache/pulsar-client-cpp#563 (merged April 3, 2026, milestone 4.2.0). The Java client has supportedvalue(null)tombstones since v2.8+ viaTypedMessageBuilderImpl.beforeSend()which setsmsgMetadata.setNullValue(true)when the value is null.This PR wraps the new C++ API for Python, using the same pattern as the Java client.
Modifications
pybind11 bindings (
src/message.cc)set_null_valuebinding onMessageBuilder→MessageBuilder::setNullValue()has_null_valuebinding onMessage→Message::hasNullValue()Python wrapper (
pulsar/__init__.py)Message.has_null_value()— check if a received message is a tombstoneProducer._build_msg()— whencontent is None, skip schema encoding and callmb.set_null_value()instead ofmb.content(data)(same pattern as Java'sbeforeSend())send()andsend_async()docstrings to documentNonecontentDependencies (
dependencies.yaml)pulsar-cppfrom4.1.0to4.2.0Tests (
tests/pulsar_test.py)test_null_value_message— send/receive null and non-null messages, verifyhas_null_value()test_null_value_vs_empty_bytes— verifyb""andNoneare distincttest_null_value_compaction— tombstoned keys disappear after topic compactiontest_null_value_table_view— tombstoned keys removed from TableViewtest_null_value_with_properties— properties survive on null-value messagesBlocked on
This PR requires
pulsar-client-cpp>= 4.2.0, which has not been released yet (v4.1.0 is the latest as of May 2026). ThesetNullValue()/hasNullValue()APIs are merged into C++mainbut not yet in a release. CI will not pass until 4.2.0 ships.References:
Made with Cursor