async def run_coroutine_job(job, jobstore_alias, run_times, logger_name): """Coroutine version of run_job().""" events = [] logger = logging.getLogger(logger_name) for run_time in run_times: # See if the job missed its run time window, and handle possible misfires accordingly if job.misfire_grace_time is not None: difference = datetime.now(utc) - run_time grace_time = timedelta(seconds=job.misfire_grace_time) if difference > grace_time: events.append(JobExecutionEvent(EVENT_JOB_MISSED, job.id, jobstore_alias, run_time)) logger.warning('Run time of job "%s" was missed by %s', job, difference) continue logger.info('Running job "%s" (scheduled at %s)', job, run_time) try: retval = await job.func(*job.args, **job.kwargs) except BaseException: exc, tb = sys.exc_info()[1:] formatted_tb = ''.join(format_tb(tb)) events.append(JobExecutionEvent(EVENT_JOB_ERROR, job.id, jobstore_alias, run_time, exception=exc, traceback=formatted_tb)) logger.exception('Job "%s" raised an exception', job) else: events.append(JobExecutionEvent(EVENT_JOB_EXECUTED, job.id, jobstore_alias, run_time, retval=retval)) logger.debug('Job "%s" executed successfully', job) return events
async def run_coroutine_job(job, logger_name, job_submission_id, jobstore_alias, run_time): """Coroutine version of run_job().""" """ Called by executors to run the job. Returns a list of scheduler events to be dispatched by the scheduler. """ events = [] logger = logging.getLogger(logger_name) try: retval = await job.func(*job.args, **job.kwargs) except: exc, tb = sys.exc_info()[1:] formatted_tb = ''.join(format_tb(tb)) events.append( JobExecutionEvent(EVENT_JOB_ERROR, job.id, jobstore_alias, run_time, exception=exc, traceback=formatted_tb)) logger.exception('Job "%s" raised an exception', job) else: events.append( JobExecutionEvent(EVENT_JOB_EXECUTED, job.id, jobstore_alias, run_time, retval=retval)) logger.info('Job "%s" executed successfully', job) return events
def run_job(job, jobstore_alias, run_times, logger_name): """ Called by executors to run the job. Returns a list of scheduler events to be dispatched by the scheduler. """ events = [] logger = logging.getLogger(logger_name) for run_time in run_times: # See if the job missed its run time window, and handle # possible misfires accordingly if job.misfire_grace_time is not None: difference = datetime.now(utc) - run_time grace_time = timedelta(seconds=job.misfire_grace_time) if difference > grace_time: events.append( JobExecutionEvent(EVENT_JOB_MISSED, job.id, jobstore_alias, run_time)) logger.warning('Run time of job "%s" was missed by %s', job, difference) continue logger.info('Running job "%s" (scheduled at %s)', job, run_time) try: retval = job.func(*job.args, **job.kwargs) except BaseException: exc, tb = sys.exc_info()[1:] formatted_tb = ''.join(format_tb(tb)) events.append( JobExecutionEvent(EVENT_JOB_ERROR, job.id, jobstore_alias, run_time, exception=exc, traceback=formatted_tb)) logger.exception('Job "%s" raised an exception', job) # This is to prevent cyclic references that would lead to memory leaks if six.PY2: sys.exc_clear() del tb else: import traceback traceback.clear_frames(tb) del tb else: events.append( JobExecutionEvent(EVENT_JOB_EXECUTED, job.id, jobstore_alias, run_time, retval=retval)) logger.info('Job "%s" executed successfully', job) return events
def test_handle_execution_event_not_supported_raises_exception( self, jobstore): event = JobExecutionEvent(events.EVENT_ALL, "test_job", jobstore, timezone.now()) with pytest.raises(NotImplementedError): jobstore.handle_execution_event(event)
def test_scheduler_listener_unknown_event(self): config = SchedulerConfiguration() self.assertIsNotNone(config) scheduler = ProgramyScheduler(self._test_client, config) self.assertIsNotNone(scheduler) scheduler_listener(JobExecutionEvent(-1, 1, None, None))
def test_scheduler_listener(self): config = SchedulerConfiguration() self.assertIsNotNone(config) scheduler = ProgramyScheduler(self._test_client, config) self.assertIsNotNone(scheduler) scheduler_listener(JobExecutionEvent(apscheduler.events.EVENT_SCHEDULER_STARTED, 1, None, None))
def test_handle_execution_event_creates_job_execution( self, jobstore, create_add_job): job = create_add_job(jobstore, dummy_job, datetime(2016, 5, 3)) event = JobExecutionEvent(events.EVENT_JOB_EXECUTED, job.id, jobstore, timezone.now()) jobstore.handle_execution_event(event) assert DjangoJobExecution.objects.filter(job_id=event.job_id).exists()
def test_handle_error_event_for_job_that_no_longer_exists_does_not_raise_exception( self, jobstore): event = JobExecutionEvent(events.EVENT_JOB_ERROR, "finished_job", jobstore, timezone.now()) jobstore.handle_error_event(event) assert not DjangoJobExecution.objects.filter( job_id=event.job_id).exists()
def test_handle_execution_event_for_job_that_no_longer_exists_does_not_raise_exception_regression_116( self, jobstore): # Test for regression https://github.com/jcass77/django-apscheduler/issues/116 event = JobExecutionEvent(events.EVENT_JOB_EXECUTED, "finished_job", jobstore, timezone.now()) jobstore.handle_execution_event(event) assert not DjangoJobExecution.objects.filter( job_id=event.job_id).exists()
def test_handle_error_event_no_exception_sets_exception_text( self, jobstore, create_add_job): job = create_add_job(jobstore, dummy_job, datetime(2016, 5, 3)) event = JobExecutionEvent(events.EVENT_JOB_ERROR, job.id, jobstore, timezone.now()) jobstore.handle_error_event(event) ex = DjangoJobExecution.objects.get(job_id=event.job_id) assert "raised an error!" in ex.exception
def run_job(job, run_time): """Called by executors to run the job. Returns a list of scheduler events to be dispatched by the scheduler.""" events = [] try: #retval = job.func(*job.args, **job.kwargs) #buf size采用默认系统缓冲(一般是全缓冲) #subproc = subprocess.Popen(job.conf.cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1, universal_newlines=True) retval = commands.getstatusoutput(job.conf.cmd) except: exc, tb = sys.exc_info()[1:] formatted_tb = ''.join(format_tb(tb)) events.append(JobExecutionEvent(EVENT_JOB_ERROR, job.id, run_time, exception=exc, traceback=formatted_tb)) logging.exception('Raised an exception, job %s (scheduled at %s)' % (job, run_time)) else: events.append(JobExecutionEvent(EVENT_JOB_EXECUTED, job.id, run_time, retval=retval)) logging.info('Executed successfully job "%s" (scheduled at %s) result: %s' % (job, run_time, retval)) return events
def test_get_event_str_job_execution_event(self): scheduled_run_time = datetime.strptime("10/04/18 19:02", "%d/%m/%y %H:%M") event = JobExecutionEvent("code", "job_id", "jobstore", scheduled_run_time, retval=1) message = ProgramyScheduler.get_event_str(event) self.assertIsNotNone(message) self.assertEqual( "JobExecutionEvent [code] [job_id] [jobstore] [2018-04-10 19:02:00] [1]", message)
def test_delete_old_job_executions(db, scheduler): register_events(scheduler) scheduler.add_job(job, trigger="interval", seconds=1, id="job_1") scheduler.add_job(job, trigger="interval", seconds=1, id="job_2") scheduler.start() now = datetime.datetime.now(utc) one_second_ago = now - datetime.timedelta(seconds=1) # Simulate scheduler._dispatch_event( JobExecutionEvent(4096, "job_1", None, one_second_ago)) scheduler._dispatch_event(JobExecutionEvent(4096, "job_2", None, now)) scheduler._dispatch_event( JobSubmissionEvent(32768, "job_1", None, [one_second_ago])) scheduler._dispatch_event(JobSubmissionEvent(32768, "job_2", None, [now])) assert DjangoJobExecution.objects.count() == 2 DjangoJobExecution.objects.delete_old_job_executions(1) assert DjangoJobExecution.objects.count() == 1
def test_job_events(db, scheduler): register_events(scheduler) scheduler.add_job(job, trigger="interval", seconds=1, id="job") scheduler.start() dj = DjangoJob.objects.last() dj.next_run_time -= datetime.timedelta(seconds=2) dj.save() now = datetime.datetime.now(utc) scheduler._dispatch_event(JobExecutionEvent(4096, "job", None, now)) scheduler._dispatch_event(JobSubmissionEvent(32768, "job", None, [now])) assert DjangoJobExecution.objects.count() == 1