[ISSUE #10972] Encode timer message propertiesString after internal properties are cleared - #10974
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a bug in the file-based timer store message conversion so propertiesString is encoded after internal properties (REAL_TOPIC / REAL_QUEUE_ID) are cleared, keeping the wire representation consistent with the broker-side properties map and matching the RocksDB timer store behavior.
Changes:
- Update
TimerMessageStore#convertMessageto clear internal properties first, then encodepropertiesStringfrom the copied/cleared properties map. - Add a regression test to ensure delivered timer messages do not carry internal properties on the wire and that
propertiesStringmatches the re-encoded properties map.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| store/src/main/java/org/apache/rocketmq/store/timer/TimerMessageStore.java | Encodes propertiesString after clearing internal timer properties to keep map/wire consistent. |
| store/src/test/java/org/apache/rocketmq/store/timer/TimerMessageStoreTest.java | Adds regression coverage verifying delivered vs rolled timer message property handling and map/wire consistency. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #10974 +/- ##
=============================================
- Coverage 48.58% 48.50% -0.08%
+ Complexity 13676 13655 -21
=============================================
Files 1381 1381
Lines 101475 101475
Branches 13190 13190
=============================================
- Hits 49299 49221 -78
- Misses 46174 46245 +71
- Partials 6002 6009 +7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Summary
This PR fixes a correctness bug in TimerMessageStore.convertMessage where propertiesString was encoded before internal properties (PROPERTY_REAL_TOPIC, PROPERTY_REAL_QUEUE_ID) were cleared from the property map. This caused the wire data to contain stale properties that didn't match the actual property map.
The fix moves setPropertiesString to after the property clearing logic, ensuring consistency between the encoded string and the property map. The comment correctly references TimerMessageRocksDBStore#convertMessage as the aligned implementation.
The test verifies both scenarios: delivered messages (properties cleared) and rolled messages (properties retained), confirming that propertiesString matches messageProperties2String(properties) in both cases.
Important bug fix — the wire format and property map must stay consistent. LGTM.
Automated review by github-manager-bot
…rnal properties are cleared
15c5193 to
20b4dc7
Compare
Which Issue(s) This PR Fixes
Fixes #10972
Brief Description
TimerMessageStore#convertMessageencodedpropertiesStringfrom the original property map and only afterwards clearedREAL_TOPIC/REAL_QUEUE_IDfrom the deep copy. As a result the delivered timer message carried the internal properties on the wire while the broker-side map had them cleared, and the file-based timer store observably diverged fromTimerMessageRocksDBStore#convertMessage, which already clears first and encodes from the copied map.This PR moves the encode after the clear block and encodes from
msgInner.getProperties(), mirroring the RocksDB implementation. It also removes the map/wire mismatch where the deep copy was made but the encode still read the original map.TIMER_DELIVER_MSand other timer metadata are not in the clearing list, so the deliveryTimestamp exposed to gRPC consumers is unchanged.How Did You Test This Change?
testConvertMessagePropertiesStringMatchesProperties: the delivered message dropsREAL_TOPIC/REAL_QUEUE_IDfrom the wire andpropertiesStringequals the re-encoded map; the rolled message keeps them.TimerMessageStoreTestpasses 11/11.benchmark.timer.TimerProducer64 threads x 40 slots x 250 msgs/slot, 1 KiB, per arm clean store + page cache drop, 3 interleaved trials; the 2-minute first-slot offset isolates GC sampling to the pure delivery phase): every arm delivered 639,990/640,000 (report-sampling rounding) with zero send failures; delivery-phase young GC base 2/2/2 vs patch 1/2/2 — correctness intact, no regression.