Dead-Code Cleaning

This commit is contained in:
Alexey
2026-10-31 12:19:16 +03:00
parent 61afd6c702
commit cecc8df758
40 changed files with 104 additions and 306 deletions
+11 -22
View File
@@ -7,6 +7,7 @@ use std::sync::Arc;
use std::time::{Duration, Instant};
use rand::RngExt;
#[cfg(test)]
use tokio::sync::Semaphore;
use tokio::task::JoinSet;
use tracing::{debug, info, warn};
@@ -65,27 +66,17 @@ struct FamilyFloorPlan {
warm_cap_effective_total: usize,
active_writers_current: usize,
warm_writers_current: usize,
target_writers_total: usize,
}
#[derive(Debug)]
struct FamilyReconnectOutcome {
key: (i32, IpFamily),
dc: i32,
family: IpFamily,
required: usize,
endpoint_count: usize,
}
#[cfg(test)]
struct ScheduledReconnects<'a> {
inflight: &'a mut HashMap<(i32, IpFamily), usize>,
keys: Vec<(i32, IpFamily)>,
}
#[cfg(test)]
impl ScheduledReconnects<'_> {
fn current(&self, key: &(i32, IpFamily)) -> usize {
self.inflight.get(key).copied().unwrap_or(0)
}
fn reserve(&mut self, key: (i32, IpFamily)) {
self.keys.push(key);
@@ -93,6 +84,7 @@ impl ScheduledReconnects<'_> {
}
}
#[cfg(test)]
impl Drop for ScheduledReconnects<'_> {
fn drop(&mut self) {
for key in self.keys.drain(..) {
@@ -118,9 +110,9 @@ mod scheduler;
mod drain;
// Per-family reconnect scheduling and health state.
mod family;
// Adaptive-floor planning and warning rate limits.
// Adaptive-floor planning.
mod floor_plan;
// Idle-writer refresh and cap-aware swaps.
// Idle-writer refresh under the current capacity policy.
mod idle_refresh;
// Single-endpoint recovery and shadow rotation.
mod recovery;
@@ -128,18 +120,15 @@ mod recovery;
mod zombie_watchdog;
pub use drain::me_drain_timeout_enforcer;
pub(in crate::transport::middle_proxy) use drain::{
health_drain_close_budget, reap_draining_writers,
};
#[cfg(test)]
pub(in crate::transport::middle_proxy) use drain::health_drain_close_budget;
pub(in crate::transport::middle_proxy) use drain::reap_draining_writers;
use family::{check_family, update_family_runtime_state};
use floor_plan::{
build_family_floor_plan, live_active_writers_for_dc_family, should_emit_rate_limited_warn,
};
use idle_refresh::{maybe_refresh_idle_writer_for_dc, maybe_swap_idle_writer_for_cap};
use floor_plan::build_family_floor_plan;
use idle_refresh::maybe_refresh_idle_writer_for_dc;
pub use monitor::me_health_monitor;
use recovery::{
has_bound_clients_on_endpoint, maybe_rotate_single_endpoint_shadow,
recover_single_endpoint_outage,
};
pub use zombie_watchdog::me_zombie_writer_watchdog;
@@ -1,56 +1,6 @@
use super::*;
pub(super) fn should_emit_rate_limited_warn(
next_allowed: &mut HashMap<(i32, IpFamily), Instant>,
key: (i32, IpFamily),
now: Instant,
cooldown: Duration,
) -> bool {
let Some(ready_at) = next_allowed.get(&key).copied() else {
next_allowed.insert(key, now + cooldown);
return true;
};
if now >= ready_at {
next_allowed.insert(key, now + cooldown);
return true;
}
false
}
pub(super) async fn live_active_writers_for_dc_family(
pool: &Arc<MePool>,
dc: i32,
family: IpFamily,
) -> usize {
let active_generation = pool.current_generation();
let writers = pool.writers.read().await;
writers
.iter()
.filter(|writer| {
if writer.draining.load(std::sync::atomic::Ordering::Relaxed) {
return false;
}
if writer.writer_dc != dc {
return false;
}
if writer.generation != active_generation {
return false;
}
if !matches!(
crate::transport::middle_proxy::pool::WriterContour::from_u8(
writer.contour.load(std::sync::atomic::Ordering::Relaxed),
),
crate::transport::middle_proxy::pool::WriterContour::Active
) {
return false;
}
match family {
IpFamily::V4 => writer.addr.is_ipv4(),
IpFamily::V6 => writer.addr.is_ipv6(),
}
})
.count()
}
pub(super) fn adaptive_floor_class_min(
pool: &Arc<MePool>,
@@ -177,7 +127,6 @@ pub(super) async fn build_family_floor_plan(
warm_cap_effective_total: warm_cap_configured_total,
active_writers_current,
warm_writers_current,
target_writers_total: 0,
};
}
@@ -199,7 +148,6 @@ pub(super) async fn build_family_floor_plan(
warm_cap_effective_total: warm_cap_configured_total,
active_writers_current,
warm_writers_current,
target_writers_total: target_total,
};
}
@@ -251,7 +199,6 @@ pub(super) async fn build_family_floor_plan(
}
let active_cap_effective_total =
active_cap_configured_total.max(other_active.saturating_add(min_sum));
let target_writers_total = other_active.saturating_add(target_sum);
FamilyFloorPlan {
by_dc,
active_cap_configured_total,
@@ -260,6 +207,5 @@ pub(super) async fn build_family_floor_plan(
warm_cap_effective_total: warm_cap_configured_total,
active_writers_current,
warm_writers_current,
target_writers_total,
}
}
@@ -1,146 +1,5 @@
use super::*;
pub(super) async fn maybe_swap_idle_writer_for_cap(
pool: &Arc<MePool>,
rng: &Arc<SecureRandom>,
dc: i32,
family: IpFamily,
endpoints: &[SocketAddr],
required: usize,
floor_targets_by_dc: &HashMap<i32, usize>,
live_writer_ids_by_addr: &HashMap<(i32, SocketAddr), Vec<u64>>,
writer_idle_since: &HashMap<u64, u64>,
bound_clients_by_writer: &HashMap<u64, usize>,
) -> bool {
let Some(replacement_endpoint) = endpoints
.iter()
.min_by_key(|endpoint| {
live_writer_ids_by_addr
.get(&(dc, **endpoint))
.map_or(0, Vec::len)
})
.copied()
else {
return false;
};
let mut alive_by_dc = HashMap::<i32, usize>::new();
for ((writer_dc, endpoint), writer_ids) in live_writer_ids_by_addr {
if endpoint.is_ipv4() == matches!(family, IpFamily::V4) {
*alive_by_dc.entry(*writer_dc).or_insert(0) += writer_ids.len();
}
}
let now_epoch_secs = MePool::now_epoch_secs();
let mut candidates = Vec::<(u64, SocketAddr, i32, u64, usize)>::new();
for ((writer_dc, endpoint), writer_ids) in live_writer_ids_by_addr {
if endpoint.is_ipv4() != matches!(family, IpFamily::V4) {
continue;
}
let Some(donor_floor) = floor_targets_by_dc.get(writer_dc).copied() else {
continue;
};
if alive_by_dc.get(writer_dc).copied().unwrap_or(0) <= donor_floor {
continue;
}
for writer_id in writer_ids {
if bound_clients_by_writer.get(writer_id).copied().unwrap_or(0) > 0 {
continue;
}
let Some(idle_since_epoch_secs) = writer_idle_since.get(writer_id).copied() else {
continue;
};
candidates.push((
*writer_id,
*endpoint,
*writer_dc,
now_epoch_secs.saturating_sub(idle_since_epoch_secs),
donor_floor,
));
}
}
candidates.sort_unstable_by(|left, right| right.3.cmp(&left.3));
for (old_writer_id, donor_endpoint, donor_dc, idle_age_secs, donor_floor) in candidates {
let expected_role = {
let writers = pool.writers.read().await;
writers
.iter()
.find(|writer| writer.id == old_writer_id)
.map(WriterRole::from_writer)
};
let Some(expected_role) = expected_role else {
continue;
};
if expected_role.dc != donor_dc
|| expected_role.family != family
|| expected_role.contour != WriterContour::Active
{
continue;
}
let Some(mut reservation) = pool
.registry
.try_reserve_writer_replacement(old_writer_id)
.await
else {
continue;
};
let replace = pool.replace_writer_with_generation_contour_for_dc(
replacement_endpoint,
rng.as_ref(),
pool.current_generation(),
WriterContour::Active,
dc,
expected_role,
WriterReplacementPurpose::FloorRebalance {
donor_floor,
receiver_floor: required,
},
&mut reservation,
);
match tokio::time::timeout(pool.reconnect_runtime.me_one_timeout, replace).await {
Ok(Ok(())) => {
info!(
dc = %dc,
?family,
%replacement_endpoint,
donor_dc = %donor_dc,
%donor_endpoint,
old_writer_id,
idle_age_secs,
"Adaptive floor cap rebalance committed"
);
return true;
}
Ok(Err(error)) => {
debug!(
dc = %dc,
?family,
%replacement_endpoint,
donor_dc = %donor_dc,
old_writer_id,
idle_age_secs,
%error,
"Adaptive floor cap rebalance failed"
);
return false;
}
Err(_) => {
debug!(
dc = %dc,
?family,
%replacement_endpoint,
donor_dc = %donor_dc,
old_writer_id,
idle_age_secs,
"Adaptive floor cap rebalance timed out"
);
return false;
}
}
}
false
}
pub(super) async fn maybe_refresh_idle_writer_for_dc(
pool: &Arc<MePool>,
@@ -15,6 +15,7 @@ pub(super) fn has_bound_clients_on_endpoint(
}
/// Restores missing single-endpoint coverage under the bounded outage retry policy.
#[cfg(test)]
pub(super) async fn recover_single_endpoint_outage(
pool: &Arc<MePool>,
rng: &Arc<SecureRandom>,
+1
View File
@@ -169,6 +169,7 @@ impl MePool {
}
/// Applies the configured or HTTP-detected NAT IP to non-public addresses.
#[cfg(test)]
pub(super) fn translate_ip_for_nat(&self, ip: IpAddr) -> IpAddr {
Self::translate_ip_with_nat(
ip,
-16
View File
@@ -193,22 +193,6 @@ impl MePool {
self.refill_states.lock().contains_key(&key)
}
pub(super) async fn connect_endpoints_round_robin(
self: &Arc<Self>,
dc: i32,
endpoints: &[SocketAddr],
rng: &SecureRandom,
) -> bool {
self.connect_endpoints_round_robin_with_generation_contour(
dc,
endpoints,
rng,
self.current_generation(),
WriterContour::Active,
WriterOpenIntent::Normal,
)
.await
}
pub(super) async fn connect_endpoints_round_robin_with_generation_contour(
self: &Arc<Self>,
@@ -378,6 +378,7 @@ impl MePool {
}
/// Returns the currently authoritative endpoint set for drain and coverage decisions.
#[cfg(test)]
pub(in crate::transport::middle_proxy) async fn desired_dc_endpoints(
&self,
) -> HashMap<i32, HashSet<SocketAddr>> {
@@ -169,14 +169,6 @@ impl MePool {
}
}
/// Reconciles one immutable endpoint snapshot without draining uncovered groups.
pub async fn zero_downtime_reinit_after_map_change(
self: &Arc<Self>,
rng: &SecureRandom,
) -> bool {
let endpoint_snapshot = self.endpoint_snapshot.load_full();
self.reinit_endpoint_snapshot(rng, endpoint_snapshot).await
}
/// Reconciles exactly the revision owned by the scheduler's retry objective.
pub(in crate::transport::middle_proxy) async fn reinit_endpoint_snapshot(
@@ -417,8 +409,4 @@ impl MePool {
true
}
/// Applies periodic rotation using the same coverage and generation fences as map changes.
pub async fn zero_downtime_reinit_periodic(self: &Arc<Self>, rng: &SecureRandom) -> bool {
self.zero_downtime_reinit_after_map_change(rng).await
}
}
@@ -55,6 +55,10 @@ pub(super) enum WriterReplacementPurpose {
/// Replaces an idle writer before the upstream idle lifetime expires.
IdleRefresh,
/// Moves one idle slot from a donor above floor to a receiver below floor.
#[cfg_attr(
not(test),
expect(dead_code, reason = "Legacy purpose is exercised by commit-fence regression tests")
)]
FloorRebalance {
/// Minimum writer count that must remain in the donor group.
donor_floor: usize,
@@ -152,6 +152,7 @@ impl MePool {
/// Commits writer visibility and lifecycle ownership after all cancellation points.
#[allow(clippy::too_many_arguments)]
#[cfg(test)]
pub(in crate::transport::middle_proxy) async fn publish_prepared_writer<F>(
self: &Arc<Self>,
writer: MeWriter,
@@ -407,37 +407,6 @@ impl MePool {
removed
}
pub(crate) async fn mark_writer_draining_with_timeout(
self: &Arc<Self>,
writer_id: u64,
timeout: Option<Duration>,
allow_drain_fallback: bool,
) {
let timeout = timeout.filter(|d| !d.is_zero());
let found = {
let ws = self.writers.write().await;
let mut registry_registration = self.registry.prepare_writer_registration().await;
if let Some(w) = ws.iter().find(|w| w.id == writer_id) {
if !allow_drain_fallback {
registry_registration.retire(writer_id);
}
self.apply_writer_draining_state(w, timeout, allow_drain_fallback);
true
} else {
false
}
};
if !found {
return;
}
let timeout_secs = timeout.map(|d| d.as_secs()).unwrap_or(0);
debug!(
writer_id,
timeout_secs, allow_drain_fallback, "ME writer marked draining"
);
}
/// Publishes drain metadata before the release-store that makes draining observable.
pub(in crate::transport::middle_proxy) fn apply_writer_draining_state(
@@ -472,10 +441,6 @@ impl MePool {
!already_draining
}
pub(crate) async fn mark_writer_draining(self: &Arc<Self>, writer_id: u64) {
self.mark_writer_draining_with_timeout(writer_id, Some(Duration::from_secs(300)), false)
.await;
}
pub(in crate::transport::middle_proxy) fn writer_accepts_new_binding(
&self,
+4
View File
@@ -180,6 +180,8 @@ impl ConnRegistry {
.as_secs()
}
/// Creates a test registry with the requested route channel capacity.
#[cfg(test)]
pub fn with_route_channel_capacity(route_channel_capacity: usize) -> Self {
let route_channel_capacity = route_channel_capacity.max(1);
Self::with_route_limits(
@@ -288,6 +290,8 @@ impl ConnRegistry {
.store(watermark, Ordering::Relaxed);
}
/// Registers a test route without a lifetime cleanup lease.
#[cfg(test)]
pub async fn register(&self) -> (u64, mpsc::Receiver<MeResponse>) {
self.register_route()
}
@@ -348,6 +348,8 @@ impl ConnRegistry {
WriterBindOutcome::Bound
}
/// Binds a test route and reports whether publication succeeded.
#[cfg(test)]
pub async fn bind_writer(&self, conn_id: u64, writer_id: u64, meta: ConnMeta) -> bool {
matches!(
self.bind_writer_with_outcome(conn_id, writer_id, meta)