#[cfg(test)]
pub(crate) mod error_assertions;
use std::sync::Arc;
use cheetah_string::CheetahString;
use rocketmq_model::common::message::message_queue::MessageQueue;
use rocketmq_runtime::ChildServiceContext;
use crate::base::client_config::ClientConfig;
use crate::latency::latency_fault_tolerance_impl::ManualFaultClock;
use crate::latency::mq_fault_strategy::MQFaultStrategy;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LatencyFaultJavaCompatState {
pub available: bool,
pub reachable: bool,
pub unavailable_until_ms: u64,
pub current_latency_ms: u64,
}
pub struct LatencyFaultJavaCompatHarness {
clock: Arc<ManualFaultClock>,
strategy: MQFaultStrategy,
}
impl LatencyFaultJavaCompatHarness {
pub fn new(
service_context: ChildServiceContext,
now_ms: u64,
latency_max_ms: Vec<u64>,
not_available_duration_ms: Vec<u64>,
) -> Self {
assert!(!latency_max_ms.is_empty(), "latency thresholds must not be empty");
assert_eq!(
latency_max_ms.len(),
not_available_duration_ms.len(),
"latency thresholds and durations must have equal lengths"
);
let clock = Arc::new(ManualFaultClock::new(now_ms));
let mut config = ClientConfig::default();
config.set_send_latency_enable(true);
let mut strategy = MQFaultStrategy::new_with_fault_clock(service_context, &config, clock.clone());
strategy.set_latency_max(latency_max_ms);
strategy.set_not_available_duration(not_available_duration_ms);
Self { clock, strategy }
}
pub fn set_now_ms(&self, now_ms: u64) {
self.clock.set_now_millis(now_ms);
}
pub fn not_available_duration(&self, latency_ms: u64, isolation: bool) -> u64 {
self.strategy.not_available_duration_for_test(latency_ms, isolation)
}
pub async fn update(&self, broker: &str, latency_ms: u64, isolation: bool, reachable: bool) {
self.strategy
.update_fault_item(CheetahString::from_slice(broker), latency_ms, isolation, reachable)
.await;
}
pub fn state(&self, broker: &str) -> Option<LatencyFaultJavaCompatState> {
self.strategy
.fault_item_state_for_test(&CheetahString::from_slice(broker))
.map(
|(available, reachable, unavailable_until_ms, current_latency_ms)| LatencyFaultJavaCompatState {
available,
reachable,
unavailable_until_ms,
current_latency_ms,
},
)
}
pub fn select(&self, brokers: &[String], last_broker: Option<&str>) -> Option<String> {
let mut topic_publish_info = TopicPublishInfo::new();
topic_publish_info.message_queue_list = brokers
.iter()
.enumerate()
.map(|(queue_id, broker)| {
MessageQueue::from_parts(
"LatencyFaultJavaCompat",
broker.as_str(),
i32::try_from(queue_id).expect("compatibility corpus queue count fits i32"),
)
})
.collect();
let last_broker = last_broker.map(CheetahString::from_slice);
self.strategy
.select_one_message_queue(&topic_publish_info, last_broker.as_ref(), true)
.map(|queue| queue.broker_name().to_string())
}
}
pub use crate::consumer::consumer_impl::consume_message_concurrently_service::{
run_concurrent_clean_expire_lifecycle_probe, ConcurrentCleanExpireLifecycleProbe,
};
pub use crate::consumer::consumer_impl::consume_message_orderly_service::{
run_orderly_lock_periodic_lifecycle_probe, OrderlyLockPeriodicLifecycleProbe,
};
pub use crate::consumer::consumer_impl::consume_message_pop_orderly_service::{
run_pop_orderly_lock_refresh_lifecycle_probe, PopOrderlyLockRefreshLifecycleProbe,
};
pub use crate::consumer::consumer_impl::default_lite_pull_consumer_impl::{
run_lite_pull_assignment_registry_probe, run_lite_pull_concurrency_contract_probe,
run_lite_pull_suspend_timeout_probe, run_lite_pull_task_lifecycle_probe, LitePullAssignmentRegistryProbe,
LitePullConcurrencyContractProbe, LitePullSuspendTimeoutProbe, LitePullTaskLifecycleProbe,
};
pub use crate::consumer::consumer_impl::process_queue::{
run_process_queue_has_temp_message_probe, run_process_queue_max_span_only_probe, run_process_queue_put_probe,
run_process_queue_remove_probe, run_process_queue_take_probe, ProcessQueue, ProcessQueueOperationFixture,
};
pub use crate::consumer::consumer_impl::pull_message_service::{
run_pull_message_service_lifecycle_probe, PullMessageService, PullMessageServiceLifecycleProbe,
PullMessageServiceShardSnapshot,
};
pub use crate::consumer::consumer_impl::pull_request::PullRequest;
pub use crate::consumer::consumer_impl::re_balance::rebalance_service::{
run_rebalance_service_lifecycle_probe, RebalanceServiceLifecycleProbe,
};
pub use crate::consumer::store::local_file_offset_store::{
run_local_file_offset_store_lifecycle_probe, LocalFileOffsetStoreLifecycleProbe,
};
pub use crate::factory::mq_client_instance::{
run_connection_event_listener_lifecycle_probe, run_heartbeat_route_index_probe,
run_route_refresh_concurrent_stale_guard_probe, run_route_refresh_shard_probe,
ConnectionEventListenerLifecycleProbe, HeartbeatRouteIndexProbe, MQClientInstance, RouteRefreshConcurrentProbe,
RouteRefreshShardProbe,
};
pub use crate::implementation::mq_client_api_factory::{
run_namesrv_refresh_lifecycle_probe, NamesrvRefreshLifecycleProbe,
};
pub use crate::latency::latency_fault_tolerance_impl::{
run_latency_fault_detector_lifecycle_probe, LatencyFaultDetectorLifecycleProbe,
};
#[cfg(feature = "nameserver-dns-discovery")]
pub use crate::nameserver_discovery::supervisor::{
run_nameserver_discovery_lifecycle_probe, NameServerDiscoveryLifecycleProbe,
};
pub use crate::producer::produce_accumulator::{
run_produce_accumulator_guard_lifecycle_probe, ProduceAccumulatorGuardLifecycleProbe,
};
pub use crate::producer::producer_impl::topic_publish_info::TopicPublishInfo;
pub use crate::producer::request_future_holder::{
run_request_future_holder_lifecycle_probe, run_request_future_holder_scan_probe, RequestFutureHolderLifecycleProbe,
RequestFutureHolderScanProbe,
};
pub use crate::stat::consumer_stats_manager::{
run_consumer_stats_manager_lifecycle_probe, ConsumerStatsManagerLifecycleProbe,
};
pub use crate::trace::async_trace_dispatcher::{
run_trace_queue_depth_accounting_probe, run_trace_worker_lifecycle_probe, TraceWorkerLifecycleProbe,
};