fix(rustproxy): Cancel connections for routes removed/disabled by adding per-route cancellation tokens and make RouteManager swappable (ArcSwap) for runtime updates

This commit is contained in:
2026-03-03 16:14:16 +00:00
parent bb471a8cc9
commit d51b2c5890
6 changed files with 81 additions and 20 deletions

View File

@@ -8,6 +8,7 @@ use std::collections::HashMap;
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use arc_swap::ArcSwap;
use bytes::Bytes;
use dashmap::DashMap;
use http_body_util::{BodyExt, Full, combinators::BoxBody};
@@ -133,7 +134,7 @@ async fn connect_tls_backend(
/// HTTP proxy service that processes HTTP traffic.
pub struct HttpProxyService {
route_manager: Arc<RouteManager>,
route_manager: Arc<ArcSwap<RouteManager>>,
metrics: Arc<MetricsCollector>,
upstream_selector: UpstreamSelector,
/// Timeout for connecting to upstream backends.
@@ -161,7 +162,7 @@ pub struct HttpProxyService {
}
impl HttpProxyService {
pub fn new(route_manager: Arc<RouteManager>, metrics: Arc<MetricsCollector>) -> Self {
pub fn new(route_manager: Arc<ArcSwap<RouteManager>>, metrics: Arc<MetricsCollector>) -> Self {
Self {
route_manager,
metrics,
@@ -182,7 +183,7 @@ impl HttpProxyService {
/// Create with a custom connect timeout.
pub fn with_connect_timeout(
route_manager: Arc<RouteManager>,
route_manager: Arc<ArcSwap<RouteManager>>,
metrics: Arc<MetricsCollector>,
connect_timeout: std::time::Duration,
) -> Self {
@@ -405,7 +406,8 @@ impl HttpProxyService {
protocol: Some("http"),
};
let route_match = match self.route_manager.find_route(&ctx) {
let current_rm = self.route_manager.load();
let route_match = match current_rm.find_route(&ctx) {
Some(rm) => rm,
None => {
debug!("No route matched for HTTP request to {:?}{}", host, path);
@@ -1759,7 +1761,7 @@ impl rustls::client::danger::ServerCertVerifier for InsecureBackendVerifier {
impl Default for HttpProxyService {
fn default() -> Self {
Self {
route_manager: Arc::new(RouteManager::new(vec![])),
route_manager: Arc::new(ArcSwap::from(Arc::new(RouteManager::new(vec![])))),
metrics: Arc::new(MetricsCollector::new()),
upstream_selector: UpstreamSelector::new(),
connect_timeout: DEFAULT_CONNECT_TIMEOUT,