This commit is contained in:
Mateusz Gruszczyński committed 2026-10-04 09:29:10 +02:00
1 parent 2e4aa4df4d
commit 87e571c170
106 files changed
+17952 -6185

No files matched your search

+33 -3
View File
@@ -40,6 +40,7 @@ pub struct App {
pub certificate_slots: Arc<Semaphore>,
pub metrics: Arc<Metrics>,
pub transform_metrics: Arc<crate::transform::Metrics>,
pub traffic: Arc<crate::traffic::Analytics>,
pub cache: Arc<crate::cache::Cache>,
pub geoip: Arc<crate::geoip::Database>,
pub rate_limiter: Arc<crate::rate_limit::Limiter>,
@@ -271,6 +272,7 @@ impl App {
}
}
let logs = Logs::start(log_settings, shutdown.clone());
let traffic = crate::traffic::Analytics::start(shutdown.clone());
let app = Arc::new(Self {
basic_workers: Arc::new(Semaphore::new(2)),
basic_limits: Default::default(),
@@ -298,6 +300,7 @@ impl App {
certificate_slots: Arc::new(Semaphore::new(2)),
metrics: Arc::new(Metrics::default()),
transform_metrics: Arc::new(crate::transform::Metrics::default()),
traffic,
logs,
software_update: Arc::new(crate::update_check::SharedStatus::default()),
shutdown,
@@ -323,6 +326,23 @@ impl App {
Arc::downgrade(&app),
app.shutdown.clone(),
));
// High request rates create short-lived allocations in Hyper/Tokio and
// cache fill paths. glibc may retain already-free arenas as RSS. Trim
// them periodically without evicting live cache objects or connections.
let trim_shutdown = app.shutdown.clone();
app.tunnels.spawn(async move {
let mut tick = tokio::time::interval(Duration::from_secs(60));
tick.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
tick.tick().await;
loop {
tokio::select! {
_ = trim_shutdown.cancelled() => break,
_ = tick.tick() => {
let _ = tokio::task::spawn_blocking(crate::diagnostics::trim_allocator).await;
}
}
}
});
app
}
pub fn start_update_check(self: &Arc<Self>, config: crate::update_check::Config) {
@@ -465,9 +485,15 @@ impl App {
/// resolver is rebuilt as one validated snapshot, so the requested pair is
/// re-read atomically with the other configured pairs while desired
/// configuration and its revision remain unchanged.
pub async fn reload_certificate(self: &Arc<Self>, certificate_id: &str) -> Result<u64, ApiError> {
pub async fn reload_certificate(
self: &Arc<Self>,
certificate_id: &str,
) -> Result<u64, ApiError> {
if !crate::config::valid_id(certificate_id) {
return Err(ApiError(StatusCode::NOT_FOUND, "certificate not found".into()));
return Err(ApiError(
StatusCode::NOT_FOUND,
"certificate not found".into(),
));
}
self.reload_certificate_snapshot(Some(certificate_id)).await
}
@@ -526,7 +552,11 @@ impl App {
.map_err(|error| ApiError(StatusCode::UNPROCESSABLE_ENTITY, format!("{error:#}")))?;
self.config.store(Arc::new(prepared));
if let Some(certificate_id) = certificate_id {
tracing::info!(revision, certificate_id, "configured certificate reloaded from disk");
tracing::info!(
revision,
certificate_id,
"configured certificate reloaded from disk"
);
} else {
tracing::info!(revision, "configured certificates reloaded from disk");
}