Skip to content

[ISSUE #6389]🚀Implement ExportPopRecord Command in rocketmq-admin-core#6517

Merged
mxsm merged 1 commit intomxsm:mainfrom
WaterWhisperer:feat-6389
Feb 27, 2026
Merged

[ISSUE #6389]🚀Implement ExportPopRecord Command in rocketmq-admin-core#6517
mxsm merged 1 commit intomxsm:mainfrom
WaterWhisperer:feat-6389

Conversation

@WaterWhisperer
Copy link
Contributor

@WaterWhisperer WaterWhisperer commented Feb 25, 2026

Which Issue(s) This PR Fixes(Closes)

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

  • New Features
    • Added exportPopRecord command to export POP consumer records.
    • Can target a specific broker address or an entire cluster.
    • Supports dry-run mode to preview actions without performing exports.
    • Prints clear per-broker success/error status and ensures admin client is started and shut down reliably during the operation.

@rocketmq-rust-bot
Copy link
Collaborator

🔊@WaterWhisperer 🚀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 Feb 25, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Walkthrough

Adds a new CLI subcommand exportPopRecord that exports Pop consumer records; registers the command, adds an enum variant and dispatch, and implements broker- and cluster-scoped export logic with optional dry-run using DefaultMQAdminExt.

Changes

Cohort / File(s) Summary
Command Registration
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands.rs
Inserted exportPopRecord entry in the command classification table (category: "Export", remark: "Export pop consumer records.").
Export Command Structure
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export.rs
Added ExportPopRecord(ExportPopRecordSubCommand) variant to ExportCommands, declared/imported export_pop_record_sub_command module, and extended CommandExecute dispatch to handle it.
ExportPopRecord Implementation
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs
New ExportPopRecordSubCommand with clap args (cluster_name, broker_addr, dry_run, common_args), MQ admin init/teardown, single-broker and cluster export flows, dry-run handling, 30s timeout constant, and async execute implementing calls to export_pop_records and broker/config retrieval.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as CLI Parser
    participant Cmd as ExportPopRecordSubCommand
    participant Admin as DefaultMQAdminExt
    participant Broker as Broker

    User->>CLI: exportPopRecord --broker-addr <addr> [--dry-run]
    CLI->>Cmd: parse args & execute()
    Cmd->>Admin: init & start (with optional RPCHook)
    Admin-->>Cmd: ready

    rect rgba(100, 150, 200, 0.5)
    Cmd->>Admin: get_broker_config(<addr>)
    Admin->>Broker: query config
    Broker-->>Admin: broker_name
    Admin-->>Cmd: broker_name
    alt dry_run = false
        Cmd->>Admin: export_pop_records(<addr>, timeout)
        Admin->>Broker: trigger export
        Broker-->>Admin: success/failure
        Admin-->>Cmd: result
        Cmd->>User: print status
    else
        Cmd->>User: print dry-run preview
    end
    end

    Cmd->>Admin: shutdown
    Admin-->>Cmd: closed
Loading
sequenceDiagram
    actor User
    participant CLI as CLI Parser
    participant Cmd as ExportPopRecordSubCommand
    participant Admin as DefaultMQAdminExt
    participant Broker1 as Broker 1
    participant BrokerN as Broker N

    User->>CLI: exportPopRecord --cluster-name <name> [--dry-run]
    CLI->>Cmd: parse args & execute()
    Cmd->>Admin: init & start
    Admin-->>Cmd: ready

    rect rgba(150, 100, 200, 0.5)
    Cmd->>Admin: examine_broker_cluster_info()
    Admin->>Broker1: request topology
    Admin->>BrokerN: request topology
    Broker1-->>Admin: info
    BrokerN-->>Admin: info
    Admin-->>Cmd: list of broker addrs

    loop for each broker
        alt dry_run = false
            Cmd->>Admin: export_pop_records(broker_addr, timeout)
            Admin->>Broker1: trigger export
            Broker1-->>Admin: result
            Admin-->>Cmd: result
            Cmd->>User: print status
        else
            Cmd->>User: print dry-run preview
        end
    end
    end

    Cmd->>Admin: shutdown
    Admin-->>Cmd: closed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • mxsm
  • TeslaRustor
  • SpaceXCN
  • rocketmq-rust-bot

Poem

🐰 I twitched my nose and found a new deed,
Exporting Pop records, for backup we need.
Across brokers and clusters I quietly peek,
Dry-run to check, then export when we speak.
Hopping away with logs snug and neat.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 title clearly indicates implementation of ExportPopRecord command in rocketmq-admin-core, which matches the main objective of the changeset.
Linked Issues check ✅ Passed The implementation successfully addresses all coding requirements: command parameters (cluster-name, broker-addr, dry-run), cluster/broker discovery, API invocation, dry-run mode, and timeout handling.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the ExportPopRecord command; no unrelated modifications to other features or unrelated refactoring detected.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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: 3

🧹 Nitpick comments (1)
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs (1)

148-151: Unreachable else branch is dead code

The early validation at lines 95–99 guarantees that at least one of broker_addr or cluster_name is Some before reaching the if/else if/else chain. The final else at line 148 can never be reached. It is harmless but adds noise. Consider replacing it with unreachable!() to make the intent explicit.

-        } else {
-            Err(RocketMQError::IllegalArgument(
-                "ExportPopRecordSubCommand: Either brokerAddr (-b) or clusterName (-c) must be provided".into(),
-            ))
-        };
+        } else {
+            unreachable!("validation at entry guarantees broker_addr or cluster_name is Some")
+        };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`
around lines 148 - 151, The final else branch in ExportPopRecordSubCommand that
returns Err(RocketMQError::IllegalArgument(...)) is unreachable because earlier
validation ensures broker_addr or cluster_name is Some; replace that unreachable
error branch with unreachable!() (or remove it) to make intent explicit and
avoid dead code—locate the if/else if/else chain that checks broker_addr and
cluster_name and change the final else arm to unreachable!() referencing
ExportPopRecordSubCommand, broker_addr, cluster_name and the current
RocketMQError::IllegalArgument usage so callers and tools see the unreachable
state.
🤖 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-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`:
- Around line 118-128: When get_broker_config on admin_ext fails you currently
swallow the error and set broker_name to empty which leads to confusing output;
update the match for admin_ext.get_broker_config(...) in
export_pop_record_sub_command.rs so that on Err(e) you emit a warning (to stderr
/ process logger) including the error and the broker_addr (e.g. via
e.to_string()) before falling back to CheetahString::from(""), then continue to
call Self::export(&admin_ext, broker_addr, broker_name.as_str(),
self.dry_run).await; reference get_broker_config, broker_name, broker_addr,
admin_ext and Self::export to locate and modify the match arm.
- Around line 129-154: The call to
admin_ext.examine_broker_cluster_info().await? in execute can early-return on
error and skip admin_ext.shutdown().await; replace the `?` usage by explicitly
matching the Result from admin_ext.examine_broker_cluster_info().await (e.g.,
let cluster_info = match admin_ext.examine_broker_cluster_info().await { Ok(ci)
=> ci, Err(e) => { admin_ext.shutdown().await; return Err(e); } }) so that on
error you first await admin_ext.shutdown() and then return the error; keep the
rest of the logic using cluster_info as before.
- Around line 65-90: The helper async function export currently swallows errors
and prints them to stdout; change export(admin_ext: &DefaultMQAdminExt,
broker_addr: &str, broker_name: &str, dry_run: bool) to return Result<(),
ExportError> (or anyhow::Result) so callers can detect failures, replace
println! for error cases with eprintln! when handling Err from
export_pop_records, propagate or map the error from
admin_ext.export_pop_records(...) into the function's Err, and then update all
call sites (e.g. the Self::export(...).await; Ok(()) call) to await and
propagate/collect the Result instead of always returning Ok(()). Ensure success
paths still return Ok(()).

