-
Notifications
You must be signed in to change notification settings - Fork 251
restrict rest workers based on open files limit #4108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
58ceadb
d55e2b3
5821c8a
56c9b8d
d1f8e70
c452b51
502a853
9d534d8
eab2fea
f3af316
d83678c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,12 +43,28 @@ const uint32_t AVAILABLE_CORES = getCoreCount(); | |||||||||||||||||||||||||||||||||
| const uint32_t WIN_MAX_GRPC_WORKERS = 1; | ||||||||||||||||||||||||||||||||||
| const uint32_t MAX_PORT_NUMBER = std::numeric_limits<uint16_t>::max(); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // For drogon, we need to minimize the number of default workers since this value is set for both: unary and streaming (making it always double) | ||||||||||||||||||||||||||||||||||
| const uint64_t DEFAULT_REST_WORKERS = AVAILABLE_CORES; | ||||||||||||||||||||||||||||||||||
| const uint32_t DEFAULT_GRPC_MAX_THREADS = AVAILABLE_CORES * 8.0; | ||||||||||||||||||||||||||||||||||
| const size_t DEFAULT_GRPC_MEMORY_QUOTA = (size_t)2 * 1024 * 1024 * 1024; // 2GB | ||||||||||||||||||||||||||||||||||
| const uint64_t MAX_REST_WORKERS = 10'000; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // We need to minimize the number of default drogon workers since this value is set for both: unary and streaming (making it always double) | ||||||||||||||||||||||||||||||||||
| // on linux, restrict also based on the max allowed number of open files | ||||||||||||||||||||||||||||||||||
| #ifdef __linux__ | ||||||||||||||||||||||||||||||||||
| #include <sys/resource.h> | ||||||||||||||||||||||||||||||||||
| const uint64_t MAX_OPEN_FILES = []() { | ||||||||||||||||||||||||||||||||||
| struct rlimit limit; | ||||||||||||||||||||||||||||||||||
| if (getrlimit(RLIMIT_NOFILE, &limit) == 0) { | ||||||||||||||||||||||||||||||||||
| return limit.rlim_cur; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| return std::numeric_limits<uint64_t>::max(); | ||||||||||||||||||||||||||||||||||
| }(); | ||||||||||||||||||||||||||||||||||
| const uint64_t RESERVED_OPEN_FILES = 10; // we need to reserve some file descriptors for other operations, so we don't want to use all of them for drogon workers | ||||||||||||||||||||||||||||||||||
| const uint64_t DEFAULT_REST_WORKERS = (MAX_OPEN_FILES <= RESERVED_OPEN_FILES) ? AVAILABLE_CORES | ||||||||||||||||||||||||||||||||||
| : std::min(static_cast<uint64_t>(AVAILABLE_CORES), (MAX_OPEN_FILES - RESERVED_OPEN_FILES) / 5); | ||||||||||||||||||||||||||||||||||
|
dtrawins marked this conversation as resolved.
Outdated
|
||||||||||||||||||||||||||||||||||
| #else | ||||||||||||||||||||||||||||||||||
| const uint64_t DEFAULT_REST_WORKERS = AVAILABLE_CORES; | ||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Config& Config::parse(int argc, char** argv) { | ||||||||||||||||||||||||||||||||||
| ovms::CLIParser parser; | ||||||||||||||||||||||||||||||||||
| ovms::ServerSettingsImpl serverSettings; | ||||||||||||||||||||||||||||||||||
|
|
@@ -306,6 +322,12 @@ bool Config::validate() { | |||||||||||||||||||||||||||||||||
| std::cerr << "rest_workers is set but rest_port is not set. rest_port is required to start rest servers" << std::endl; | ||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| #ifdef __linux__ | ||||||||||||||||||||||||||||||||||
| if (restWorkers() > (MAX_OPEN_FILES - RESERVED_OPEN_FILES) / 5) { | ||||||||||||||||||||||||||||||||||
| std::cerr << "rest_workers count cannot be larger than " << (MAX_OPEN_FILES - RESERVED_OPEN_FILES) / 5 << " due to open files limit. Current open files limit: " << MAX_OPEN_FILES << std::endl; | ||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
| if (restWorkers() > (MAX_OPEN_FILES - RESERVED_OPEN_FILES) / 5) { | |
| std::cerr << "rest_workers count cannot be larger than " << (MAX_OPEN_FILES - RESERVED_OPEN_FILES) / 5 << " due to open files limit. Current open files limit: " << MAX_OPEN_FILES << std::endl; | |
| return false; | |
| } | |
| if (MAX_OPEN_FILES <= RESERVED_OPEN_FILES) { | |
| std::cerr << "Open files limit (" << MAX_OPEN_FILES | |
| << ") is too low to run REST workers. Increase the RLIMIT_NOFILE soft limit " | |
| << "or adjust the server configuration." << std::endl; | |
| return false; | |
| } | |
| const uint64_t maxRestWorkersByFiles = (MAX_OPEN_FILES - RESERVED_OPEN_FILES) / 5; | |
| if (restWorkers() > maxRestWorkersByFiles) { | |
| std::cerr << "rest_workers count cannot be larger than " << maxRestWorkersByFiles | |
| << " due to open files limit. Current open files limit: " << MAX_OPEN_FILES << std::endl; | |
| return false; | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |||||||||||||
| #include <filesystem> | ||||||||||||||
| #include <fstream> | ||||||||||||||
| #include <regex> | ||||||||||||||
| #include <sys/resource.h> | ||||||||||||||
|
||||||||||||||
| #include <regex> | |
| #include <sys/resource.h> | |
| #include <regex> | |
| #ifdef __linux__ | |
| #include <sys/resource.h> | |
| #endif |
Copilot
AI
Apr 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test comment says the open-files limit is set to 1024, but the code actually sets it to cpu_cores * 5. Please update the comment to match the behavior (or adjust the limit if 1024 is intended).
Copilot
AI
Apr 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setrlimit(RLIMIT_NOFILE, ...) can fail if newLimit.rlim_cur exceeds limit.rlim_max (or if the process lacks permission to change limits). As written, cpu_cores * 5 might be > rlim_max on some systems/containers, making this test flaky. Consider clamping rlim_cur to limit.rlim_max and/or skipping the test with a clear message when the limit cannot be adjusted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test doesnt check if number of workers has been changed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
never mind, it would require calculation how many cores the machine has
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If test exits earlier we won't restore original rlimit value. Need either unique_ptr with custom deleter to handle that or helper struct. The same is true for previous test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include <sys/resource.h>is placed insidenamespace ovms(and mid-file). Including system headers inside a namespace can unintentionally put all their declarations/types into that namespace and create subtle lookup/type issues. Move this include up with the other includes at file scope (outside the namespace) and keep only the constants insideovms.