2025-08-27 21:31:31 +08:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
2025-08-26 17:57:39 +08:00
|
|
|
use futures::StreamExt;
|
2025-07-19 23:46:42 +08:00
|
|
|
use solana_sdk::pubkey::Pubkey;
|
|
|
|
|
|
2025-08-18 01:08:12 +08:00
|
|
|
use crate::common::AnyResult;
|
2025-08-26 17:57:39 +08:00
|
|
|
use crate::protos::shredstream::SubscribeEntriesRequest;
|
|
|
|
|
use crate::streaming::common::{EventProcessor, SubscriptionHandle};
|
2025-08-18 01:08:12 +08:00
|
|
|
use crate::streaming::event_parser::common::filter::EventTypeFilter;
|
2025-09-14 01:13:11 +08:00
|
|
|
use crate::streaming::event_parser::common::high_performance_clock::get_high_perf_clock;
|
2025-08-18 01:08:12 +08:00
|
|
|
use crate::streaming::event_parser::{Protocol, UnifiedEvent};
|
2025-09-02 17:27:27 +08:00
|
|
|
use crate::streaming::shred::pool::factory;
|
2025-08-26 17:57:39 +08:00
|
|
|
use log::error;
|
|
|
|
|
use solana_entry::entry::Entry;
|
2025-08-11 01:04:16 +08:00
|
|
|
|
2025-08-18 01:08:12 +08:00
|
|
|
use super::ShredStreamGrpc;
|
2025-08-03 05:37:04 +08:00
|
|
|
|
2025-07-19 23:46:42 +08:00
|
|
|
impl ShredStreamGrpc {
|
2025-08-04 21:30:55 +08:00
|
|
|
/// 订阅ShredStream事件(支持批处理和即时处理)
|
2025-07-19 23:46:42 +08:00
|
|
|
pub async fn shredstream_subscribe<F>(
|
|
|
|
|
&self,
|
|
|
|
|
protocols: Vec<Protocol>,
|
|
|
|
|
bot_wallet: Option<Pubkey>,
|
2025-08-18 01:08:12 +08:00
|
|
|
event_type_filter: Option<EventTypeFilter>,
|
2025-07-19 23:46:42 +08:00
|
|
|
callback: F,
|
|
|
|
|
) -> AnyResult<()>
|
|
|
|
|
where
|
|
|
|
|
F: Fn(Box<dyn UnifiedEvent>) + Send + Sync + 'static,
|
|
|
|
|
{
|
2025-08-21 15:47:31 +08:00
|
|
|
// 如果已有活跃订阅,先停止它
|
|
|
|
|
self.stop().await;
|
|
|
|
|
|
|
|
|
|
let mut metrics_handle = None;
|
2025-08-04 21:30:55 +08:00
|
|
|
// 启动自动性能监控(如果启用)
|
|
|
|
|
if self.config.enable_metrics {
|
2025-08-21 15:47:31 +08:00
|
|
|
metrics_handle = self.metrics_manager.start_auto_monitoring().await;
|
2025-08-04 21:30:55 +08:00
|
|
|
}
|
2025-08-11 01:04:16 +08:00
|
|
|
|
2025-08-26 17:57:39 +08:00
|
|
|
// 创建事件处理器
|
|
|
|
|
let mut event_processor =
|
|
|
|
|
EventProcessor::new(self.metrics_manager.clone(), self.config.clone());
|
|
|
|
|
event_processor.set_protocols_and_event_type_filter(
|
2025-09-19 23:17:50 +08:00
|
|
|
super::common::EventSource::Shred,
|
2025-08-26 17:57:39 +08:00
|
|
|
protocols,
|
|
|
|
|
event_type_filter,
|
2025-08-27 21:31:31 +08:00
|
|
|
self.config.backpressure.clone(),
|
|
|
|
|
Some(Arc::new(callback)),
|
2025-08-26 17:57:39 +08:00
|
|
|
);
|
2025-08-11 01:04:16 +08:00
|
|
|
|
2025-08-26 17:57:39 +08:00
|
|
|
// 启动流处理
|
|
|
|
|
let mut client = (*self.shredstream_client).clone();
|
|
|
|
|
let request = tonic::Request::new(SubscribeEntriesRequest {});
|
|
|
|
|
let mut stream = client.subscribe_entries(request).await?.into_inner();
|
|
|
|
|
let event_processor_clone = event_processor.clone();
|
|
|
|
|
let stream_task = tokio::spawn(async move {
|
|
|
|
|
while let Some(message) = stream.next().await {
|
|
|
|
|
match message {
|
|
|
|
|
Ok(msg) => {
|
|
|
|
|
if let Ok(entries) = bincode::deserialize::<Vec<Entry>>(&msg.entries) {
|
|
|
|
|
for entry in entries {
|
|
|
|
|
for transaction in entry.transactions {
|
2025-09-14 01:13:11 +08:00
|
|
|
let transaction_with_slot =
|
|
|
|
|
factory::create_transaction_with_slot_pooled(
|
|
|
|
|
transaction.clone(),
|
|
|
|
|
msg.slot,
|
|
|
|
|
get_high_perf_clock(),
|
|
|
|
|
);
|
2025-08-31 22:18:18 +08:00
|
|
|
// 直接处理,背压控制在 EventProcessor 内部处理
|
|
|
|
|
if let Err(e) = event_processor_clone
|
|
|
|
|
.process_shred_transaction_with_metrics(
|
|
|
|
|
transaction_with_slot,
|
|
|
|
|
bot_wallet,
|
|
|
|
|
)
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
error!("Error handling message: {e:?}");
|
|
|
|
|
}
|
2025-08-26 17:57:39 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
Err(error) => {
|
|
|
|
|
error!("Stream error: {error:?}");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-08-21 15:47:31 +08:00
|
|
|
|
|
|
|
|
// 保存订阅句柄
|
2025-08-27 21:31:31 +08:00
|
|
|
let subscription_handle = SubscriptionHandle::new(stream_task, None, metrics_handle);
|
2025-08-21 15:47:31 +08:00
|
|
|
let mut handle_guard = self.subscription_handle.lock().await;
|
|
|
|
|
*handle_guard = Some(subscription_handle);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
2025-08-04 21:30:55 +08:00
|
|
|
}
|
2025-08-11 01:04:16 +08:00
|
|
|
}
|