def process_cron_triggers_v2(self, ctx): for t in triggers.get_next_cron_triggers(): LOG.debug("Processing cron trigger: %s" % t) # Setup admin context before schedule triggers. ctx = security.create_context(t.trust_id, t.project_id) auth_ctx.set_ctx(ctx) LOG.debug("Cron trigger security context: %s" % ctx) try: rpc.get_engine_client().start_workflow( t.workflow.name, t.workflow_input, description="Workflow execution created by cron trigger.", **t.workflow_params ) finally: if t.remaining_executions is not None and t.remaining_executions > 0: t.remaining_executions -= 1 if t.remaining_executions == 0: db_api_v2.delete_cron_trigger(t.name) else: # if remaining execution = None or > 0 next_time = triggers.get_next_execution_time(t.pattern, t.next_execution_time) db_api_v2.update_cron_trigger( t.name, {"next_execution_time": next_time, "remaining_executions": t.remaining_executions} ) auth_ctx.set_ctx(None)
def advance_cron_trigger(t): modified_count = 0 try: # If the cron trigger is defined with limited execution count. if t.remaining_executions is not None and t.remaining_executions > 0: t.remaining_executions -= 1 # If this is the last execution. if t.remaining_executions == 0: modified_count = triggers.delete_cron_trigger(t.name, trust_id=t.trust_id, delete_trust=False) else: # if remaining execution = None or > 0. # In case the we are lagging or if the api stopped for some time # we use the max of the current time or the next scheduled time. next_time = triggers.get_next_execution_time( t.pattern, max(datetime.datetime.utcnow(), t.next_execution_time)) # Update the cron trigger with next execution details # only if it wasn't already updated by a different process. updated, modified_count = db_api_v2.update_cron_trigger( t.name, { 'next_execution_time': next_time, 'remaining_executions': t.remaining_executions }, query_filter={'next_execution_time': t.next_execution_time}) except exc.DBEntityNotFoundError as e: # Cron trigger was probably already deleted by a different process. LOG.debug("Cron trigger named '%s' does not exist anymore: %s", t.name, str(e)) # Return True if this engine was able to modify the cron trigger in DB. return modified_count > 0
def advance_cron_trigger(ct): modified_count = 0 try: # If the cron trigger is defined with limited execution count. if (ct.remaining_executions is not None and ct.remaining_executions > 0): ct.remaining_executions -= 1 # If this is the last execution. if ct.remaining_executions == 0: modified_count = db_api_v2.delete_cron_trigger(ct.name) else: # if remaining execution = None or > 0. next_time = triggers.get_next_execution_time( ct.pattern, ct.next_execution_time) # Update the cron trigger with next execution details # only if it wasn't already updated by a different process. updated, modified_count = db_api_v2.update_cron_trigger( ct.name, { 'next_execution_time': next_time, 'remaining_executions': ct.remaining_executions }, query_filter={'next_execution_time': ct.next_execution_time}) except exc.NotFoundException as e: # Cron trigger was probably already deleted by a different process. LOG.debug("Cron trigger named '%s' does not exist anymore: %s", ct.name, str(e)) # Return True if this engine was able to modify the cron trigger in DB. return modified_count > 0
def process_cron_triggers_v2(self, ctx): for t in triggers.get_next_cron_triggers(): LOG.debug("Processing cron trigger: %s" % t) # Setup admin context before schedule triggers. ctx = security.create_context(t.trust_id, t.project_id) auth_ctx.set_ctx(ctx) LOG.debug("Cron trigger security context: %s" % ctx) try: rpc.get_engine_client().start_workflow( t.workflow.name, t.workflow_input, description="workflow execution by cron trigger.", **t.workflow_params ) finally: if t.remaining_executions > 0: t.remaining_executions -= 1 if t.remaining_executions == 0: db_api_v2.delete_cron_trigger(t.name) else: # if remaining execution = None or > 0 next_time = triggers.get_next_execution_time( t.pattern, t.next_execution_time ) db_api_v2.update_cron_trigger( t.name, {'next_execution_time': next_time, 'remaining_executions': t.remaining_executions} ) auth_ctx.set_ctx(None)
def test_create_cron_trigger_with_pattern_and_first_time( self, validate_mock): cfg.CONF.set_default('auth_enable', False, group='pecan') wf = workflows.create_workflows(WORKFLOW_LIST)[0] # Make the first_time 1 sec later than current time, in order to make # it executed by next cron-trigger task. first_time = datetime.datetime.utcnow() + datetime.timedelta(0, 1) # Creates a cron-trigger with pattern and first time, ensure the # cron-trigger can be executed more than once, and cron-trigger will # not be deleted. trigger_name = 'trigger-%s' % utils.generate_unicode_uuid() cron_trigger = triggers.create_cron_trigger(trigger_name, wf.name, {}, {}, '*/1 * * * *', first_time, None, None) self.assertEqual(first_time, cron_trigger.next_execution_time) periodic.MistralPeriodicTasks(cfg.CONF).process_cron_triggers_v2(None) next_time = triggers.get_next_execution_time( cron_trigger.pattern, cron_trigger.next_execution_time) cron_trigger_db = db_api.get_cron_trigger(trigger_name) self.assertIsNotNone(cron_trigger_db) self.assertEqual(next_time, cron_trigger_db.next_execution_time)
def test_trigger_create(self): trigger = t_s.create_cron_trigger( 'trigger-%s' % utils.generate_unicode_uuid(), self.wf.name, {}, {}, '*/5 * * * *', None, None, datetime.datetime(2010, 8, 25)) self.assertEqual(datetime.datetime(2010, 8, 25, 0, 5), trigger.next_execution_time) next_time = t_s.get_next_execution_time(trigger['pattern'], trigger.next_execution_time) self.assertEqual(datetime.datetime(2010, 8, 25, 0, 10), next_time)
def test_create_cron_trigger_with_pattern_and_first_time(self, validate_mock): cfg.CONF.set_default('auth_enable', False, group='pecan') wf = workflows.create_workflows(WORKFLOW_LIST)[0] # Make the first_time 1 sec later than current time, in order to make # it executed by next cron-trigger task. first_time = datetime.datetime.now() + datetime.timedelta(0, 1) # Creates a cron-trigger with pattern and first time, ensure the # cron-trigger can be executed more than once, and cron-trigger will # not be deleted. trigger_name = 'trigger-%s' % utils.generate_unicode_uuid() cron_trigger = triggers.create_cron_trigger( trigger_name, wf.name, {}, {}, '*/1 * * * *', first_time, None, None ) first_second = time.mktime(first_time.timetuple()) first_utc_time = datetime.datetime.utcfromtimestamp(first_second) self.assertEqual( first_utc_time, cron_trigger.next_execution_time ) periodic.MistralPeriodicTasks(cfg.CONF).process_cron_triggers_v2(None) next_time = triggers.get_next_execution_time( cron_trigger.pattern, cron_trigger.next_execution_time ) cron_trigger_db = db_api.get_cron_trigger(trigger_name) self.assertIsNotNone(cron_trigger_db) self.assertEqual( next_time, cron_trigger_db.next_execution_time )
def test_create_cron_trigger_with_pattern_and_first_time(self, validate_mock): cfg.CONF.set_default('auth_enable', False, group='pecan') wf = workflows.create_workflows(WORKFLOW_LIST)[0] # Make the first_time 1 sec later than current time, in order to make # it executed by next cron-trigger task. first_time = datetime.datetime.utcnow() + datetime.timedelta(0, 1) # Creates a cron-trigger with pattern and first time, ensure the # cron-trigger can be executed more than once, and cron-trigger will # not be deleted. trigger_name = 'trigger-%s' % utils.generate_unicode_uuid() cron_trigger = triggers.create_cron_trigger( trigger_name, wf.name, {}, {}, '*/1 * * * *', first_time, None, None ) interval = (cron_trigger.next_execution_time - first_time) self.assertLessEqual(interval.total_seconds(), 3.0) periodic.process_cron_triggers_v2(None, None) # After process_triggers context is set to None, need to reset it. auth_ctx.set_ctx(self.ctx) next_time = triggers.get_next_execution_time( cron_trigger.pattern, cron_trigger.next_execution_time ) cron_trigger_db = db_api.get_cron_trigger(trigger_name) self.assertIsNotNone(cron_trigger_db) interval = (cron_trigger_db.next_execution_time - next_time) self.assertLessEqual(interval.total_seconds(), 3.0)
def advance_cron_trigger(t): modified_count = 0 try: # If the cron trigger is defined with limited execution count. if t.remaining_executions is not None and t.remaining_executions > 0: t.remaining_executions -= 1 # If this is the last execution. if t.remaining_executions == 0: modified_count = triggers.delete_cron_trigger( t.name, trust_id=t.trust_id, delete_trust=False ) else: # if remaining execution = None or > 0. # In case the we are lagging or if the api stopped for some time # we use the max of the current time or the next scheduled time. next_time = triggers.get_next_execution_time( t.pattern, max(datetime.datetime.utcnow(), t.next_execution_time) ) # Update the cron trigger with next execution details # only if it wasn't already updated by a different process. updated, modified_count = db_api_v2.update_cron_trigger( t.name, { 'next_execution_time': next_time, 'remaining_executions': t.remaining_executions }, query_filter={ 'next_execution_time': t.next_execution_time } ) except exc.DBEntityNotFoundError as e: # Cron trigger was probably already deleted by a different process. LOG.debug( "Cron trigger named '%s' does not exist anymore: %s", t.name, str(e) ) # Return True if this engine was able to modify the cron trigger in DB. return modified_count > 0
def test_create_cron_trigger_with_pattern_and_first_time(self, validate_mock): wf = workflows.create_workflows(WORKFLOW_LIST)[0] # Make the first_time 1 sec later than current time, in order to make # it executed by next cron-trigger task. first_time = datetime.datetime.now() + datetime.timedelta(0, 1) # Creates a cron-trigger with pattern and first time, ensure the # cron-trigger can be executed more than once, and cron-trigger will # not be deleted. cron_trigger = triggers.create_cron_trigger( 'test', wf.name, {}, {}, '*/1 * * * *', first_time, None, None ) self.assertEqual( first_time, cron_trigger.next_execution_time ) periodic.MistralPeriodicTasks(cfg.CONF).process_cron_triggers_v2(None) next_time = triggers.get_next_execution_time( cron_trigger.pattern, cron_trigger.next_execution_time ) cron_trigger_db = db_api.get_cron_trigger('test') self.assertIsNotNone(cron_trigger_db) self.assertEqual( next_time, cron_trigger_db.next_execution_time )
def advance_cron_trigger(ct): modified_count = 0 try: # If the cron trigger is defined with limited execution count. if (ct.remaining_executions is not None and ct.remaining_executions > 0): ct.remaining_executions -= 1 # If this is the last execution. if ct.remaining_executions == 0: modified_count = db_api_v2.delete_cron_trigger(ct.name) else: # if remaining execution = None or > 0. next_time = triggers.get_next_execution_time( ct.pattern, ct.next_execution_time ) # Update the cron trigger with next execution details # only if it wasn't already updated by a different process. updated, modified_count = db_api_v2.update_cron_trigger( ct.name, { 'next_execution_time': next_time, 'remaining_executions': ct.remaining_executions }, query_filter={ 'next_execution_time': ct.next_execution_time } ) except exc.NotFoundException as e: # Cron trigger was probably already deleted by a different process. LOG.debug( "Cron trigger named '%s' does not exist anymore: %s", ct.name, str(e) ) # Return True if this engine was able to modify the cron trigger in DB. return modified_count > 0
def test_trigger_create(self): trigger = t_s.create_cron_trigger( 'test', self.wf.name, {}, {}, '*/5 * * * *', None, None, datetime.datetime(2010, 8, 25) ) self.assertEqual( datetime.datetime(2010, 8, 25, 0, 5), trigger.next_execution_time ) next_time = t_s.get_next_execution_time( trigger['pattern'], trigger.next_execution_time ) self.assertEqual(datetime.datetime(2010, 8, 25, 0, 10), next_time)
def test_get_next_execution_time(self): pattern = '*/20 * * * *' start_time = datetime.datetime(2016, 3, 22, 23, 40) result = t_s.get_next_execution_time(pattern, start_time) self.assertEqual(result, datetime.datetime(2016, 3, 23, 0, 0))