Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #1067] Supprot mq fault strategy #1068

Merged
merged 2 commits into from
Oct 21, 2024
Merged

[ISSUE #1067] Supprot mq fault strategy #1068

merged 2 commits into from
Oct 21, 2024

Conversation

mxsm
Copy link
Owner

@mxsm mxsm commented Oct 21, 2024

Which Issue(s) This PR Fixes(Closes)

Fixes #1067

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

  • New Features

    • Enhanced asynchronous capabilities for message sending and fault tolerance mechanisms.
    • Introduced new ResolverLocal trait for non-blocking resolution of broker addresses.
  • Bug Fixes

    • Improved error handling for message sending and topic routing.
    • Fixed comparison logic in topic_route_data_changed to ensure accurate topic route data changes.
  • Documentation

    • Updated method signatures and added inline attributes for better performance.
  • Refactor

    • Streamlined the instantiation process of DefaultMQProducer using a builder pattern.
    • Modified fault strategy methods for better clarity and consistency.

Copy link
Contributor

coderabbitai bot commented Oct 21, 2024

Walkthrough

The pull request introduces significant modifications to the RocketMQ client, focusing on enhancing asynchronous capabilities across various components. Key changes include updating the send_message_async and send_message methods in MQClientAPIImpl to handle asynchronous fault item updates. The LatencyFaultTolerance trait and its implementations have been updated to support asynchronous operations, along with changes in the DefaultMQProducer and related structs. Additionally, the Resolver trait has been replaced with ResolverLocal, which supports asynchronous resolution. Overall, these changes improve the concurrency model and error handling throughout the codebase.

Changes

File Path Change Summary
rocketmq-client/src/implementation/mq_client_api_impl.rs Updated send_message_async and send_message methods for asynchronous fault item handling.
rocketmq-client/src/latency/latency_fault_tolerance.rs Modified LatencyFaultTolerance trait to include async methods and additional generic parameters.
rocketmq-client/src/latency/latency_fault_tolerance_impl.rs Updated LatencyFaultToleranceImpl with async methods and changed locking mechanism to async.
rocketmq-client/src/latency/mq_fault_strategy.rs Changed fault tolerance management to use ArcRefCellWrapper and updated methods for async handling.
rocketmq-client/src/latency/resolver.rs Introduced ResolverLocal trait with async resolution method.
rocketmq-client/src/producer/default_mq_producer.rs Updated DefaultMQProducer to use builder pattern and added inline attributes for performance.
rocketmq-client/src/producer/producer_impl/default_mq_producer_impl.rs Enhanced async functionality in DefaultMQProducerImpl and improved error handling.
rocketmq-remoting/src/protocol/route/route_data_view.rs Implemented PartialOrd and Ord for BrokerData struct to enable comparison.
rocketmq-remoting/src/protocol/route/topic_route_data.rs Activated sorting logic in topic_route_data_changed method for meaningful comparisons.

Assessment against linked issues

Objective Addressed Explanation
Support mq fault strategy (#1067)

Possibly related PRs

Suggested labels

approved, auto merge

Suggested reviewers

  • SpaceXCN
  • TeslaRustor

Poem

In the land of code where rabbits play,
Asynchronous magic brightens the day.
With messages sent, and faults in line,
Our RocketMQ hops, oh how it will shine!
So let’s cheer for changes, both swift and bold,
In the world of tech, new stories unfold! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@mxsm
Copy link
Owner Author

mxsm commented Oct 21, 2024

🚀Thanks for your contribution🎉. CodeRabbit(AI) will review your code first🔥

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

🧹 Outside diff range and nitpick comments (5)
rocketmq-remoting/src/protocol/route/topic_route_data.rs (1)

45-51: Approved: Improved functionality of topic_route_data_changed

The changes correctly implement the comparison logic for detecting changes in topic route data. By sorting both the current and old data before comparison, we ensure a consistent and accurate result.

Consider a minor optimization: move the sorting operations to a separate method to improve readability and reusability. For example:

impl TopicRouteData {
    fn sort_data(&mut self) {
        self.queue_datas.sort();
        self.broker_datas.sort();
    }

    pub fn topic_route_data_changed(&self, old_data: Option<&TopicRouteData>) -> bool {
        if old_data.is_none() {
            return true;
        }
        let mut now = TopicRouteData::from_existing(self);
        let mut old = TopicRouteData::from_existing(old_data.unwrap());
        now.sort_data();
        old.sort_data();
        now != old
    }
}

This refactoring would make the topic_route_data_changed method cleaner and allow reuse of the sorting logic if needed elsewhere.

rocketmq-remoting/src/protocol/route/route_data_view.rs (1)

Line range hint 18-49: Summary: Ordering capabilities added to BrokerData

The changes introduce PartialOrd and Ord trait implementations for BrokerData, enabling comparison and sorting based on the broker_name field. This enhancement allows BrokerData to be used in ordered collections and sorting operations.

While the implementations are correct, it's important to consider the following:

  1. The choice of broker_name as the ordering key may affect how BrokerData is used throughout the system.
  2. Existing code that works with collections of BrokerData might behave differently now that ordering is defined.

To ensure these changes align with the overall system design:

  1. Review any code that sorts or compares BrokerData instances to confirm that ordering by broker_name is appropriate.
  2. Consider documenting this new behavior in the struct's documentation to inform other developers of the ordering semantics.
  3. If alternative ordering schemes are needed in some contexts, consider implementing custom comparison functions or using wrapper types with different Ord implementations.
rocketmq-client/src/producer/default_mq_producer.rs (1)

255-255: LGTM: Good use of the builder pattern in new().

The update to the new() method to use the builder pattern is a good improvement. It simplifies the creation of a new DefaultMQProducer instance and is consistent with modern Rust practices.

Consider adding a #[inline] attribute to this method as well, similar to the builder() method. This could potentially improve performance for frequent instantiations.

rocketmq-client/src/latency/latency_fault_tolerance_impl.rs (1)

25-32: Derive Clone for LatencyFaultToleranceImpl<R, S> if cloneability is required

The struct LatencyFaultToleranceImpl<R, S> contains fields like Option<R> and Option<S>. If instances of this struct need to be cloned elsewhere in your code, consider deriving Clone:

#[derive(Clone)]
pub struct LatencyFaultToleranceImpl<R, S> {
    // ... existing fields ...
}

This makes it easier to work with the struct when cloning is necessary.

rocketmq-client/src/producer/producer_impl/default_mq_producer_impl.rs (1)

Line range hint 828-837: Ensure semaphore permits are released after the async task completes

Currently, semaphore permits are dropped immediately after spawning the async task in execute_async_message_send. This may lead to incorrect backpressure handling because the permits should be held until the async task completes. Consider moving the permit release into the async task so that the permits are released after the task finishes.

Apply this diff to fix the permit handling:

-        self.get_async_sender_executor().get_handle().spawn(f);
-        drop((acquire_value_num, acquire_value_size));
+        self.get_async_sender_executor().get_handle().spawn(async move {
+            let result = f.await;
+            drop((acquire_value_num, acquire_value_size));
+            result
+        });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 31dbf92 and 8e06fd2.

📒 Files selected for processing (9)
  • rocketmq-client/src/implementation/mq_client_api_impl.rs (2 hunks)
  • rocketmq-client/src/latency/latency_fault_tolerance.rs (5 hunks)
  • rocketmq-client/src/latency/latency_fault_tolerance_impl.rs (5 hunks)
  • rocketmq-client/src/latency/mq_fault_strategy.rs (7 hunks)
  • rocketmq-client/src/latency/resolver.rs (1 hunks)
  • rocketmq-client/src/producer/default_mq_producer.rs (1 hunks)
  • rocketmq-client/src/producer/producer_impl/default_mq_producer_impl.rs (11 hunks)
  • rocketmq-remoting/src/protocol/route/route_data_view.rs (2 hunks)
  • rocketmq-remoting/src/protocol/route/topic_route_data.rs (1 hunks)
🧰 Additional context used
🔇 Additional comments (10)
rocketmq-remoting/src/protocol/route/route_data_view.rs (3)

18-18: LGTM: Necessary import added.

The Ordering import is correctly added and is required for the new trait implementations.


39-43: LGTM: Correct implementation of PartialOrd.

The PartialOrd implementation for BrokerData is correct and follows Rust's best practices by delegating to the Ord implementation. This ensures consistency between partial and total ordering.


45-49: LGTM: Correct implementation of Ord. Verify ordering choice.

The Ord implementation for BrokerData is correct and provides a total ordering based on the broker_name field. This allows for sorting and using BrokerData in ordered collections.

Please confirm that ordering BrokerData by broker_name is the intended behavior for all use cases. If there are scenarios where a different ordering might be needed, consider implementing a custom Ord trait or using a separate comparison function.

To verify the usage of this ordering, you can run the following script:

This will help identify any potential impacts of the new ordering implementation on existing code.

rocketmq-client/src/producer/default_mq_producer.rs (2)

250-253: LGTM: Good addition of a builder method.

The introduction of the builder() method is a positive change. It promotes the use of the builder pattern, which is beneficial for creating complex objects like DefaultMQProducer. The #[inline] attribute is also a good optimization hint for the compiler.


250-255: Verify usage of DefaultMQProducer in the codebase.

The introduction of the builder pattern for DefaultMQProducer is a good improvement. However, it's important to ensure that all existing instantiations of DefaultMQProducer in the codebase are updated to use the new builder pattern if necessary.

Run the following script to check for direct instantiations of DefaultMQProducer that might need to be updated:

✅ Verification successful

DefaultMQProducer usage is properly updated.
All instantiations of DefaultMQProducer utilize the new builder pattern, and no direct new() calls were found elsewhere in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find direct instantiations of DefaultMQProducer that might need updating

# Search for DefaultMQProducer::new() calls
echo "Searching for DefaultMQProducer::new() calls:"
rg "DefaultMQProducer::new\(\)" --type rust

# Search for DefaultMQProducer { .. } struct instantiations
echo -e "\nSearching for DefaultMQProducer { .. } struct instantiations:"
rg "DefaultMQProducer\s*\{" --type rust

Length of output: 761

rocketmq-client/src/latency/resolver.rs (1)

19-20: Introduction of ResolverLocal trait with async resolve method

The new ResolverLocal trait with an asynchronous resolve method aligns with the shift towards non-blocking operations in the codebase. This change enhances the system's ability to perform asynchronous resolution, improving overall concurrency and responsiveness.

Run the following script to ensure all implementations of ResolverLocal correctly handle the async resolve method:

rocketmq-client/src/latency/latency_fault_tolerance.rs (1)

74-74: ⚠️ Potential issue

Ensure proper handling of Option<T> in pick_one_at_least

The method pick_one_at_least now returns Option<T> instead of T. Please verify that all implementations and call sites of this method have been updated to handle the None case appropriately to prevent potential runtime errors.

Run the following script to find usages of pick_one_at_least and check for proper handling:

✅ Verification successful

No usages of pick_one_at_least found. Verification successful.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of `pick_one_at_least` to ensure `Option<T>` is handled correctly.

# Search for method invocations
rg 'pick_one_at_least\(' -A 3 -B 2

Length of output: 1159


Script:

#!/bin/bash
# Description: Use ast-grep to find all call sites of `pick_one_at_least` and check for proper `Option<T>` handling.

# Search for function calls and surrounding handling
ast-grep --pattern '
match $$$ {
    Some($_) => { $$$ },
    None => { $$$ },
}
' --lang rust

Length of output: 96

rocketmq-client/src/implementation/mq_client_api_impl.rs (3)

460-462: Correctly awaiting the asynchronous update_fault_item method

The update_fault_item method is now asynchronous, and it's appropriate to await it to ensure fault items are updated correctly.


475-477: Duplicate comment: Correctly awaiting update_fault_item

As previously mentioned, awaiting the asynchronous update_fault_item method is necessary here as well.


481-483: Duplicate comment: Correctly awaiting update_fault_item

As previously noted, awaiting the asynchronous update_fault_item method ensures proper error handling and fault item updates.

Comment on lines +118 to +120
fn as_any(&self) -> &dyn Any;

fn set_service_detector(&mut self, service_detector: Box<dyn ServiceDetector>);
fn as_any_mut(&mut self) -> &mut dyn Any;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Reconsider the use of as_any and as_any_mut for downcasting

Introducing as_any and as_any_mut methods to enable downcasting can lead to fragile code and may indicate that the trait's abstraction is leaking. Consider redesigning the trait or its implementations to eliminate the need for downcasting. Alternative approaches include:

  • Using associated types or generic parameters to retain type information.
  • Defining additional trait methods that expose the necessary functionality without requiring downcasting.
  • Employing an enum to represent different concrete types if the set of possible types is known and finite.

pub trait LatencyFaultTolerance<T>: Send + Sync + 'static {
use rocketmq_common::ArcRefCellWrapper;

#[allow(async_fn_in_trait)]
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

Consider using async_trait instead of #[allow(async_fn_in_trait)]

Using #[allow(async_fn_in_trait)] permits the use of async functions in traits but relies on an unstable feature that requires nightly Rust. To ensure compatibility with stable Rust, consider using the async_trait crate, which provides a macro to enable async functions in traits safely.

Apply this diff to use async_trait:

+use async_trait::async_trait;

-#[allow(async_fn_in_trait)]
-pub trait LatencyFaultTolerance<T, R, S>: Send + Sync + 'static {
+#[async_trait]
+pub trait LatencyFaultTolerance<T, R, S>: Send + Sync + 'static {

Committable suggestion was skipped due to low confidence.

Comment on lines +191 to +202
let mut flag = false;
let handle = Handle::current();
scope(|s| {
s.spawn(|| {
flag = handle.block_on(async {
self.latency_fault_tolerance
.is_reachable(&message_queue.get_broker_name().to_string())
.await
});
});
});
flag
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

Data race due to unsynchronized mutation of flag in ReachableFilter::filter

The variable flag is mutated inside a spawned thread without synchronization, which can lead to data races and undefined behavior.

Consider removing the thread and directly blocking on the async function to avoid the data race. Apply this diff to fix the issue:

-            let mut flag = false;
-            let handle = Handle::current();
-            scope(|s| {
-                s.spawn(|| {
-                    flag = handle.block_on(async {
-                        self.latency_fault_tolerance
-                            .is_reachable(&message_queue.get_broker_name().to_string())
-                            .await
-                    });
-                });
-            });
-            flag
+            let handle = Handle::current();
+            let flag = handle.block_on(async {
+                self.latency_fault_tolerance
+                    .is_reachable(&message_queue.get_broker_name().to_string())
+                    .await
+            });
+            flag
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let mut flag = false;
let handle = Handle::current();
scope(|s| {
s.spawn(|| {
flag = handle.block_on(async {
self.latency_fault_tolerance
.is_reachable(&message_queue.get_broker_name().to_string())
.await
});
});
});
flag
let handle = Handle::current();
let flag = handle.block_on(async {
self.latency_fault_tolerance
.is_reachable(&message_queue.get_broker_name().to_string())
.await
});
flag

Comment on lines +213 to +224
let mut flag = false;
let handle = Handle::current();
scope(|s| {
s.spawn(|| {
flag = handle.block_on(async {
self.latency_fault_tolerance
.is_available(&message_queue.get_broker_name().to_string())
.await
});
});
});
flag
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

Data race due to unsynchronized mutation of flag in AvailableFilter::filter

Similar to the previous issue, the variable flag is mutated inside a spawned thread without proper synchronization, causing potential data races.

Apply the same fix by removing the thread and directly blocking on the async function:

-            let mut flag = false;
-            let handle = Handle::current();
-            scope(|s| {
-                s.spawn(|| {
-                    flag = handle.block_on(async {
-                        self.latency_fault_tolerance
-                            .is_available(&message_queue.get_broker_name().to_string())
-                            .await
-                    });
-                });
-            });
-            flag
+            let handle = Handle::current();
+            let flag = handle.block_on(async {
+                self.latency_fault_tolerance
+                    .is_available(&message_queue.get_broker_name().to_string())
+                    .await
+            });
+            flag
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let mut flag = false;
let handle = Handle::current();
scope(|s| {
s.spawn(|| {
flag = handle.block_on(async {
self.latency_fault_tolerance
.is_available(&message_queue.get_broker_name().to_string())
.await
});
});
});
flag
let handle = Handle::current();
let flag = handle.block_on(async {
self.latency_fault_tolerance
.is_available(&message_queue.get_broker_name().to_string())
.await
});
flag

Comment on lines +137 to +175
let mut fault_item_table = self.fault_item_table.lock().await;
let mut remove_set = HashSet::new();
for (name, fault_item) in fault_item_table.iter() {
if get_current_millis() as i64
- (fault_item
.check_stamp
.load(std::sync::atomic::Ordering::Relaxed) as i64)
< 0
{
continue;
}
fault_item.check_stamp.store(
get_current_millis() + self.detect_interval as u64,
std::sync::atomic::Ordering::Release,
);
let broker_addr = self
.resolver
.as_ref()
.unwrap()
.resolve(fault_item.name.as_str())
.await;
if broker_addr.is_none() {
remove_set.insert(name.clone());
continue;
}
if self.service_detector.is_none() {
continue;
}
let service_ok = self
.service_detector
.as_ref()
.unwrap()
.detect(broker_addr.unwrap().as_str(), self.detect_timeout as u64);
if service_ok
&& fault_item
.reachable_flag
.load(std::sync::atomic::Ordering::Acquire)
{
info!("{} is reachable now, then it can be used.", name);
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

Avoid holding the fault_item_table lock across await points to prevent potential deadlocks

In the detect_by_one_round method, you're holding the fault_item_table mutex lock while performing asynchronous operations like resolver.resolve().await. Holding an asynchronous mutex across await points can lead to reduced concurrency or potential deadlocks because other tasks cannot access the locked resource until the lock is released.

To address this, consider collecting the necessary data while holding the lock and then release it before performing any asynchronous operations. Here's how you might adjust the code:

async fn detect_by_one_round(&self) {
    let fault_items: Vec<(String, FaultItem)> = {
        let fault_item_table = self.fault_item_table.lock().await;
        fault_item_table.iter().map(|(name, item)| (name.clone(), item.clone())).collect()
    };
    let mut remove_set = HashSet::new();

    for (name, fault_item) in fault_items {
        if get_current_millis() as i64 - (fault_item.check_stamp.load(Ordering::Relaxed) as i64) < 0 {
            continue;
        }
        fault_item.check_stamp.store(
            get_current_millis() + self.detect_interval as u64,
            Ordering::Release,
        );
        let broker_addr = match self.resolver.as_ref() {
            Some(resolver) => resolver.resolve(fault_item.name.as_str()).await,
            None => {
                remove_set.insert(name.clone());
                continue;
            }
        };
        if broker_addr.is_none() {
            remove_set.insert(name.clone());
            continue;
        }
        if let Some(service_detector) = self.service_detector.as_ref() {
            let service_ok = service_detector
                .detect(broker_addr.unwrap().as_str(), self.detect_timeout as u64);
            if service_ok && fault_item.reachable_flag.load(Ordering::Acquire) {
                info!("{} is reachable now, then it can be used.", name);
                fault_item.reachable_flag.store(true, Ordering::Release);
            }
        }
    }
    let mut fault_item_table = self.fault_item_table.lock().await;
    for name in remove_set {
        fault_item_table.remove(&name);
    }
}

This modification collects the necessary data upfront and releases the lock before the asynchronous calls, enhancing concurrency and preventing potential deadlocks.

Comment on lines +152 to +157
let broker_addr = self
.resolver
.as_ref()
.unwrap()
.resolve(fault_item.name.as_str())
.await;
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

Handle the possibility of resolver being None to prevent potential panics

You're using self.resolver.as_ref().unwrap() without checking if resolver is Some. If resolver is None, this will cause a panic at runtime.

Consider handling the None case gracefully:

let broker_addr = match self.resolver.as_ref() {
    Some(resolver) => resolver.resolve(fault_item.name.as_str()).await,
    None => {
        remove_set.insert(name.clone());
        continue;
    }
};

This ensures that your code doesn't panic and handles the scenario where resolver is not set.

Comment on lines +118 to +131
fn start_detector(this: ArcRefCellWrapper<Self>) {
tokio::spawn(async move {
loop {
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
if !this
.start_detector_enable
.load(std::sync::atomic::Ordering::Relaxed)
{
continue;
}

this.detect_by_one_round().await;
}
});
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

Implement a shutdown mechanism for the detector task to prevent resource leaks

In the start_detector method, you're spawning a Tokio task that runs indefinitely. Without a way to stop this task, it could continue running even when the instance is no longer needed, leading to resource leaks.

Consider adding a shutdown signal using a tokio::sync::Notify or a cancellation token to allow the task to exit gracefully when it's appropriate.

Copy link

codecov bot commented Oct 21, 2024

Codecov Report

Attention: Patch coverage is 0% with 121 lines in your changes missing coverage. Please review.

Project coverage is 19.80%. Comparing base (31dbf92) to head (8e06fd2).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...client/src/latency/latency_fault_tolerance_impl.rs 0.00% 48 Missing ⚠️
rocketmq-client/src/latency/mq_fault_strategy.rs 0.00% 37 Missing ⚠️
...producer/producer_impl/default_mq_producer_impl.rs 0.00% 13 Missing ⚠️
...mq-client/src/implementation/mq_client_api_impl.rs 0.00% 9 Missing ⚠️
...mq-remoting/src/protocol/route/topic_route_data.rs 0.00% 7 Missing ⚠️
...tmq-remoting/src/protocol/route/route_data_view.rs 0.00% 6 Missing ⚠️
...ocketmq-client/src/producer/default_mq_producer.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1068      +/-   ##
==========================================
- Coverage   19.86%   19.80%   -0.06%     
==========================================
  Files         426      426              
  Lines       35561    35659      +98     
==========================================
+ Hits         7063     7064       +1     
- Misses      28498    28595      +97     

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved PR has approved auto merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature🚀] Supprot mq fault strategy
2 participants