summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-29 14:34:55 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-29 14:34:55 +0000
commite4efa726d065712d39c4d61b7babc5a8278ff54d (patch)
tree4fb4233226d16595d32cb37fca58b90b1425c3fd
parentb1b65de9604dab4824664f091f7884c2b48bfdf7 (diff)
downloadportage-e4efa726d065712d39c4d61b7babc5a8278ff54d.tar.gz
portage-e4efa726d065712d39c4d61b7babc5a8278ff54d.tar.bz2
portage-e4efa726d065712d39c4d61b7babc5a8278ff54d.zip
During the first minute of entering the main scheduler loop, if --load-average
is enabled then limit the rate that new jobs are spawned, so that the load average measurement has time to respond to the new load introduced by the new jobs. The time between spawning new jobs is proportional to the number of currently running jobs. svn path=/main/trunk/; revision=11263
-rw-r--r--pym/_emerge/__init__.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index a9f28a79d..a153ea6f3 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -8860,6 +8860,17 @@ class Scheduler(PollScheduler):
self._max_load = myopts.get("--load-average")
+ # The load average takes some time to respond when new
+ # jobs are added, so we need to limit the rate of adding
+ # new jobs when emerge first starts.
+ self._main_loop_init_delay_period = 60
+ self._job_delay_factor = 0.5
+
+ # State variables
+ self._main_loop_init_delay = None
+ self._previous_job_start_time = None
+ self._main_loop_start_time = None
+
self._set_digraph(digraph)
# This is used to memoize the _choose_pkg() result when
@@ -9625,6 +9636,8 @@ class Scheduler(PollScheduler):
self._config_pool[settings["ROOT"]].append(settings)
def _main_loop(self):
+ self._main_loop_init_delay = self._max_load is not None
+ self._main_loop_start_time = time.time()
# Only allow 1 job max if a restart is scheduled
# due to portage update.
@@ -9656,6 +9669,26 @@ class Scheduler(PollScheduler):
self._status_display.display()
return remaining
+ def _job_delay(self):
+ """
+ @rtype: bool
+ @returns: True if job scheduling should be delayed, False otherwise.
+ """
+
+ if self._main_loop_init_delay and self._jobs:
+
+ current_time = time.time()
+
+ if current_time - self._main_loop_start_time > \
+ self._main_loop_init_delay_period:
+ self._main_loop_init_delay = False
+
+ elif current_time - self._previous_job_start_time < \
+ self._job_delay_factor * self._jobs:
+ return True
+
+ return False
+
def _schedule_tasks_imp(self):
"""
@rtype: bool
@@ -9669,6 +9702,9 @@ class Scheduler(PollScheduler):
if not self._pkg_queue or self._failed_pkgs:
return (False, state_change)
+ if self._job_delay():
+ return (True, state_change)
+
if self._choose_pkg_return_early or \
not self._can_add_job():
return (True, state_change)
@@ -9691,12 +9727,14 @@ class Scheduler(PollScheduler):
elif pkg.built:
self._jobs += 1
+ self._previous_job_start_time = time.time()
self._status_display.running = self._jobs
task.addExitListener(self._extract_exit)
self._task_queues.jobs.add(task)
else:
self._jobs += 1
+ self._previous_job_start_time = time.time()
self._status_display.running = self._jobs
task.addExitListener(self._build_exit)
self._task_queues.jobs.add(task)