Skip to content

[ISSUE #6589]📝Refactor MessageTrait documentation for improved clarity and consistency#6590

Merged
rocketmq-rust-bot merged 1 commit intomainfrom
doc-6589
Mar 1, 2026
Merged

[ISSUE #6589]📝Refactor MessageTrait documentation for improved clarity and consistency#6590
rocketmq-rust-bot merged 1 commit intomainfrom
doc-6589

Conversation

@mxsm
Copy link
Owner

@mxsm mxsm commented Mar 1, 2026

Which Issue(s) This PR Fixes(Closes)

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

Release Notes

  • New Features
    • Message format versioning mechanism supporting V2 for improved backward and forward compatibility
    • Expanded message properties including origin host, timestamps, dead-letter queue metadata, immunity time, and timer/index engine configuration options
    • Strengthened property validation with reserved system property protection and improved error handling

@rocketmq-rust-bot
Copy link
Collaborator

🔊@mxsm 🚀Thanks for your contribution🎉!

💡CodeRabbit(AI) will review your code first🔥!

Note

🚨The code review suggestions from CodeRabbit are to be used as a reference only, and the PR submitter can decide whether to make changes based on their own judgment. Ultimately, the project management personnel will conduct the final code review💥.

@rocketmq-rust-robot rocketmq-rust-robot added the documentation📝 Improvements or additions to documentation label Mar 1, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

Walkthrough

The changes introduce a message versioning system with V2 support, expand MessageConst with new property and timer engine constants, strengthen property validation with a reserved property set, and extend MessageTrait with additional accessor/mutator methods and convenience utilities.

Changes

Cohort / File(s) Summary
Message Versioning System
rocketmq-common/src/common/message.rs
Added MESSAGE_MAGIC_CODE_V2 constant and refactored value_of_magic_code to return Result. Introduced topic length encoding/decoding utilities (get_topic_length_size, get_topic_length, get_topic_length_at_index, put_topic_length) with version-aware implementations. Added is_v1/is_v2 helper methods.
MessageConst Expansion
rocketmq-common/src/common/message.rs
Added new public constants: PROPERTY_BORN_HOST, PROPERTY_BORN_TIMESTAMP, PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS, PROPERTY_DLQ_ORIGIN_TOPIC, PROPERTY_TRANSIENT_, TIMER_ENGINE_ variants, and INDEX_*_TYPE constants. Introduced STRING_HASH_SET to track reserved property names.
Property Validation & API Refinement
rocketmq-common/src/common/message.rs
Enhanced put_user_property to validate inputs against reserved properties (STRING_HASH_SET), returning InvalidProperty errors for reserved or blank names. Expanded MessageTrait with new accessor/mutator variants (get_keys_ref, get_tags_ref, get_compressed_body_mut/get_compressed_body) and convenience methods for timing (get_delay_time_sec, get_delay_time_ms, get_deliver_time_ms) and collection-based operations (set_keys_from_collection).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A Versioned Tale

Messages now sport version V2's gleam,
With reserved properties guarding the stream,
Topic lengths shift with each magic byte,
Constants multiply—the API's quite bright!
Traits grow stronger, validation rings true—
A rabbit's delight in the refactored view! 🥬✨

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title claims to refactor MessageTrait documentation, but the actual changes include substantial code modifications: new versioning mechanisms, property validation logic, and public API expansions—far beyond documentation refactoring. Update the title to accurately reflect the major code changes, such as '[ISSUE #6589] Add message versioning support and enhance MessageTrait API' or similar.
Linked Issues check ⚠️ Warning The linked issue #6589 requests documentation refactoring only, but the PR implements significant functional changes: message versioning, property validation, and new public API methods that were not part of the stated documentation objective. Either align the implementation to documentation-only changes per #6589, or create separate issues to track the functional additions introduced in this PR.
Out of Scope Changes check ⚠️ Warning The PR introduces substantial out-of-scope changes beyond documentation refactoring: MESSAGE_MAGIC_CODE_V2 versioning support, put_user_property validation logic, new MessageConst constants, and expanded MessageTrait signatures. Remove non-documentation changes or create corresponding issues that explicitly authorize the functional enhancements being introduced.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch doc-6589

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rocketmq-common/src/common/message.rs (1)

356-365: ⚠️ Potential issue | 🟡 Minor

V1 topic length silently truncates values greater than 255.

When using V1, topic_length as u8 will truncate any value above 255. If a topic name exceeds 255 bytes, this will corrupt the encoded length without warning.

Consider adding a debug assertion or validation to catch oversized topic names during development:

💡 Suggested defensive check
             MessageVersion::V1 => {
+                debug_assert!(topic_length <= 255, "V1 topic length cannot exceed 255 bytes");
                 buffer.push(topic_length as u8)
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-common/src/common/message.rs` around lines 356 - 365,
put_topic_length currently truncates topic_length for MessageVersion::V1 by
casting to u8; add a defensive check to catch oversized topic names during
development by inserting a debug assertion in put_topic_length (e.g. in the
MessageVersion::V1 arm use debug_assert!(topic_length <= 0xFF, "topic_length {}
exceeds V1 max 255", topic_length)) so oversized lengths are detected early;
reference: function put_topic_length and enum variant MessageVersion::V1.
🧹 Nitpick comments (2)
rocketmq-common/src/common/message.rs (2)

55-90: Documentation and trait implementation look good overall.

The put_user_property validation logic is well-structured. Minor note: the error message on line 80 mentions "blank string" but is_empty() only checks for zero-length strings, not whitespace-only strings. If the intent is to also reject whitespace-only input, consider using trim().is_empty(). Otherwise, adjust the message to say "empty" instead of "blank."

💡 Optional: Align message with behavior

Either update the message:

-                "The name or value of property can not be null or blank string!".to_string(),
+                "The name or value of property cannot be empty!".to_string(),

Or extend the check to include whitespace-only strings:

-        if name.is_empty() || value.is_empty() {
+        if name.trim().is_empty() || value.trim().is_empty() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-common/src/common/message.rs` around lines 55 - 90, The validation
in put_user_property currently uses name.is_empty() and value.is_empty() but the
error text mentions "blank string" — update the validation to reject
whitespace-only inputs by using name.trim().is_empty() and
value.trim().is_empty() (keep the same RocketMQError::InvalidProperty path and
message), and leave the follow-up reserved-name check
(STRING_HASH_SET.contains(name.as_str())) and the call to put_property(name,
value) unchanged.

367-382: Simplify is_v1() and is_v2() methods.

These methods can be written more concisely using direct enum comparison.

♻️ Simplified implementation
     pub fn is_v1(&self) -> bool {
-        match self {
-            MessageVersion::V1 => true,
-            MessageVersion::V2 => false,
-        }
+        matches!(self, MessageVersion::V1)
     }
 
     pub fn is_v2(&self) -> bool {
-        match self {
-            MessageVersion::V1 => false,
-            MessageVersion::V2 => true,
-        }
+        matches!(self, MessageVersion::V2)
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-common/src/common/message.rs` around lines 367 - 382, The is_v1()
and is_v2() implementations on the MessageVersion enum are verbose; replace the
match arms with direct enum comparisons: change MessageVersion::is_v1 to return
self == &MessageVersion::V1 and MessageVersion::is_v2 to return self ==
&MessageVersion::V2 (or use *self == MessageVersion::V1 / V2 if using Copy) so
the methods are concise and idiomatic; update the functions named is_v1 and
is_v2 on the MessageVersion type accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@rocketmq-common/src/common/message.rs`:
- Around line 339-345: The get_topic_length function may cast a negative i16 to
usize for MessageVersion::V2 (buffer.get_i16()), causing huge lengths; update
MessageVersion::V2 handling in get_topic_length to either read an unsigned value
(use buffer.get_u16() semantics) or explicitly validate the i16 (check if < 0
and return an error or 0/handle appropriately) before converting to usize so
negative values cannot wrap into large sizes.
- Around line 347-354: get_topic_length_at_index currently indexes buffer
directly and can panic; change its signature to return Option<usize> and perform
bounds-checked access via slice.get(): for MessageVersion::V1 use
buffer.get(index).map(|b| *b as usize), and for MessageVersion::V2 use
buffer.get(index).and_then(|b0| buffer.get(index + 1).map(|b1| (((*b0 as usize)
<< 8) | (*b1 as usize)))); this prevents panics on short buffers and propagates
None when bytes are missing.

---

Outside diff comments:
In `@rocketmq-common/src/common/message.rs`:
- Around line 356-365: put_topic_length currently truncates topic_length for
MessageVersion::V1 by casting to u8; add a defensive check to catch oversized
topic names during development by inserting a debug assertion in
put_topic_length (e.g. in the MessageVersion::V1 arm use
debug_assert!(topic_length <= 0xFF, "topic_length {} exceeds V1 max 255",
topic_length)) so oversized lengths are detected early; reference: function
put_topic_length and enum variant MessageVersion::V1.

---

Nitpick comments:
In `@rocketmq-common/src/common/message.rs`:
- Around line 55-90: The validation in put_user_property currently uses
name.is_empty() and value.is_empty() but the error text mentions "blank string"
— update the validation to reject whitespace-only inputs by using
name.trim().is_empty() and value.trim().is_empty() (keep the same
RocketMQError::InvalidProperty path and message), and leave the follow-up
reserved-name check (STRING_HASH_SET.contains(name.as_str())) and the call to
put_property(name, value) unchanged.
- Around line 367-382: The is_v1() and is_v2() implementations on the
MessageVersion enum are verbose; replace the match arms with direct enum
comparisons: change MessageVersion::is_v1 to return self == &MessageVersion::V1
and MessageVersion::is_v2 to return self == &MessageVersion::V2 (or use *self ==
MessageVersion::V1 / V2 if using Copy) so the methods are concise and idiomatic;
update the functions named is_v1 and is_v2 on the MessageVersion type
accordingly.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ec62c0 and 68d1b9c.

📒 Files selected for processing (1)
  • rocketmq-common/src/common/message.rs

Comment on lines +339 to 345
/// Reads and returns the topic length from the buffer, advancing the buffer position.
pub fn get_topic_length(&self, buffer: &mut Bytes) -> usize {
match self {
MessageVersion::V1 => buffer.get_u8() as usize,
MessageVersion::V2 => buffer.get_i16() as usize,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential issue with negative i16 to usize cast.

On line 343, buffer.get_i16() as usize can produce incorrect results if the value is negative. A negative i16 cast to usize will wrap around to a very large value, causing incorrect topic length parsing.

🛡️ Proposed fix: use unsigned read or validate
             MessageVersion::V1 => buffer.get_u8() as usize,
-            MessageVersion::V2 => buffer.get_i16() as usize,
+            MessageVersion::V2 => buffer.get_u16() as usize,

Alternatively, if signed is intentional, validate the value:

MessageVersion::V2 => {
    let len = buffer.get_i16();
    if len < 0 {
        return 0; // or handle error appropriately
    }
    len as usize
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-common/src/common/message.rs` around lines 339 - 345, The
get_topic_length function may cast a negative i16 to usize for
MessageVersion::V2 (buffer.get_i16()), causing huge lengths; update
MessageVersion::V2 handling in get_topic_length to either read an unsigned value
(use buffer.get_u16() semantics) or explicitly validate the i16 (check if < 0
and return an error or 0/handle appropriately) before converting to usize so
negative values cannot wrap into large sizes.

Comment on lines +347 to 354
/// Returns the topic length from the buffer at the specified index without advancing the
/// position.
pub fn get_topic_length_at_index(&self, buffer: &[u8], index: usize) -> usize {
match self {
MessageVersion::V1 => buffer[index] as usize,
MessageVersion::V2 => ((buffer[index] as usize) << 8) | (buffer[index + 1] as usize),
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Array access without bounds checking can panic.

get_topic_length_at_index accesses buffer[index] and buffer[index + 1] without validating that these indices are within bounds. This can cause a panic if the buffer is too short.

🛡️ Proposed fix: add bounds validation or return Result

Option 1 - Return Option<usize>:

-    pub fn get_topic_length_at_index(&self, buffer: &[u8], index: usize) -> usize {
+    pub fn get_topic_length_at_index(&self, buffer: &[u8], index: usize) -> Option<usize> {
         match self {
-            MessageVersion::V1 => buffer[index] as usize,
+            MessageVersion::V1 => buffer.get(index).map(|&b| b as usize),
             MessageVersion::V2 => {
+                if index + 1 >= buffer.len() {
+                    return None;
+                }
-                ((buffer[index] as usize) << 8) | (buffer[index + 1] as usize)
+                Some(((buffer[index] as usize) << 8) | (buffer[index + 1] as usize))
             }
         }
     }

Option 2 - Use .get() with a fallback if panicking is unacceptable in your use case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-common/src/common/message.rs` around lines 347 - 354,
get_topic_length_at_index currently indexes buffer directly and can panic;
change its signature to return Option<usize> and perform bounds-checked access
via slice.get(): for MessageVersion::V1 use buffer.get(index).map(|b| *b as
usize), and for MessageVersion::V2 use buffer.get(index).and_then(|b0|
buffer.get(index + 1).map(|b1| (((*b0 as usize) << 8) | (*b1 as usize)))); this
prevents panics on short buffers and propagates None when bytes are missing.

@codecov
Copy link

codecov bot commented Mar 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 41.84%. Comparing base (0ec62c0) to head (68d1b9c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6590   +/-   ##
=======================================
  Coverage   41.84%   41.84%           
=======================================
  Files         956      956           
  Lines      133557   133557           
=======================================
  Hits        55884    55884           
  Misses      77673    77673           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Collaborator

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Choose a reason for hiding this comment

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

LGTM - All CI checks passed ✅

@rocketmq-rust-bot rocketmq-rust-bot merged commit c5b1a29 into main Mar 1, 2026
20 checks passed
@rocketmq-rust-bot rocketmq-rust-bot added approved PR has approved and removed ready to review waiting-review waiting review this PR labels Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI review first Ai review pr first approved PR has approved auto merge documentation📝 Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Doc📝] Refactor MessageTrait documentation for improved clarity and consistency

3 participants