Fix Network listener: Accept loop spins all CPU cores with no back-off when the process hits EMFILE (too many open files)
This commit is contained in:
@@ -29,6 +29,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
|
||||
- CalDAV: `calendar-query` REPORT returns invalid HTTP `404` when no events match the query.
|
||||
- Snowflake past id generation fails when the provided duration is longer than 4 years.
|
||||
- Calendar scheduling: Wrong RSVP base URL is used.
|
||||
- Network listener: Accept loop spins all CPU cores with no back-off when the process hits `EMFILE` (too many open files).
|
||||
|
||||
## [0.16.11] - 2026-06-25
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ use rustls::crypto::aws_lc_rs::cipher_suite::TLS13_AES_128_GCM_SHA256;
|
||||
use std::{
|
||||
net::{IpAddr, SocketAddr},
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
use store::registry::bootstrap::Bootstrap;
|
||||
use tokio::{net::TcpStream, sync::watch};
|
||||
@@ -112,11 +113,17 @@ impl Listener {
|
||||
),
|
||||
};
|
||||
|
||||
const ACCEPT_BACKOFF: Duration = Duration::from_millis(5);
|
||||
const MAX_ACCEPT_BACKOFF: Duration = Duration::from_secs(1);
|
||||
let mut accept_backoff = ACCEPT_BACKOFF;
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
stream = listener.accept() => {
|
||||
match stream {
|
||||
Ok((stream, remote_addr)) => {
|
||||
accept_backoff = ACCEPT_BACKOFF;
|
||||
|
||||
let server = inner.build_server();
|
||||
let enable_acme = (is_https && server.has_acme_tls_providers()).then(|| server.clone());
|
||||
|
||||
@@ -160,6 +167,15 @@ impl Listener {
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
if matches!(
|
||||
err.kind(),
|
||||
std::io::ErrorKind::ConnectionAborted
|
||||
| std::io::ErrorKind::ConnectionReset
|
||||
| std::io::ErrorKind::Interrupted
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
Network(trc::NetworkEvent::AcceptError),
|
||||
ListenerId = instance.id.clone(),
|
||||
@@ -168,6 +184,16 @@ impl Listener {
|
||||
Tls = is_tls,
|
||||
Reason = err.to_string(),
|
||||
);
|
||||
|
||||
tokio::select! {
|
||||
_ = tokio::time::sleep(accept_backoff) => {}
|
||||
_ = shutdown_rx.changed() => {
|
||||
manager.shutdown().await;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
accept_backoff = (accept_backoff * 2).min(MAX_ACCEPT_BACKOFF);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user