Skip to content

[ISSUE #7252]✨enhance(allocate_mapped_file_service, commit_log, local_file_message_store): integrate warm mapped file configuration and improve file allocation logic#7253

Merged
rocketmq-rust-bot merged 1 commit into
mainfrom
feat-7252
May 1, 2026

Conversation

@mxsm

@mxsm mxsm commented May 1, 2026

Copy link
Copy Markdown
Owner

Which Issue(s) This PR Fixes(Closes)

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

  • New Features

    • Added commit-log memory warm-up support to improve file allocation performance.
    • Enhanced file allocation service initialization with configuration and status introspection.
  • Bug Fixes

    • Prevented invalid async allocation requests when the file allocation service is not ready.

…_file_message_store): integrate warm mapped file configuration and improve file allocation logic
@rocketmq-rust-bot

Copy link
Copy Markdown
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💥.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Integrates warm-mapped-file configuration into AllocateMappedFileService and propagates the service through the dependency chain (LocalFileMessageStore → CommitLog → MappedFileQueue). The allocation service now supports warm-up when file sizes meet configured thresholds, with startup state checks to gate async allocation attempts.

Changes

Cohort / File(s) Summary
Warm-up Integration
rocketmq-store/src/base/allocate_mapped_file_service.rs
Added WarmMappedFileConfig sourcing from MessageStoreConfig, new constructor new_with_message_store_config, introspection helpers (is_started, should_warm_mapped_file), and conditional warm-up invocation in create_mapped_file when file size meets commitlog threshold.
Dependency Injection
rocketmq-store/src/log_file/commit_log.rs, rocketmq-store/src/message_store/local_file_message_store.rs
CommitLog::new now accepts and injects AllocateMappedFileService; LocalFileMessageStore::try_new builds and configures the service with transient_store_pool support, then passes it to CommitLog.
Allocation Logic
rocketmq-store/src/consume_queue/mapped_file_queue.rs
Pre-allocation and async file-creation paths now check service.is_started() before attempting allocation; non-started services bypass async allocation and fall back to synchronous creation.

Sequence Diagram

