def innerLoop(self):
        """
        The main loop for processing jobs by the leader.
        """
        self.timeSinceJobsLastRescued = time.time()

        while self.toilState.updatedJobs or \
              self.getNumberOfJobsIssued() or \
              self.serviceManager.jobsIssuedToServiceManager:

            if self.toilState.updatedJobs:
                self._processReadyJobs()

            # deal with service-related jobs
            self._startServiceJobs()
            self._processJobsWithRunningServices()

            # check in with the batch system
            updatedJobTuple = self.batchSystem.getUpdatedBatchJob(maxWait=2)
            if updatedJobTuple is not None:
                self._gatherUpdatedJobs(updatedJobTuple)
            else:
                self._processLostJobs()

            # Check on the associated threads and exit if a failure is detected
            self.statsAndLogging.check()
            self.serviceManager.check()
            # the cluster scaler object will only be instantiated if autoscaling is enabled
            if self.clusterScaler is not None:
                self.clusterScaler.check()

            if len(self.toilState.updatedJobs) == 0 and self.deadlockThrottler.throttle(wait=False):
                # Nothing happened this round and it's been long
                # enough since we last checked. Check for deadlocks.
                self.checkForDeadlocks()

        logger.debug("Finished the main loop: no jobs left to run.")

        # Consistency check the toil state
        assert self.toilState.updatedJobs == set()
        assert self.toilState.successorCounts == {}
        assert self.toilState.successorJobStoreIDToPredecessorJobs == {}
        assert self.toilState.serviceJobStoreIDToPredecessorJob == {}
        assert self.toilState.servicesIssued == {}
The main loop for processing jobs by the leader.