---

Nitpick comments:
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`:
- Around line 148-151: The final else branch in ExportPopRecordSubCommand that
returns Err(RocketMQError::IllegalArgument(...)) is unreachable because earlier
validation ensures broker_addr or cluster_name is Some; replace that unreachable
error branch with unreachable!() (or remove it) to make intent explicit and
avoid dead code—locate the if/else if/else chain that checks broker_addr and
cluster_name and change the final else arm to unreachable!() referencing
ExportPopRecordSubCommand, broker_addr, cluster_name and the current
RocketMQError::IllegalArgument usage so callers and tools see the unreachable
state.

ℹ️ 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 7616f22 and 22a2df2.

📒 Files selected for processing (3)
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs

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: 1

♻️ Duplicate comments (1)
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs (1)

65-90: ⚠️ Potential issue | 🟠 Major

Propagate export failures instead of always succeeding.

Line 65 defines export as (), so failures at Line 77 are only logged; then Line 127 and Lines 139-145 still lead to Ok(()). This makes failed exports look successful.

🐛 Proposed fix
-    async fn export(admin_ext: &DefaultMQAdminExt, broker_addr: &str, broker_name: &str, dry_run: bool) {
+    async fn export(
+        admin_ext: &DefaultMQAdminExt,
+        broker_addr: &str,
+        broker_name: &str,
+        dry_run: bool,
+    ) -> RocketMQResult<()> {
         if !dry_run {
             match admin_ext
                 .export_pop_records(CheetahString::from(broker_addr), EXPORT_POP_RECORD_TIMEOUT_MILLIS)
                 .await
             {
                 Ok(()) => {
                     println!(
                         "Export broker records, brokerName={}, brokerAddr={}, dryRun={}",
                         broker_name, broker_addr, dry_run
                     );
+                    Ok(())
                 }
                 Err(e) => {
                     eprintln!(
                         "Export broker records error, brokerName={}, brokerAddr={}, dryRun={}\n{}",
                         broker_name, broker_addr, dry_run, e
                     );
+                    Err(e)
                 }
             }
         } else {
             println!(
                 "Export broker records, brokerName={}, brokerAddr={}, dryRun={}",
                 broker_name, broker_addr, dry_run
             );
+            Ok(())
         }
     }
-            Self::export(&admin_ext, broker_addr, broker_name.as_str(), self.dry_run).await;
-            Ok(())
+            Self::export(&admin_ext, broker_addr, broker_name.as_str(), self.dry_run).await
-                                            Self::export(
+                                            Self::export(
                                                 &admin_ext,
                                                 broker_addr.as_str(),
                                                 broker_name.as_str(),
                                                 self.dry_run,
                                             )
-                                            .await;
+                                            .await?;

Also applies to: 127-128, 139-146

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

In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`
around lines 65 - 90, The export function currently swallows failures from
admin_ext.export_pop_records and always returns success; change export (the
async fn export) to return Result<(), E> (or boxed error) and propagate errors
from admin_ext.export_pop_records by returning Err(e) when the call fails (keep
the existing println for the Ok path and for dry_run return Ok(())), and update
any callers that assumed export returned () (those invoking export at the sites
referenced) to handle the Result (use ? or map_err to propagate). Ensure the
exported timeout constant EXPORT_POP_RECORD_TIMEOUT_MILLIS and the method
export_pop_records are left intact, only change the export function signature
and its error handling/propagation.
🤖 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-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`:
- Around line 133-152: The current block in the export_pop_record_sub_command
early-returns Ok(()) when cluster resolution yields no broker targets; change it
to return an explicit error instead. Inside the logic that inspects
cluster_info.cluster_addr_table and cluster_info.broker_addr_table for
CheetahString::from(cluster_name) and iterates broker_name_set/broker_addr,
detect the case where no broker addresses are found (e.g. broker_name_set is
missing/empty or broker_addr_table has no entries) and return a suitable Err
variant (propagate the command's error type) with a clear message like "no
brokers found for cluster {cluster_name}"; keep the existing successful path
that calls Self::export(...).await but ensure the function returns Err when
resolution fails rather than Ok(()).

---

Duplicate comments:
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`:
- Around line 65-90: The export function currently swallows failures from
admin_ext.export_pop_records and always returns success; change export (the
async fn export) to return Result<(), E> (or boxed error) and propagate errors
from admin_ext.export_pop_records by returning Err(e) when the call fails (keep
the existing println for the Ok path and for dry_run return Ok(())), and update
any callers that assumed export returned () (those invoking export at the sites
referenced) to handle the Result (use ? or map_err to propagate). Ensure the
exported timeout constant EXPORT_POP_RECORD_TIMEOUT_MILLIS and the method
export_pop_records are left intact, only change the export function signature
and its error handling/propagation.

