Skip to content

Commit

Permalink
feat(cli): raise file descriptor limit on startup (denoland#10162)
Browse files Browse the repository at this point in the history
Raise the soft limit to the hard limit when possible. This is similar
to what Node.js does to avoid running into "out of file descriptors"
errors too quickly.

On most Linux systems, raises the limit from 1,024 to 1,048,576.
On most macOS systems, raises the limit from 256 to 10,240.

Fixes denoland#10148.
  • Loading branch information
bnoordhuis committed Apr 13, 2021
1 parent df49a84 commit d46b37f
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mod tokio_util;
mod tools;
mod tsc;
mod tsc_config;
mod unix_util;
mod version;

use crate::file_fetcher::File;
Expand Down Expand Up @@ -1176,6 +1177,7 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
pub fn main() {
#[cfg(windows)]
colors::enable_ansi(); // For Windows 10
unix_util::raise_fd_limit();

let args: Vec<String> = env::args().collect();
let standalone_res = match standalone::extract_standalone(args.clone()) {
Expand Down
2 changes: 2 additions & 0 deletions cli/main_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
mod colors;
mod standalone;
mod tokio_util;
mod unix_util;
mod version;

use deno_core::error::anyhow;
Expand All @@ -14,6 +15,7 @@ use std::env;
pub fn main() {
#[cfg(windows)]
colors::enable_ansi(); // For Windows 10
unix_util::raise_fd_limit();

let args: Vec<String> = env::args().collect();
if let Err(err) = run(args) {
Expand Down
41 changes: 41 additions & 0 deletions cli/unix_util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/// Raise soft file descriptor limit to hard file descriptor limit.
/// This is the difference between `ulimit -n` and `ulimit -n -H`.
pub fn raise_fd_limit() {
#[cfg(unix)]
unsafe {
let mut limits = libc::rlimit {
rlim_cur: 0,
rlim_max: 0,
};

if 0 != libc::getrlimit(libc::RLIMIT_NOFILE, &mut limits) {
return;
}

if limits.rlim_cur == libc::RLIM_INFINITY {
return;
}

// No hard limit? Do a binary search for the effective soft limit.
if limits.rlim_max == libc::RLIM_INFINITY {
let mut min = limits.rlim_cur;
let mut max = 1 << 20;

while min + 1 < max {
limits.rlim_cur = min + (max - min) / 2;
match libc::setrlimit(libc::RLIMIT_NOFILE, &limits) {
0 => min = limits.rlim_cur,
_ => max = limits.rlim_cur,
}
}

return;
}

// Raise the soft limit to the hard limit.
if limits.rlim_cur < limits.rlim_max {
limits.rlim_cur = limits.rlim_max;
libc::setrlimit(libc::RLIMIT_NOFILE, &limits);
}
}
}

0 comments on commit d46b37f

Please sign in to comment.