fix(daemon): ask the OS for enough open files, and stop spinning when it says no
A search fans out to hundreds of peers, each holding a socket. A shell hands its children a soft limit of 256 open files on macOS, which one busy search blows straight through; a one-shot command never noticed because it exited before it mattered, but a resident daemon hits it and then cannot accept peers or control connections. From a client that looks like 'cannot reach the daemon: Connection closed', intermittently, for no visible reason. The daemon now raises its own soft limit to 8192 at startup, before anything opens a socket, and says so plainly when the hard limit will not allow it. macOS rejects an unlimited hard limit for open files, so both fields are named. Both accept loops also slept zero on failure. Out of descriptors does not clear by the next instruction, so one exhausted moment became a spinning core and thousands of identical log lines — which is what the report looked like. They now back off.
This commit is contained in:
@@ -13,6 +13,13 @@ use crate::types::Download;
|
||||
use crate::utils::lock::RwLockExt;
|
||||
use crate::{DownloadStatus, debug, error, info, trace};
|
||||
|
||||
/// How long to wait before accepting again after a failure.
|
||||
///
|
||||
/// The failure worth pausing for is running out of file descriptors, which a
|
||||
/// busy search can reach: it does not clear by the next instruction, and
|
||||
/// retrying flat out spins a core and floods the log.
|
||||
const ACCEPT_BACKOFF: Duration = Duration::from_millis(100);
|
||||
|
||||
const PEER_INIT_MESSAGE_CODE: u8 = 1;
|
||||
|
||||
/// How long an accepted peer gets to send its peer-init handshake.
|
||||
@@ -406,6 +413,11 @@ impl Listen {
|
||||
"[listener] Failed to accept connection: {}",
|
||||
stream.unwrap_err()
|
||||
);
|
||||
// Running out of file descriptors does not clear by the next
|
||||
// instruction, and retrying flat out turns one exhausted
|
||||
// moment into a spinning core and thousands of identical log
|
||||
// lines. Pause long enough for something to be released.
|
||||
std::thread::sleep(ACCEPT_BACKOFF);
|
||||
continue;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user