ℹ️ 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 22a2df2 and 28f7ac1.

📒 Files selected for processing (3)
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs

@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 0% with 87 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.07%. Comparing base (c5e507e) to head (30a6960).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...c/commands/export/export_pop_record_sub_command.rs 0.00% 81 Missing ⚠️
...rocketmq-admin/rocketmq-admin-core/src/commands.rs 0.00% 5 Missing ⚠️
...q-admin/rocketmq-admin-core/src/commands/export.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6517      +/-   ##
==========================================
- Coverage   42.10%   42.07%   -0.03%     
==========================================
  Files         949      950       +1     
  Lines      132503   132590      +87     
==========================================
- Hits        55795    55793       -2     
- Misses      76708    76797      +89     

☔ 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
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.

♻️ Duplicate comments (2)
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs (2)

65-90: ⚠️ Potential issue | 🟠 Major

Propagate export failures instead of always reporting success.

export() swallows Err and returns (), so callers (e.g., Line 127 and Line 139-146) cannot fail the command when export fails.

🐛 Proposed fix
-    async fn export(admin_ext: &DefaultMQAdminExt, broker_addr: &str, broker_name: &str, dry_run: bool) {
+    async fn export(
+        admin_ext: &DefaultMQAdminExt,
+        broker_addr: &str,
+        broker_name: &str,
+        dry_run: bool,
+    ) -> RocketMQResult<()> {
         if !dry_run {
             match admin_ext
                 .export_pop_records(CheetahString::from(broker_addr), EXPORT_POP_RECORD_TIMEOUT_MILLIS)
                 .await
             {
                 Ok(()) => {
                     println!(
                         "Export broker records, brokerName={}, brokerAddr={}, dryRun={}",
                         broker_name, broker_addr, dry_run
                     );
+                    Ok(())
                 }
                 Err(e) => {
                     eprintln!(
                         "Export broker records error, brokerName={}, brokerAddr={}, dryRun={}\n{}",
                         broker_name, broker_addr, dry_run, e
                     );
+                    Err(e)
                 }
             }
         } else {
             println!(
-                "Export broker records, brokerName={}, brokerAddr={}, dryRun={}",
+                "DRY RUN: Would export broker records, brokerName={}, brokerAddr={}, dryRun={}",
                 broker_name, broker_addr, dry_run
             );
+            Ok(())
         }
     }
-            Self::export(&admin_ext, broker_addr, broker_name.as_str(), self.dry_run).await;
-            Ok(())
+            Self::export(&admin_ext, broker_addr, broker_name.as_str(), self.dry_run).await
-                                            Self::export(
+                                            Self::export(
                                                 &admin_ext,
                                                 broker_addr.as_str(),
                                                 broker_name.as_str(),
                                                 self.dry_run,
                                             )
-                                            .await;
+                                            .await?;

Also applies to: 127-128, 139-146

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

In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`
around lines 65 - 90, The export function currently swallows errors and returns
() which prevents callers from detecting failures; change async fn export(...)
to return a Result<(), E> (use the crate's common error type or Box<dyn Error>)
and propagate the error from admin_ext.export_pop_records(...) by returning
Err(e) when it fails, while keeping the success branch as Ok(()). Update the
callers that invoke export (the call sites referenced around lines where export
is invoked) to handle the Result (propagate with ? or map_err and fail the
command) so command execution correctly fails when export_pop_records on
DefaultMQAdminExt returns an error.

133-152: ⚠️ Potential issue | 🟠 Major

Return an explicit error when cluster resolution finds no brokers.

If cluster_name is missing in tables or resolves to no broker addresses, this branch currently falls through to Ok(()), which is misleading for operators and scripts.

🔍 Proposed fix
                 Ok(cluster_info) => {
-                    if let Some(cluster_addr_table) = &cluster_info.cluster_addr_table {
-                        if let Some(broker_name_set) = cluster_addr_table.get(&CheetahString::from(cluster_name)) {
-                            if let Some(broker_addr_table) = &cluster_info.broker_addr_table {
-                                for broker_name in broker_name_set {
-                                    if let Some(broker_data) = broker_addr_table.get(broker_name) {
-                                        for broker_addr in broker_data.broker_addrs().values() {
-                                            Self::export(
-                                                &admin_ext,
-                                                broker_addr.as_str(),
-                                                broker_name.as_str(),
-                                                self.dry_run,
-                                            )
-                                            .await;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
+                    let cluster_addr_table = cluster_info
+                        .cluster_addr_table
+                        .as_ref()
+                        .ok_or_else(|| RocketMQError::IllegalArgument("cluster address table is empty".into()))?;
+                    let broker_name_set = cluster_addr_table
+                        .get(&CheetahString::from(cluster_name))
+                        .ok_or_else(|| {
+                            RocketMQError::IllegalArgument(
+                                format!("no brokers found for cluster '{}'", cluster_name).into(),
+                            )
+                        })?;
+                    let broker_addr_table = cluster_info
+                        .broker_addr_table
+                        .as_ref()
+                        .ok_or_else(|| RocketMQError::IllegalArgument("broker address table is empty".into()))?;
+
+                    let mut exported_any = false;
+                    for broker_name in broker_name_set {
+                        if let Some(broker_data) = broker_addr_table.get(broker_name) {
+                            for broker_addr in broker_data.broker_addrs().values() {
+                                exported_any = true;
+                                Self::export(
+                                    &admin_ext,
+                                    broker_addr.as_str(),
+                                    broker_name.as_str(),
+                                    self.dry_run,
+                                )
+                                .await?;
+                            }
+                        }
+                    }
+                    if !exported_any {
+                        return Err(RocketMQError::IllegalArgument(
+                            format!("no brokers found for cluster '{}'", cluster_name).into(),
+                        ));
+                    }
                     Ok(())
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`
around lines 133 - 152, The code currently silently returns Ok(()) when cluster
resolution yields no brokers; update the logic in the block that uses
cluster_info.cluster_addr_table,
cluster_addr_table.get(&CheetahString::from(cluster_name)), and
broker_addr_table.get(broker_name) so that if the cluster_name is not found or
the resolved broker_name_set is empty or no broker_addrs are found you return an
explicit Err with a descriptive error (e.g., "cluster not found" or "no broker
addresses for cluster") instead of falling through to Ok(()); keep the existing
loop that calls Self::export(&admin_ext, broker_addr.as_str(),
broker_name.as_str(), self.dry_run).await when brokers are present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs`:
- Around line 65-90: The export function currently swallows errors and returns
() which prevents callers from detecting failures; change async fn export(...)
to return a Result<(), E> (use the crate's common error type or Box<dyn Error>)
and propagate the error from admin_ext.export_pop_records(...) by returning
Err(e) when it fails, while keeping the success branch as Ok(()). Update the
callers that invoke export (the call sites referenced around lines where export
is invoked) to handle the Result (propagate with ? or map_err and fail the
command) so command execution correctly fails when export_pop_records on
DefaultMQAdminExt returns an error.
- Around line 133-152: The code currently silently returns Ok(()) when cluster
resolution yields no brokers; update the logic in the block that uses
cluster_info.cluster_addr_table,
cluster_addr_table.get(&CheetahString::from(cluster_name)), and
broker_addr_table.get(broker_name) so that if the cluster_name is not found or
the resolved broker_name_set is empty or no broker_addrs are found you return an
explicit Err with a descriptive error (e.g., "cluster not found" or "no broker
addresses for cluster") instead of falling through to Ok(()); keep the existing
loop that calls Self::export(&admin_ext, broker_addr.as_str(),
broker_name.as_str(), self.dry_run).await when brokers are present.

ℹ️ 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 28f7ac1 and 30a6960.

📒 Files selected for processing (3)
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/export/export_pop_record_sub_command.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands.rs

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 ✅

Copy link
Owner

@mxsm mxsm left a comment

Choose a reason for hiding this comment

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

LGTM

@mxsm mxsm merged commit 9c8d7dd into mxsm:main Feb 27, 2026
8 of 14 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 Feb 27, 2026
@WaterWhisperer WaterWhisperer deleted the feat-6389 branch February 27, 2026 13:57
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🚀] Implement ExportPopRecord Command in rocketmq-admin-core

4 participants