def get_next_fire_time(self, start_date): if start_date < self.start_date: return self.start_date timediff_seconds = timedelta_seconds(start_date - self.start_date) next_interval_num = int(ceil(timediff_seconds / self.interval_length)) return self.start_date + self.interval * next_interval_num
def get_next_fire_time(self, previous_fire_time, now): if previous_fire_time: next_fire_time = previous_fire_time + self.interval elif self.start_date > now: next_fire_time = self.start_date else: timediff_seconds = timedelta_seconds(now - self.start_date) next_interval_num = int(ceil(timediff_seconds / self.interval_length)) next_fire_time = self.start_date + self.interval * next_interval_num if not self.end_date or next_fire_time <= self.end_date: return self.timezone.normalize(next_fire_time)
def __init__(self, interval, start_date=None): if not isinstance(interval, timedelta): raise TypeError('interval must be a timedelta') if start_date: start_date = convert_to_datetime(start_date) self.interval = interval self.interval_length = timedelta_seconds(self.interval) if self.interval_length == 0: self.interval = timedelta(seconds=1) self.interval_length = 1 if start_date is None: self.start_date = datetime.now() + self.interval else: self.start_date = convert_to_datetime(start_date)
def __init__(self, weeks=0, days=0, hours=0, minutes=0, seconds=0, start_date=None, end_date=None, timezone=None): self.interval = timedelta(weeks=weeks, days=days, hours=hours, minutes=minutes, seconds=seconds) self.interval_length = timedelta_seconds(self.interval) if self.interval_length == 0: self.interval = timedelta(seconds=1) self.interval_length = 1 if timezone: self.timezone = astimezone(timezone) elif start_date and start_date.tzinfo: self.timezone = start_date.tzinfo elif end_date and end_date.tzinfo: self.timezone = end_date.tzinfo else: self.timezone = get_localzone() start_date = start_date or (datetime.now(self.timezone) + self.interval) self.start_date = convert_to_datetime(start_date, self.timezone, 'start_date') self.end_date = convert_to_datetime(end_date, self.timezone, 'end_date')
def _process_jobs(self): """ Iterates through jobs in every jobstore, starts jobs that are due and figures out how long to wait for the next round. """ 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): # Look up the job's executor 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) # Update the job if it has a next execution time. Otherwise remove it from the job store. 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) # Set a new next wakeup time if there isn't one yet or the jobstore has an even earlier one 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 # Determine the delay until this method should be called again 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