use std::sync::Arc;
use std::sync::Weak;
use cheetah_string::CheetahString;
use rocketmq_model::common::message::message_client_ext::MessageClientExt;
use rocketmq_model::common::message::message_ext::MessageExt;
use rocketmq_model::common::message::message_queue::MessageQueue;
use rocketmq_protocol::protocol::body::consume_message_directly_result::ConsumeMessageDirectlyResult;
use crate::consumer::consumer_impl::pop_process_queue::PopProcessQueue;
use crate::consumer::consumer_impl::process_queue::ProcessQueue;
use rocketmq_protocol::protocol::body::cm_result::CMResult;
pub struct ConsumeMessageServiceGeneral<T, K> {
consume_message_concurrently_service: Option<Arc<T>>,
consume_message_orderly_service: Option<Arc<K>>,
}
impl<T, K> ConsumeMessageServiceGeneral<T, K> {
pub fn new(
consume_message_concurrently_service: Option<Arc<T>>,
consume_message_orderly_service: Option<Arc<K>>,
) -> Self {
Self {
consume_message_concurrently_service,
consume_message_orderly_service,
}
}
pub fn get_consume_message_concurrently_service_weak(&self) -> Option<Weak<T>> {
self.consume_message_concurrently_service.as_ref().map(Arc::downgrade)
}
}
impl<T, K> ConsumeMessageServiceGeneral<T, K>
where
T: ConsumeMessageServiceTrait,
K: ConsumeMessageServiceTrait,
{
pub fn start(&self) {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
let this = consume_message_concurrently_service.clone();
consume_message_concurrently_service.start(this);
}
if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
let this = consume_message_orderly_service.clone();
consume_message_orderly_service.start(this);
}
}
pub async fn shutdown(&self, await_terminate_millis: u64) {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
consume_message_concurrently_service
.shutdown(await_terminate_millis)
.await;
}
if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
consume_message_orderly_service.shutdown(await_terminate_millis).await;
}
}
pub fn update_core_pool_size(&self, core_pool_size: usize) {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
consume_message_concurrently_service.update_core_pool_size(core_pool_size);
}
if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
consume_message_orderly_service.update_core_pool_size(core_pool_size);
}
}
pub fn inc_core_pool_size(&self) {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
consume_message_concurrently_service.inc_core_pool_size();
}
if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
consume_message_orderly_service.inc_core_pool_size();
}
}
pub fn dec_core_pool_size(&self) {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
consume_message_concurrently_service.dec_core_pool_size();
}
if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
consume_message_orderly_service.dec_core_pool_size();
}
}
pub fn get_core_pool_size(&self) -> usize {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
return consume_message_concurrently_service.get_core_pool_size();
}
if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
return consume_message_orderly_service.get_core_pool_size();
}
num_cpus::get()
}
pub async fn consume_message_directly(
&self,
msg: MessageExt,
broker_name: Option<CheetahString>,
) -> ConsumeMessageDirectlyResult {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
consume_message_concurrently_service
.consume_message_directly(msg, broker_name)
.await
} else if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
consume_message_orderly_service
.consume_message_directly(msg, broker_name)
.await
} else {
ConsumeMessageDirectlyResult::new(
false,
true,
CMResult::CRThrowException,
CheetahString::from_static_str("ConsumeMessageServiceGeneral has no direct-consume service"),
0,
)
}
}
pub async fn submit_consume_request(
&self,
msgs: Vec<Arc<MessageExt>>,
process_queue: Arc<ProcessQueue>,
message_queue: MessageQueue,
dispatch_to_consume: bool,
) {
if let Some(consume_message_concurrently_service) = &self.consume_message_concurrently_service {
let this = consume_message_concurrently_service.clone();
consume_message_concurrently_service
.submit_consume_request(this, msgs, process_queue, message_queue, dispatch_to_consume)
.await;
} else if let Some(consume_message_orderly_service) = &self.consume_message_orderly_service {
let this = consume_message_orderly_service.clone();
consume_message_orderly_service
.submit_consume_request(this, msgs, process_queue, message_queue, dispatch_to_consume)
.await;
}
}
pub async fn submit_pop_consume_request(
&self,
msgs: Vec<MessageExt>,
process_queue: &PopProcessQueue,
message_queue: &MessageQueue,
) {
let _ = (msgs, process_queue, message_queue);
}
pub fn get_consume_message_concurrently_service(&self) -> Option<Arc<T>> {
self.consume_message_concurrently_service.as_ref().cloned()
}
}
pub struct ConsumeMessagePopServiceGeneral<T, K> {
consume_message_pop_concurrently_service: Option<Arc<T>>,
consume_message_pop_orderly_service: Option<Arc<K>>,
}
impl<T, K> ConsumeMessagePopServiceGeneral<T, K> {
pub fn new(
consume_message_pop_concurrently_service: Option<Arc<T>>,
consume_message_pop_orderly_service: Option<Arc<K>>,
) -> Self {
Self {
consume_message_pop_concurrently_service,
consume_message_pop_orderly_service,
}
}
}
impl<T, K> ConsumeMessagePopServiceGeneral<T, K>
where
T: ConsumeMessageServiceTrait,
K: ConsumeMessageServiceTrait,
{
pub fn start(&self) {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
let this = consume_message_pop_concurrently_service.clone();
consume_message_pop_concurrently_service.start(this);
}
if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
let this = consume_message_pop_orderly_service.clone();
consume_message_pop_orderly_service.start(this);
}
}
pub async fn shutdown(&self, await_terminate_millis: u64) {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
consume_message_pop_concurrently_service
.shutdown(await_terminate_millis)
.await;
}
if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
consume_message_pop_orderly_service
.shutdown(await_terminate_millis)
.await;
}
}
pub fn update_core_pool_size(&self, core_pool_size: usize) {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
consume_message_pop_concurrently_service.update_core_pool_size(core_pool_size);
}
if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
consume_message_pop_orderly_service.update_core_pool_size(core_pool_size);
}
}
pub fn inc_core_pool_size(&self) {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
consume_message_pop_concurrently_service.inc_core_pool_size();
}
if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
consume_message_pop_orderly_service.inc_core_pool_size();
}
}
pub fn dec_core_pool_size(&self) {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
consume_message_pop_concurrently_service.dec_core_pool_size();
}
if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
consume_message_pop_orderly_service.dec_core_pool_size();
}
}
pub fn get_core_pool_size(&self) -> usize {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
return consume_message_pop_concurrently_service.get_core_pool_size();
}
if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
return consume_message_pop_orderly_service.get_core_pool_size();
}
num_cpus::get()
}
pub(crate) async fn consume_message_directly(
&self,
msg: MessageExt,
broker_name: Option<CheetahString>,
) -> ConsumeMessageDirectlyResult {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
consume_message_pop_concurrently_service
.consume_message_directly(msg, broker_name)
.await
} else if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
consume_message_pop_orderly_service
.consume_message_directly(msg, broker_name)
.await
} else {
ConsumeMessageDirectlyResult::new(
false,
true,
CMResult::CRThrowException,
CheetahString::from_static_str("ConsumeMessagePopServiceGeneral has no direct-consume service"),
0,
)
}
}
pub async fn submit_consume_request(
&self,
msgs: Vec<Arc<MessageClientExt>>,
process_queue: Arc<ProcessQueue>,
message_queue: MessageQueue,
dispatch_to_consume: bool,
) {
let _ = (msgs, process_queue, message_queue, dispatch_to_consume);
}
pub async fn submit_pop_consume_request(
&self,
msgs: Vec<MessageExt>,
process_queue: &PopProcessQueue,
message_queue: &MessageQueue,
) {
if let Some(consume_message_pop_concurrently_service) = &self.consume_message_pop_concurrently_service {
let this = consume_message_pop_concurrently_service.clone();
consume_message_pop_concurrently_service
.submit_pop_consume_request(this, msgs, process_queue, message_queue)
.await;
} else if let Some(consume_message_pop_orderly_service) = &self.consume_message_pop_orderly_service {
let this = consume_message_pop_orderly_service.clone();
consume_message_pop_orderly_service
.submit_pop_consume_request(this, msgs, process_queue, message_queue)
.await;
}
}
}
#[allow(async_fn_in_trait)]
pub trait ConsumeMessageServiceTrait {
fn start(&self, this: Arc<Self>);
async fn shutdown(&self, await_terminate_millis: u64);
fn update_core_pool_size(&self, _core_pool_size: usize) {}
fn inc_core_pool_size(&self) {}
fn dec_core_pool_size(&self) {}
fn get_core_pool_size(&self) -> usize {
num_cpus::get()
}
async fn consume_message_directly(
&self,
msg: MessageExt,
broker_name: Option<CheetahString>,
) -> ConsumeMessageDirectlyResult;
async fn submit_consume_request(
&self,
this: Arc<Self>,
msgs: Vec<Arc<MessageExt>>,
process_queue: Arc<ProcessQueue>,
message_queue: MessageQueue,
dispatch_to_consume: bool,
);
async fn submit_pop_consume_request(
&self,
this: Arc<Self>,
msgs: Vec<MessageExt>,
process_queue: &PopProcessQueue,
message_queue: &MessageQueue,
);
}
pub trait ConsumeMessageService: ConsumeMessageServiceTrait {}
impl<T> ConsumeMessageService for T where T: ConsumeMessageServiceTrait + ?Sized {}
#[cfg(test)]
mod tests {
use super::*;
struct NoopConsumeMessageService;
impl ConsumeMessageServiceTrait for NoopConsumeMessageService {
fn start(&self, _this: Arc<Self>) {}
async fn shutdown(&self, _await_terminate_millis: u64) {}
async fn consume_message_directly(
&self,
_msg: MessageExt,
_broker_name: Option<CheetahString>,
) -> ConsumeMessageDirectlyResult {
ConsumeMessageDirectlyResult::default()
}
async fn submit_consume_request(
&self,
_this: Arc<Self>,
_msgs: Vec<Arc<MessageExt>>,
_process_queue: Arc<ProcessQueue>,
_message_queue: MessageQueue,
_dispatch_to_consume: bool,
) {
}
async fn submit_pop_consume_request(
&self,
_this: Arc<Self>,
_msgs: Vec<MessageExt>,
_process_queue: &PopProcessQueue,
_message_queue: &MessageQueue,
) {
}
}
fn assert_consume_message_service<T: ConsumeMessageService>() {}
#[test]
fn consume_message_service_java_name_is_blanket_implemented() {
assert_consume_message_service::<NoopConsumeMessageService>();
}
}