diff --git a/lib/_emerge/Scheduler.py b/lib/_emerge/Scheduler.py index 614df9e783..50f3912903 100644 --- a/lib/_emerge/Scheduler.py +++ b/lib/_emerge/Scheduler.py @@ -229,6 +229,7 @@ def __init__( if max_jobs is None: max_jobs = 1 self._set_max_jobs(max_jobs) + self._jobs_merge_wait_threshold = myopts.get("--jobs-merge-wait-threshold") self._running_root = trees[trees._running_eroot]["root_config"] self.edebug = 0 if settings.get("PORTAGE_DEBUG", "") == "1": @@ -1792,6 +1793,18 @@ def _is_work_scheduled(self): def _running_job_count(self): return self._jobs + def _can_add_job(self): + if not super()._can_add_job(): + return False + + if ( + self._jobs_merge_wait_threshold is not None + and len(self._merge_wait_queue) >= self._jobs_merge_wait_threshold + ): + return False + + return True + def _schedule_tasks(self): while True: state_change = 0 diff --git a/lib/_emerge/main.py b/lib/_emerge/main.py index 465e20163d..cbd21865e9 100644 --- a/lib/_emerge/main.py +++ b/lib/_emerge/main.py @@ -1,4 +1,4 @@ -# Copyright 1999-2023 Gentoo Authors +# Copyright 1999-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import argparse @@ -165,6 +165,7 @@ def __contains__(self, s): "--getbinpkgonly": y_or_n, "--ignore-world": y_or_n, "--jobs": valid_integers, + "--jobs-merge-wait-threshold": valid_integers, "--keep-going": y_or_n, "--load-average": valid_floats, "--onlydeps-with-ideps": y_or_n, @@ -523,6 +524,10 @@ def parse_opts(tmpcmdline, silent=False): "help": "Specifies the number of packages to build " + "simultaneously.", "action": "store", }, + "--jobs-merge-wait-threshold": { + "help": "Specifies the maximum number of queued merges that can exist when starting a new job.", + "action": "store", + }, "--keep-going": { "help": "continue as much as possible after an error", "choices": true_y_or_n, @@ -1033,6 +1038,24 @@ def parse_opts(tmpcmdline, silent=False): myoptions.jobs = jobs + if myoptions.jobs_merge_wait_threshold == "True": + myoptions.jobs_merge_wait_threshold = None + + if myoptions.jobs_merge_wait_threshold: + try: + jobs_merge_wait_threshold = int(myoptions.jobs_merge_wait_threshold) + except ValueError: + jobs_merge_wait_threshold = 0 + + if jobs_merge_wait_threshold <= 0: + jobs_merge_wait_threshold = None + if not silent: + parser.error( + f"Invalid --jobs-merge-wait-threshold: '{myoptions.jobs_merge_wait_threshold}'\n" + ) + + myoptions.jobs_merge_wait_threshold = jobs_merge_wait_threshold + if myoptions.load_average == "True": myoptions.load_average = None diff --git a/man/emerge.1 b/man/emerge.1 index e30f5f813e..49419c4ed7 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -1,4 +1,4 @@ -.TH "EMERGE" "1" "May 2024" "Portage @VERSION@" "Portage" +.TH "EMERGE" "1" "Jun 2024" "Portage @VERSION@" "Portage" .SH "NAME" emerge \- Command\-line interface to the Portage system .SH "SYNOPSIS" @@ -693,6 +693,11 @@ Note that interactive packages currently force a setting of \fI\-\-jobs=1\fR. This issue can be temporarily avoided by specifying \fI\-\-accept\-properties=\-interactive\fR. .TP +.BR \-\-jobs\-merge\-wait\-threshold[=COUNT] +Specifies the maximum number of queued merges that can exist when +starting a new job. With no argument, removes a previous merge wait +threshold. +.TP .BR "\-\-keep\-going [ y | n ]" Continue as much as possible after an error. When an error occurs, dependencies are recalculated for remaining packages and any with