From cdadc739cd267e736d30c5bee111bbd0326c974b Mon Sep 17 00:00:00 2001 From: Emily Date: Thu, 18 Jul 2024 12:47:36 +0100 Subject: [PATCH] libstore: add load-limit setting to control parallelism Closes: #7091 Closes: #6855 Closes: #8105 Co-authored-by: Alex Wied --- doc/manual/src/release-notes/rl-next.md | 4 ++ src/libstore/daemon.cc | 2 + src/libstore/globals.cc | 19 ++++++++ src/libstore/globals.hh | 48 ++++++++++++++++++- .../unix/build/local-derivation-goal.cc | 4 ++ src/nix-build/nix-build.cc | 2 + tests/functional/load-limit.nix | 8 ++++ tests/functional/load-limit.sh | 21 ++++++++ tests/functional/local.mk | 1 + 9 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 doc/manual/src/release-notes/rl-next.md create mode 100644 tests/functional/load-limit.nix create mode 100644 tests/functional/load-limit.sh diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md new file mode 100644 index 000000000000..869dcb3befc9 --- /dev/null +++ b/doc/manual/src/release-notes/rl-next.md @@ -0,0 +1,4 @@ +# Release X.Y (202?-??-??) + +- Add a `load-limit` setting to control builder parallelism. This has + also been backported to the 2.18 and later release branches. diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 6533b2f58c46..f94c7ae3f61c 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -199,6 +199,7 @@ struct ClientSettings time_t maxSilentTime; bool verboseBuild; unsigned int buildCores; + std::optional loadLimit; bool useSubstitutes; StringMap overrides; @@ -212,6 +213,7 @@ struct ClientSettings settings.maxSilentTime = maxSilentTime; settings.verboseBuild = verboseBuild; settings.buildCores = buildCores; + settings.loadLimit.assign(loadLimit); settings.useSubstitutes = useSubstitutes; for (auto & i : overrides) { diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index fa4c0ba7fad6..f62e86ba0a07 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -333,6 +333,25 @@ unsigned int MaxBuildJobsSetting::parse(const std::string & str) const } } +std::optional LoadLimitSetting::parse(const std::string & str) const +{ + if (str == "none") return std::nullopt; + else { + if (auto n = string2Int(str)) + return { *n }; + else + throw UsageError("configuration setting '%s' should be 'none' or an integer", name); + } +} + +std::string LoadLimitSetting::to_string() const +{ + if (value) + return std::to_string(value.value()); + else + return "none"; +} + static void preloadNSS() { diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 30d7537bd52b..e3394eebee24 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -31,6 +31,24 @@ struct MaxBuildJobsSetting : public BaseSetting unsigned int parse(const std::string & str) const override; }; +struct LoadLimitSetting : public Setting> +{ + LoadLimitSetting(Config * options, + const std::optional & def, + const std::string & name, + const std::string & description, + const std::set & aliases = {}, + const bool documentDefault = true, + std::optional experimentalFeature = std::nullopt) + : Setting>( + options, def, name, description, aliases, documentDefault, std::move(experimentalFeature)) + {} + + std::optional parse(const std::string & str) const override; + std::string to_string() const override; +}; + + const uint32_t maxIdsPerBuild = #if __linux__ 1 << 16 @@ -166,7 +184,6 @@ public: R"( Sets the value of the `NIX_BUILD_CORES` environment variable in the [invocation of the `builder` executable](@docroot@/language/derivations.md#builder-execution) of a derivation. The `builder` executable can use this variable to control its own maximum amount of parallelism. -