sequenceDiagram
    participant LSM as LocalFileMessageStore
    participant AMFS as AllocateMappedFileService
    participant CL as CommitLog
    participant MFQ as MappedFileQueue
    participant MF as MappedFile

    LSM->>AMFS: new_with_message_store_config(config)
    AMFS->>AMFS: extract WarmMappedFileConfig
    LSM->>CL: new(..., allocate_service)
    CL->>MFQ: new(..., Some(allocate_service))
    MFQ->>MFQ: store allocate_mapped_file_service

    rect rgba(100, 150, 200, 0.5)
    Note over MFQ: File Allocation Flow
    MFQ->>AMFS: is_started()?
    alt Service Started
        AMFS-->>MFQ: true
        MFQ->>AMFS: allocate_mapped_file(...)
        AMFS->>MF: create_mapped_file(warm_config)
        MF->>MF: warm_mapped_file() if size >= threshold
    else Service Not Started
        AMFS-->>MFQ: false
        MFQ->>MF: DefaultMappedFile::try_new (sync fallback)
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 Hop hop, files warm with care,
Config flows through layers fair,
Service checks before we go,
Allocation maps now steal the show!
Startup gates keep chaos low, 🔥

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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 changes: integrating warm mapped file configuration and improving file allocation logic across three components.
Linked Issues check ✅ Passed The code changes implement warm mapped file configuration integration and file allocation improvements across allocate_mapped_file_service, commit_log, and local_file_message_store as required by #7252.
Out of Scope Changes check ✅ Passed All changes are directly related to warm mapped file configuration and file allocation logic improvements across the three specified components with no unrelated modifications.
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
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-7252

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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-store/src/base/allocate_mapped_file_service.rs`:
- Around line 404-409: The warm-up call mapped_file.warm_mapped_file is
currently performed before allocation completion is signaled, which blocks the
allocation critical path and can trigger timeouts; change the flow so allocation
completion is signaled before doing expensive warm-up (i.e., move the
mapped_file.warm_mapped_file call to run after the allocation result is
published/notify), or if you must keep warm-up inline, increase the wait budget
for callers when warm_mapped_file_config.should_warm(file_size) is true by
adding a configurable extra timeout; update the logic around
warm_mapped_file_config and the allocation completion/notification code in
allocate_mapped_file_service to reflect this change.

In `@rocketmq-store/src/message_store/local_file_message_store.rs`:
- Around line 457-465: The code freezes transient_store_pool_enable into
allocate_transient_store_pool/allocate_mapped_file_service at construction so a
later sync_broker_role() change won't update allocation behavior; instead remove
the startup-only gate by making AllocateMappedFileService consult the current
role/config at allocation time (e.g., accept a reference/closure to query
broker_role and message_store_config.fast_fail_if_no_buffer_in_store_pool or add
a reconfigure/set_transient_pool_enabled method on AllocateMappedFileService)
and update callers that currently use
AllocateMappedFileService::new_with_message_store_config to either pass a live
check or call the reconfigure setter from sync_broker_role(), ensuring
allocation decisions are made from current broker_role rather than the frozen
transient_store_pool_enable value.
- Around line 4042-4048: Add a focused regression test that asserts
MappedFileQueue creation behavior when the allocate service is started vs not
started: instantiate a test CommitLog/MappedFileQueue from
new_configured_test_store (or directly construct MappedFileQueue) and verify
that when allocate_mapped_file_service().is_started() is true the async
allocation path is used (e.g., file creation is delegated and not performed
synchronously), and when is_started() is false the code falls back to
synchronous creation; use the existing
commit_log.has_allocate_mapped_file_service() check only as setup but add
explicit assertions that exercise the two branches (started and not-started) to
fail if the service-gate behavior in MappedFileQueue or CommitLog (methods on
commit_log / MappedFileQueue and allocate_mapped_file_service) is not honored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 111ede65-80ad-4fdb-80c4-ce7fec5ac12f

📥 Commits

Reviewing files that changed from the base of the PR and between 7918fc9 and 9006ecd.

📒 Files selected for processing (4)
  • rocketmq-store/src/base/allocate_mapped_file_service.rs
  • rocketmq-store/src/consume_queue/mapped_file_queue.rs
  • rocketmq-store/src/log_file/commit_log.rs
  • rocketmq-store/src/message_store/local_file_message_store.rs

Comment on lines +404 to +409
if warm_mapped_file_config.should_warm(file_size) {
mapped_file.warm_mapped_file(
warm_mapped_file_config.flush_disk_type,
warm_mapped_file_config.flush_least_pages_when_warm_mapped_file,
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Warm-up now sits on the allocation critical path and can cause false timeouts

Line 404 performs warm-up before completion is signaled. With the fixed 5s wait budget, large files can time out callers even though allocation eventually succeeds.

💡 Proposed mitigation (extend wait budget when warm-up is enabled)
 const WAIT_TIMEOUT: Duration = Duration::from_secs(5);
+const WAIT_TIMEOUT_WITH_WARM: Duration = Duration::from_secs(30);

 impl AllocateMappedFileService {
+    #[inline]
+    fn request_wait_timeout(&self) -> Duration {
+        if self.warm_mapped_file_config.enabled {
+            WAIT_TIMEOUT_WITH_WARM
+        } else {
+            WAIT_TIMEOUT
+        }
+    }
+
     pub async fn put_request_and_return_mapped_file(
         &self,
         next_file_path: String,
         next_next_file_path: String,
         file_size: i32,
     ) -> Result<Option<Arc<DefaultMappedFile>>, RocketMQError> {
@@
-            let wait_result = tokio::time::timeout(WAIT_TIMEOUT, req.wait()).await;
+            let wait_result = tokio::time::timeout(self.request_wait_timeout(), req.wait()).await;
@@
     fn put_request_and_return_mapped_file_blocking(
         &self,
         next_file_path: String,
         next_next_file_path: String,
         file_size: i32,
     ) -> Result<Option<Arc<DefaultMappedFile>>, RocketMQError> {
@@
-            if req.wait_blocking(WAIT_TIMEOUT) {
+            if req.wait_blocking(self.request_wait_timeout()) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-store/src/base/allocate_mapped_file_service.rs` around lines 404 -
409, The warm-up call mapped_file.warm_mapped_file is currently performed before
allocation completion is signaled, which blocks the allocation critical path and
can trigger timeouts; change the flow so allocation completion is signaled
before doing expensive warm-up (i.e., move the mapped_file.warm_mapped_file call
to run after the allocation result is published/notify), or if you must keep
warm-up inline, increase the wait budget for callers when
warm_mapped_file_config.should_warm(file_size) is true by adding a configurable
extra timeout; update the logic around warm_mapped_file_config and the
allocation completion/notification code in allocate_mapped_file_service to
reflect this change.

