bufferbloat fixes, deadlocks and buf sizes change

This commit is contained in:
2026-04-16 13:14:16 +07:00
parent f5f1d20f54
commit 2d70f33257
12 changed files with 191 additions and 211 deletions
+31 -29
View File
@@ -1,6 +1,6 @@
use bytes::Bytes;
use dashmap::DashMap;
use netrunner_logger::{debug, info, trace, warn};
use netrunner_logger::{info, trace, warn};
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Instant;
@@ -54,9 +54,9 @@ impl IdGenerator {
#[derive(Clone)]
pub struct MuxMessage {
pub stream_id: u32,
pub frame_type: FrameType,
pub data: Bytes,
pub(crate) stream_id: u32,
pub(crate) frame_type: FrameType,
pub(crate) data: Bytes,
}
pub static GLOBAL_MIN_RTT: AtomicU32 = AtomicU32::new(250);
@@ -102,11 +102,13 @@ impl Muxer {
stats: Arc::new(LegStats::default()),
},
);
info!(leg_id, "MUXER: Leg registered (Total: {})", self.legs.len());
info!(
leg_id,
"MUXER: Physical TCP+TLS leg registered (Total: {})",
self.legs.len()
);
}
// 🔥 ФИКС: Умное удаление ноги. Мы проверяем, не была ли эта нога уже перезаписана
// более новым подключением (чтобы не удалить живую ногу по ошибке)
pub fn remove_leg(&self, leg_id: u32, tx: &Sender<MuxMessage>) {
let should_remove = if let Some(leg) = self.legs.get(&leg_id) {
leg.control_tx.same_channel(tx)
@@ -116,7 +118,10 @@ impl Muxer {
if should_remove {
self.legs.remove(&leg_id);
info!(leg_id, "MUXER: Leg removed safely, streams will re-balance");
info!(
leg_id,
"MUXER: TCP leg removed safely, streams will re-balance"
);
} else {
trace!(
leg_id,
@@ -126,7 +131,7 @@ impl Muxer {
}
pub fn remove_all_legs(&self) {
warn!("🚨 MUXER: Emergency reset! Removing all legs due to network change.");
warn!("🚨 MUXER: Emergency reset! Removing all physical legs due to network change.");
self.legs.clear();
self.stream_bindings.clear();
}
@@ -181,7 +186,7 @@ impl Muxer {
let rtt = start_time.elapsed().as_millis() as u32;
if let Some(leg) = self.legs.get(&leg_id) {
leg.stats.rtt_ms.store(rtt, Ordering::Relaxed);
trace!(leg_id, rtt, "💓 [Muxer] RTT updated for leg");
trace!(leg_id, rtt, "💓 [Muxer] RTT updated for physical leg");
let min_rtt = self
.legs
@@ -208,7 +213,7 @@ impl Muxer {
let (leg_id, leg) = match self.select_leg(&message.frame_type, message.stream_id) {
Some(l) => l,
None => return Err("MUXER: No active legs available".to_string()),
None => return Err("MUXER: No active physical legs available".to_string()),
};
let target_tx = match message.frame_type {
@@ -220,7 +225,7 @@ impl Muxer {
};
match tokio::time::timeout(
std::time::Duration::from_secs(2),
std::time::Duration::from_secs(10),
target_tx.send(message.clone()),
)
.await
@@ -243,7 +248,7 @@ impl Muxer {
Err(_) => {
warn!(
message.stream_id,
"Physical TX full for 2s! Leg {} is dead. Evicting.", leg_id
"Physical TCP TX full for 10s! Leg {} is dead. Evicting.", leg_id
);
self.remove_leg(leg_id, &leg.control_tx);
continue;
@@ -271,7 +276,7 @@ impl Muxer {
.await
}
pub async fn send_control(
pub(crate) async fn send_control(
&self,
stream_id: u32,
f_type: FrameType,
@@ -303,17 +308,16 @@ impl Muxer {
if let Some((tx, stats)) = stream_opt {
let size = data.len() as u64;
match tx.try_send(data) {
// 🔥 КЛЮЧЕВОЙ ФИКС: Используем .send().await
// Мы больше не выбрасываем пакеты! Мы ждем, пока освободится очередь.
// Это создает естественный TCP Backpressure на стороне сервера.
match tx.send(data).await {
Ok(_) => {
stats.rx_bytes.fetch_add(size, Ordering::Relaxed);
}
Err(tokio::sync::mpsc::error::TrySendError::Full(_)) => {
trace!(
stream_id,
"Local RX queue full. Dropped packet for inner-TCP backpressure."
);
}
Err(tokio::sync::mpsc::error::TrySendError::Closed(_)) => {
Err(_) => {
// Канал закрыт (клиент отвалился)
self.remove_stream(stream_id);
}
}
@@ -360,10 +364,10 @@ impl Muxer {
match tokio::time::timeout(crate::net::HEALTH_CHECK_TIMEOUT, probe_rx.recv()).await {
Ok(Some(_)) => {
trace!(leg_id, "✅ Leg Health Check OK");
trace!(leg_id, " TCP Leg Health Check OK");
}
_ => {
warn!(leg_id, "❌ Leg Health Check FAIL/Timeout - Evicting");
warn!(leg_id, " TCP Leg Health Check FAIL/Timeout - Evicting");
self.remove_leg(leg_id, &tx);
}
}
@@ -407,7 +411,6 @@ impl Muxer {
total_tx += tx;
total_rx += rx;
let leg_type = if id % 2 == 0 { "TCP" } else { "UDP" };
let rtt_str = if rtt == 0 {
"N/A".to_string()
} else {
@@ -415,9 +418,8 @@ impl Muxer {
};
legs_info.push(format!(
" ├─ Leg {} ({}) ─ ⇡ {:<9} | ⇣ {:<9} [RTT: {}]",
" ├─ Leg {} (TCP+TLS) ─ ⇡ {:<9} | ⇣ {:<9} [RTT: {}]",
id,
leg_type,
Self::format_size(tx),
Self::format_size(rx),
rtt_str
@@ -430,7 +432,7 @@ impl Muxer {
Self::format_size(total_rx)
));
out.push_str(&format!(
"├─ 🦵 Physical Legs (Active: {})\n",
"├─ 🦵 Physical Connections (Active: {})\n",
legs_info.len()
));
@@ -444,7 +446,7 @@ impl Muxer {
let streams_count = self.streams.len();
out.push_str(&format!(
"└─ 🔀 Virtual Streams (Active: {})\n",
"└─ 🔀 Virtual Streams (TCP/UDP multiplexed: {})\n",
streams_count
));