'Iterates through jobs in every jobstore, starts jobs that are due and figures out how long to wait for the next
round.'

def _process_jobs(self):

    self._logger.debug('Looking    for    jobs    to    run')
    now = datetime.now(self.timezone)
    next_wakeup_time = None
    with self._jobstores_lock:
        for (jobstore_alias, jobstore) in six.iteritems(self._jobstores):
            for job in jobstore.get_due_jobs(now):
                try:
                    executor = self._lookup_executor(job.executor)
                except:
                    self._logger.error('Executor    lookup    ("%s")    failed    for    job    "%s"    --    removing    it    from    the    job    store', job.executor, job)
                    self.remove_job(job.id, jobstore_alias)
                    continue
                run_times = job._get_run_times(now)
                run_times = (run_times[(-1):] if (run_times and job.coalesce) else run_times)
                if run_times:
                    try:
                        executor.submit_job(job, run_times)
                    except MaxInstancesReachedError:
                        self._logger.warning('Execution    of    job    "%s"    skipped:    maximum    number    of    running    instances    reached    (%d)', job, job.max_instances)
                    except:
                        self._logger.exception('Error    submitting    job    "%s"    to    executor    "%s"', job, job.executor)
                    job_next_run = job.trigger.get_next_fire_time(run_times[(-1)], now)
                    if job_next_run:
                        job._modify(next_run_time=job_next_run)
                        jobstore.update_job(job)
                    else:
                        self.remove_job(job.id, jobstore_alias)
            jobstore_next_run_time = jobstore.get_next_run_time()
            if (jobstore_next_run_time and ((next_wakeup_time is None) or (jobstore_next_run_time < next_wakeup_time))):
                next_wakeup_time = jobstore_next_run_time
    if (next_wakeup_time is not None):
        wait_seconds = max(timedelta_seconds((next_wakeup_time - now)), 0)
        self._logger.debug('Next    wakeup    is    due    at    %s    (in    %f    seconds)', next_wakeup_time, wait_seconds)
    else:
        wait_seconds = None
        self._logger.debug('No    jobs;    waiting    until    a    job    is    added')
    return wait_seconds
