Skip to content

[ISSUE #6603]🚀Add seek functionality and offset retrieval methods in DefaultLitePullConsumerImpl#6604

Merged
rocketmq-rust-bot merged 1 commit intomainfrom
feat-6603
Mar 1, 2026
Merged

[ISSUE #6603]🚀Add seek functionality and offset retrieval methods in DefaultLitePullConsumerImpl#6604
rocketmq-rust-bot merged 1 commit intomainfrom
feat-6603

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

  • New Features
    • Message queue seeking: reposition consumption at specific offsets, queue beginning, or queue end
    • Committed offset tracking: retrieve the last consumed offset position for message queues
    • Offset boundary queries: fetch minimum and maximum available offsets from brokers
    • Enhanced consumption control with improved message queue position management

@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 feature🚀 Suggest an idea for this project. label Mar 1, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

Walkthrough

The PR introduces seek functionality to DefaultLitePullConsumerImpl, enabling consumers to navigate to specific offsets, queue beginnings, or queue ends. It adds offset retrieval via a committed() method and internal helpers for offset management. Additionally, a get_min_offset() API is introduced in mq_client_api_impl to query broker minimum offsets.

Changes

Cohort / File(s) Summary
Seek and Offset Retrieval APIs
rocketmq-client/src/consumer/consumer_impl/default_lite_pull_consumer_impl.rs
Added four public async methods: seek(), seek_to_begin(), seek_to_end(), and committed() for queue positioning and offset tracking. Internal helpers seek_internal(), max_offset(), min_offset(), and clear_message_queue_in_cache() support seek operations via state validation, cache clearing, and task lifecycle management. Updated imports for mix_all and ReadOffsetType.
Broker Offset API
rocketmq-client/src/implementation/mq_client_api_impl.rs
Added public async method get_min_offset() to fetch minimum broker offset for a message queue via remote invocation, mirroring the existing get_max_offset() pattern. Includes request/response header imports.

Sequence Diagram

sequenceDiagram
    participant Consumer as Consumer
    participant StateStore as State/Cache
    participant ProcessQueue as ProcessQueue
    participant Broker as Broker
    
    Consumer->>StateStore: validate state & assignment
    StateStore-->>Consumer: state validated
    
    Consumer->>ProcessQueue: check not dropped
    ProcessQueue-->>Consumer: status OK
    
    Consumer->>StateStore: clear queue from cache
    StateStore-->>Consumer: cache cleared
    
    Consumer->>ProcessQueue: abort existing pull task
    ProcessQueue-->>Consumer: task aborted
    
    Consumer->>StateStore: set seek offset
    StateStore-->>Consumer: offset persisted
    
    Consumer->>Broker: fetch messages from new offset
    Broker-->>Consumer: messages returned
    
    Consumer->>ProcessQueue: restart pull task
    ProcessQueue-->>Consumer: task running
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop along the message streams so grand,
With seek we now can take our stand,
To start, to end, or in between,
The finest offsets ever seen!
Pull and quest through broker's land,

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly describes the main change: adding seek functionality and offset retrieval methods to DefaultLitePullConsumerImpl, which matches the implemented changes.
Linked Issues check ✅ Passed The PR implements the feature mentioned in #6603 by adding seek APIs and offset retrieval methods, fulfilling the stated objective despite minimal issue description.
Out of Scope Changes check ✅ Passed All changes are focused on implementing seek functionality and offset retrieval. The addition of get_min_offset to mq_client_api_impl.rs is a supporting method for the core feature.

✏️ 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 feat-6603

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.

🧹 Nitpick comments (2)
rocketmq-client/src/consumer/consumer_impl/default_lite_pull_consumer_impl.rs (2)

1001-1014: Redundant conditional check after task removal.

Line 1003 removes the task handle for message_queue, so the check at line 1011 !task_handles.contains_key(message_queue) will always be true. The conditional is unnecessary.

♻️ Suggested simplification
         // Stop old pull task
         let mut task_handles = self.task_handles.write().await;
         if let Some(handle) = task_handles.remove(message_queue) {
             handle.abort();
         }
 
         // Set seek offset
         self.assigned_message_queue.set_seek_offset(message_queue, offset).await;
 
         // Start new pull task
-        if !task_handles.contains_key(message_queue) {
-            drop(task_handles); // Release write lock before starting pull task
-            self.start_pull_task(message_queue.clone()).await?;
-        }
+        drop(task_handles); // Release write lock before starting pull task
+        self.start_pull_task(message_queue.clone()).await?;
 
         Ok(())
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@rocketmq-client/src/consumer/consumer_impl/default_lite_pull_consumer_impl.rs`
around lines 1001 - 1014, The check for task_handles.contains_key(message_queue)
after removing the handle is redundant because
task_handles.remove(message_queue) just ran; drop the conditional and always
release the write lock then call
self.start_pull_task(message_queue.clone()).await? in the same place—i.e., after
remove and set_seek_offset, drop task_handles and invoke
self.start_pull_task(message_queue.clone()).await? unconditionally (keep abort()
and set_seek_offset logic intact) so the flow uses task_handles.remove(...),
set_seek_offset(...), drop(task_handles), then start_pull_task(...).

1055-1061: Consider replacing .unwrap() with proper error handling.

Lines 1057-1058 and 1081-1082 use .unwrap() on mq_client_api_impl.as_mut(), which could panic if the API impl is unexpectedly None. While this should not happen when service_state is Running, defensive error handling would be more robust.

♻️ Suggested improvement for max_offset
-        client_instance
-            .mq_client_api_impl
-            .as_mut()
-            .unwrap()
-            .get_max_offset(broker_result.broker_addr.as_str(), message_queue, 3000)
-            .await
+        client_instance
+            .mq_client_api_impl
+            .as_mut()
+            .ok_or_else(|| crate::mq_client_err!("MQ client API not initialized"))?
+            .get_max_offset(broker_result.broker_addr.as_str(), message_queue, 3000)
+            .await

Apply the same pattern to min_offset.

Also applies to: 1079-1085

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

In
`@rocketmq-client/src/consumer/consumer_impl/default_lite_pull_consumer_impl.rs`
around lines 1055 - 1061, Replace the vulnerable .unwrap() calls on
client_instance.mq_client_api_impl with explicit error handling: check
mq_client_api_impl.as_mut() (e.g., if let Some(api) = ...) before calling
get_max_offset/get_min_offset and return or propagate a meaningful error if None
(include context like broker_result.broker_addr and message_queue). Update both
places where get_max_offset and get_min_offset are invoked so they return a
Result or map the absence to a domain error rather than panicking; refer to the
mq_client_api_impl field and the get_max_offset/get_min_offset calls to locate
and fix the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@rocketmq-client/src/consumer/consumer_impl/default_lite_pull_consumer_impl.rs`:
- Around line 1001-1014: The check for task_handles.contains_key(message_queue)
after removing the handle is redundant because
task_handles.remove(message_queue) just ran; drop the conditional and always
release the write lock then call
self.start_pull_task(message_queue.clone()).await? in the same place—i.e., after
remove and set_seek_offset, drop task_handles and invoke
self.start_pull_task(message_queue.clone()).await? unconditionally (keep abort()
and set_seek_offset logic intact) so the flow uses task_handles.remove(...),
set_seek_offset(...), drop(task_handles), then start_pull_task(...).
- Around line 1055-1061: Replace the vulnerable .unwrap() calls on
client_instance.mq_client_api_impl with explicit error handling: check
mq_client_api_impl.as_mut() (e.g., if let Some(api) = ...) before calling
get_max_offset/get_min_offset and return or propagate a meaningful error if None
(include context like broker_result.broker_addr and message_queue). Update both
places where get_max_offset and get_min_offset are invoked so they return a
Result or map the absence to a domain error rather than panicking; refer to the
mq_client_api_impl field and the get_max_offset/get_min_offset calls to locate
and fix the code.

ℹ️ 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 768268b and 66e9c63.

📒 Files selected for processing (2)
  • rocketmq-client/src/consumer/consumer_impl/default_lite_pull_consumer_impl.rs
  • rocketmq-client/src/implementation/mq_client_api_impl.rs

@codecov
Copy link

codecov bot commented Mar 1, 2026

Codecov Report

❌ Patch coverage is 0% with 166 lines in your changes missing coverage. Please review.
✅ Project coverage is 41.58%. Comparing base (768268b) to head (66e9c63).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...r/consumer_impl/default_lite_pull_consumer_impl.rs 0.00% 126 Missing ⚠️
...mq-client/src/implementation/mq_client_api_impl.rs 0.00% 40 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6604      +/-   ##
==========================================
- Coverage   41.63%   41.58%   -0.06%     
==========================================
  Files         959      959              
  Lines      134280   134446     +166     
==========================================
  Hits        55907    55907              
- Misses      78373    78539     +166     

☔ 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 9cfae92 into main Mar 1, 2026
18 of 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 feature🚀 Suggest an idea for this project.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature🚀] Add seek functionality and offset retrieval methods in DefaultLitePullConsumerImpl

3 participants