def test_12_datetime_object(self): """Set slices using datetime object""" item = crontab.CronItem(command='cmd') self.assertEqual(str(item.slices), '* * * * *') item.setall(datetime(2009, 8, 9, 3, 4)) self.assertTrue(item.is_valid()) self.assertEqual(str(item.slices), '4 3 9 8 *')
def test_11_date_object(self): """Set slices using date object""" item = crontab.CronItem(command='cmd') self.assertEqual(str(item.slices), '* * * * *') item.setall(date(2010, 6, 7)) self.assertEqual(str(item.slices), '0 0 7 6 *') self.assertTrue(item.is_valid())
def test_08_cronitem(self): """CronItem Standalone""" item = crontab.CronItem(line='noline') self.assertTrue(item.is_enabled()) with self.assertRaises(UnboundLocalError): item.delete() item.command = str('nothing') self.assertEqual(item.render(), '* * * * * nothing')
def new_job(command: str, comment: str) -> crontab.CronItem: job = crontab.CronItem( command=command, comment=comment, user=None, cron=None, pre_comment=False, ) return job
def test_10_time_object(self): """Set slices using time object""" item = crontab.CronItem(command='cmd') self.assertEqual(str(item.slices), '* * * * *') item.setall(time(1, 2)) self.assertEqual(str(item.slices), '2 1 * * *') self.assertTrue(item.is_valid()) item.setall(time(0, 30, 0, 0)) self.assertEqual(str(item.slices), '30 0 * * *') self.assertTrue(item.is_valid()) self.assertEqual(str(item), '30 0 * * * cmd')
def test_11_date_object(self): """Set slices using date object""" item = crontab.CronItem() self.assertEqual(str(item.slices), '* * * * *') item.setall(date(2010, 6, 7)) self.assertEqual(str(item.slices), '0 0 7 6 *')
def test_10_time_object(self): """Set slices using time object""" item = crontab.CronItem() self.assertEqual(str(item.slices), '* * * * *') item.setall(time(1, 2)) self.assertEqual(str(item.slices), '2 1 * * *')
def main(argv=sys.argv): if len(argv) < 2: usage(argv) config_uri = argv[1] options = parse_vars(argv[2:]) setup_logging(config_uri) settings = get_appsettings(config_uri, options=options) import gengine gengine.main({}, **settings) from gengine.metadata import (DBSession) sess = DBSession() import gengine.app.model as m import crontab from gengine.app.registries import get_task_registry enginetasks = get_task_registry().registrations with transaction.manager: mark_changed(sess, transaction.manager, True) tasks = sess.execute(m.t_tasks.select()).fetchall() for task in tasks: cron = task["cron"] if not cron: cron = enginetasks.get(task["task_name"]).get( "default_cron", None) if cron: now = dt_now().replace(second=0) item = crontab.CronItem(line=cron) s = item.schedule(date_from=now) prev = s.get_next().replace(second=0) next = s.get_next().replace(second=0) execs = sess.execute(m.t_taskexecutions.select().where( and_( m.t_taskexecutions.c.task_id == task["id"], m.t_taskexecutions.c.canceled_at == None, m.t_taskexecutions.c.finished_at == None, )).order_by( m.t_taskexecutions.c.planned_at.desc())).fetchall() found = False for exec in execs: if exec["planned_at"] >= next: # The next execution is already planned found = True if exec["planned_at"] <= prev and prev < dt_ago( minutes=10) and not exec["locked_at"]: # The execution is more than 10 minutes in the past and not yet locked (worker not running / overloaded) if next - datetime.timedelta(minutes=10) < dt_now(): # The next execution is planned in less than 10 minutes, cancel the other one sess.execute(m.t_taskexecutions.update().values({ 'canceled_at': dt_now() }).where({'id': exec["id"]})) if exec["locked_at"] and exec["locked_at"] < dt_ago( hours=24): # this task is running for more than 24 hours. probably crashed.... set it to canceled sess.execute(m.t_taskexecutions.update().values({ 'canceled_at': dt_now() }).where({'id': exec["id"]})) if not found: # Plan next execution sess.execute(m.t_taskexecutions.insert().values({ 'task_id': task["id"], 'planned_at': next })) sess.flush() sess.commit()