Comment on lines +457 to +465
let transient_store_pool_enable = message_store_config.transient_store_pool_enable
&& (broker_config.enable_controller_mode || message_store_config.broker_role != BrokerRole::Slave);
let allocate_transient_store_pool = transient_store_pool_enable.then(|| Arc::new(transient_store_pool.clone()));
let allocate_mapped_file_service = Arc::new(AllocateMappedFileService::new_with_message_store_config(
allocate_transient_store_pool,
transient_store_pool_enable,
message_store_config.fast_fail_if_no_buffer_in_store_pool,
message_store_config.as_ref(),
));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Don't freeze allocation-service eligibility at construction time.

transient_store_pool_enable is computed once from the startup role here, but sync_broker_role() can change broker_role later. After a promotion/demotion, the allocate service keeps the old transient-pool/warm-allocation mode, so file allocation can diverge from the store's current role. Recompute/reconfigure this when the role changes, or move the role gate into the allocation path instead of baking it into construction.

Also applies to: 2700-2704

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

In `@rocketmq-store/src/message_store/local_file_message_store.rs` around lines
457 - 465, The code freezes transient_store_pool_enable into
allocate_transient_store_pool/allocate_mapped_file_service at construction so a
later sync_broker_role() change won't update allocation behavior; instead remove
the startup-only gate by making AllocateMappedFileService consult the current
role/config at allocation time (e.g., accept a reference/closure to query
broker_role and message_store_config.fast_fail_if_no_buffer_in_store_pool or add
a reconfigure/set_transient_pool_enabled method on AllocateMappedFileService)
and update callers that currently use
AllocateMappedFileService::new_with_message_store_config to either pass a live
check or call the reconfigure setter from sync_broker_role(), ensuring
allocation decisions are made from current broker_role rather than the frozen
transient_store_pool_enable value.

Comment on lines +4042 to +4048
#[test]
fn commitlog_uses_allocate_mapped_file_service_for_file_creation() {
let temp_dir = tempdir().unwrap();
let store = new_configured_test_store(&temp_dir, MessageStoreConfig::default());

assert!(store.commit_log.has_allocate_mapped_file_service());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Cover the new allocation branches, not just service injection.

This test only proves that a service is present. It would still pass if MappedFileQueue always fell back to synchronous creation or never honored the new is_started() gate, which is the behavior this PR actually changes. Please add a focused regression test for the started vs. not-started paths.

As per coding guidelines "For behavior changes, add or update focused tests that would fail without the change."

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

In `@rocketmq-store/src/message_store/local_file_message_store.rs` around lines
4042 - 4048, Add a focused regression test that asserts MappedFileQueue creation
behavior when the allocate service is started vs not started: instantiate a test
CommitLog/MappedFileQueue from new_configured_test_store (or directly construct
MappedFileQueue) and verify that when
allocate_mapped_file_service().is_started() is true the async allocation path is
used (e.g., file creation is delegated and not performed synchronously), and
when is_started() is false the code falls back to synchronous creation; use the
existing commit_log.has_allocate_mapped_file_service() check only as setup but
add explicit assertions that exercise the two branches (started and not-started)
to fail if the service-gate behavior in MappedFileQueue or CommitLog (methods on
commit_log / MappedFileQueue and allocate_mapped_file_service) is not honored.

@codecov

codecov Bot commented May 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.99099% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.21%. Comparing base (7918fc9) to head (9006ecd).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ketmq-store/src/consume_queue/mapped_file_queue.rs 58.33% 5 Missing ⚠️
...tmq-store/src/base/allocate_mapped_file_service.rs 94.52% 4 Missing ⚠️
...tore/src/message_store/local_file_message_store.rs 94.44% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7253      +/-   ##
==========================================
+ Coverage   60.18%   60.21%   +0.03%     
==========================================
  Files        1093     1093              
  Lines      203701   203794      +93     
==========================================
+ Hits       122588   122714     +126     
+ Misses      81113    81080      -33     

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

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

Copy link
Copy Markdown
Collaborator

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 5430057 into main May 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 May 1, 2026
@mxsm mxsm deleted the feat-7252 branch May 18, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

3 participants