During the first minute of entering the main scheduler loop, if --load-average
authorZac Medico <zmedico@gentoo.org>
Tue, 29 Jul 2008 14:34:55 +0000 (14:34 -0000)
committerZac Medico <zmedico@gentoo.org>
Tue, 29 Jul 2008 14:34:55 +0000 (14:34 -0000)
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

pym/_emerge/__init__.py

index a9f28a79d4146b75e2b01087c04670a5a2c26d35..a153ea6f3934e6232beb0cbf5c795854af9bf4bd 100644 (file)
@@ -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)