| # Copyright 1999-2009 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| # $Id$ |
| |
| from _emerge.PollScheduler import PollScheduler |
| |
| class QueueScheduler(PollScheduler): |
| |
| """ |
| Add instances of SequentialTaskQueue and then call run(). The |
| run() method returns when no tasks remain. |
| """ |
| |
| def __init__(self, max_jobs=None, max_load=None): |
| PollScheduler.__init__(self) |
| |
| if max_jobs is None: |
| max_jobs = 1 |
| |
| self._max_jobs = max_jobs |
| self._max_load = max_load |
| self.sched_iface = self._sched_iface_class( |
| register=self._register, |
| schedule=self._schedule_wait, |
| unregister=self._unregister) |
| |
| self._queues = [] |
| self._schedule_listeners = [] |
| |
| def add(self, q): |
| self._queues.append(q) |
| |
| def remove(self, q): |
| self._queues.remove(q) |
| |
| def run(self): |
| |
| while self._schedule(): |
| self._poll_loop() |
| |
| while self._running_job_count(): |
| self._poll_loop() |
| |
| def _schedule_tasks(self): |
| """ |
| @rtype: bool |
| @returns: True if there may be remaining tasks to schedule, |
| False otherwise. |
| """ |
| while self._can_add_job(): |
| n = self._max_jobs - self._running_job_count() |
| if n < 1: |
| break |
| |
| if not self._start_next_job(n): |
| return False |
| |
| for q in self._queues: |
| if q: |
| return True |
| return False |
| |
| def _running_job_count(self): |
| job_count = 0 |
| for q in self._queues: |
| job_count += len(q.running_tasks) |
| self._jobs = job_count |
| return job_count |
| |
| def _start_next_job(self, n=1): |
| started_count = 0 |
| for q in self._queues: |
| initial_job_count = len(q.running_tasks) |
| q.schedule() |
| final_job_count = len(q.running_tasks) |
| if final_job_count > initial_job_count: |
| started_count += (final_job_count - initial_job_count) |
| if started_count >= n: |
| break |
| return started_count |
| |