def get_timeuntil(self): """ Returns a string representing the time until the next time this Job will be run (actually, the "string" returned is really an instance of ``ugettext_lazy``). >>> from precoinr.apps.chronograph.compatibility.dates import now >>> job = Job(next_run=now()) >>> job.get_timeuntil().translate('en') u'due' """ if self.disabled: return _('never (disabled)') if self.next_run==None: self.next_run=dates.now() delta = self.next_run - dates.now() if delta.days < 0: # The job is past due and should be run as soon as possible if self.check_is_running(): return _('running') return _('due') elif delta.seconds < 60: # Adapted from django.utils.timesince count = lambda n: ungettext('second', 'seconds', n) return ugettext('%(number)d %(type)s') % {'number': delta.seconds, 'type': count(delta.seconds)} return timeuntil(self.next_run)
def due(self): """ Returns a ``QuerySet`` of all jobs waiting to be run. NOTE: this may return ``Job``s that are still currently running; it is your responsibility to call ``Job.check_is_running()`` to determine whether or not the ``Job`` actually needs to be run. """ return self.filter(disabled=False).filter(models.Q(next_run__lte=dates.now()) | models.Q(force_run=True))
def get_timeuntil(self, obj): if obj.force_run: next_run = dates.localtime(dates.now()) time_until = _("forced") else: next_run = dates.localtime(obj.next_run) time_until = obj.get_timeuntil() value = capfirst(dates.local_dateformat(next_run)) return "%s<br /><span class='mini'>(%s)</span>" % (value, time_until)
def save(self, *args, **kwargs): if not self.disabled: if self.pk: j = Job.objects.get(pk=self.pk) else: j = self if not self.next_run or j.params != self.params: logger.debug("Updating 'next_run") next_run = self.next_run if not next_run: next_run = dates.now() next_run = dates.make_naive(next_run) self.next_run = dates.make_aware(self.rrule.after(next_run)) else: self.next_run = None super(Job, self).save(*args, **kwargs)
def handle_run(self): """ This method implements the code to actually run a ``Job``. This is meant to be run, primarily, by the `run_job` management command as a subprocess, which can be invoked by calling this ``Job``\'s ``run`` method. """ args, options = self.get_args() stdout = StringIO() stderr = StringIO() # Redirect output so that we can log it if there is any ostdout = sys.stdout ostderr = sys.stderr sys.stdout = stdout sys.stderr = stderr stdout_str, stderr_str = "", "" heartbeat = JobHeartbeatThread() run_date = dates.now() self.is_running = True self.lock_file = heartbeat.lock_file.name self.save() heartbeat.start() try: logger.debug("Calling command '%s'" % self.command) call_command(self.command, *args, **options) logger.debug("Command '%s' completed" % self.command) self.last_run_successful = True except Exception, e: # The command failed to run; log the exception t = loader.get_template('chronograph/error_message.txt') c = Context({ 'exception': unicode(e), 'traceback': ['\n'.join(traceback.format_exception(*sys.exc_info()))] }) stderr_str += t.render(c) self.last_run_successful = False
def is_due(self): """ >>> from precoinr.apps.chronograph.compatibility.dates import now >>> job = Job(next_run=now()) >>> job.is_due() True >>> job = Job(next_run=now()+timedelta(seconds=60)) >>> job.is_due() False >>> job.force_run = True >>> job.is_due() True >>> job = Job(next_run=now(), disabled=True) >>> job.is_due() False """ reqs = (self.next_run <= dates.now() and self.disabled == False and self.check_is_running() == False) return (reqs or self.force_run)