def handle_expired_actions(): LOG.debug("Running heartbeat checker...") interval = CONF.action_heartbeat.check_interval max_missed = CONF.action_heartbeat.max_missed_heartbeats exp_date = utils.utc_now_sec() - datetime.timedelta( seconds=max_missed * interval ) with db_api.transaction(): action_exs = db_api.get_running_expired_sync_action_executions( exp_date, CONF.action_heartbeat.batch_size ) LOG.debug("Found {} running and expired actions.".format( len(action_exs)) ) if action_exs: LOG.info( "Actions executions to transit to error, because " "heartbeat wasn't received: {}".format(action_exs) ) for action_ex in action_exs: result = mistral_lib.Result( error="Heartbeat wasn't received." ) action_handler.on_action_complete(action_ex, result)
def handle_expired_actions(): LOG.debug("Running heartbeat checker...") interval = CONF.action_heartbeat.check_interval max_missed = CONF.action_heartbeat.max_missed_heartbeats exp_date = utils.utc_now_sec() - datetime.timedelta(seconds=max_missed * interval) try: with db_api.transaction(): action_exs = db_api.get_running_expired_sync_actions(exp_date) LOG.debug("Found {} running and expired actions.".format( len(action_exs))) if action_exs: LOG.info("Actions executions to transit to error, because " "heartbeat wasn't received: {}".format(action_exs)) for action_ex in action_exs: result = mistral_lib.Result( error="Heartbeat wasn't received.") action_handler.on_action_complete(action_ex, result) finally: schedule(interval)
def on_action_complete(self, action_ex_id, result, wf_action=False): with db_api.transaction(): if wf_action: action_ex = db_api.get_workflow_execution(action_ex_id) else: action_ex = db_api.get_action_execution(action_ex_id) action_handler.on_action_complete(action_ex, result) return action_ex.get_clone()
def on_action_complete(self, action_ex_id, result): with db_api.transaction(): action_ex = db_api.get_action_execution(action_ex_id) task_ex = action_ex.task_execution if task_ex: wf_handler.lock_workflow_execution( task_ex.workflow_execution_id) action_handler.on_action_complete(action_ex, result) return action_ex.get_clone()
def on_action_complete(self, action_ex_id, result): with db_api.transaction(): action_ex = db_api.get_action_execution(action_ex_id) task_ex = action_ex.task_execution if task_ex: wf_handler.lock_workflow_execution( task_ex.workflow_execution_id ) action_handler.on_action_complete(action_ex, result) return action_ex.get_clone()
def on_action_complete(self, action_ex_id, result, wf_action=False, async_=False): with db_api.transaction(): if wf_action: action_ex = db_api.get_workflow_execution(action_ex_id) # If result is None it means that it's a normal subworkflow # output and we just need to fetch it from the model. # This is just an optimization to not send data over RPC if result is None: result = ml_actions.Result(data=action_ex.output) else: action_ex = db_api.get_action_execution(action_ex_id) action_handler.on_action_complete(action_ex, result) return action_ex.get_clone()
def on_action_complete(self, action_ex_id, result, wf_action=False, async_=False): with db_api.transaction(): if wf_action: action_ex = db_api.get_workflow_execution(action_ex_id) # If result is None it means that it's a normal subworkflow # output and we just need to fetch it from the model. # This is just an optimization to not send data over RPC if result is None: result = ml_actions.Result(data=action_ex.output) else: action_ex = db_api.get_action_execution(action_ex_id) action_handler.on_action_complete(action_ex, result) return action_ex.get_clone()
class DefaultEngine(base.Engine): @action_queue.process @u.log_exec(LOG) @profiler.trace('engine-start-workflow') def start_workflow(self, wf_identifier, wf_input, description='', **params): with db_api.transaction(): wf_ex = wf_handler.start_workflow(wf_identifier, wf_input, description, params) return wf_ex.get_clone() @action_queue.process @u.log_exec(LOG) def start_action(self, action_name, action_input, description=None, **params): with db_api.transaction(): action = action_handler.build_action_by_name(action_name) action.validate_input(action_input) sync = params.get('run_sync') save = params.get('save_result') target = params.get('target') is_action_sync = action.is_sync(action_input) if sync and not is_action_sync: raise exceptions.InputException( "Action does not support synchronous execution.") if not sync and (save or not is_action_sync): action.schedule(action_input, target) return action.action_ex.get_clone() output = action.run(action_input, target, save=False) state = states.SUCCESS if output.is_success() else states.ERROR if not save: # Action execution is not created but we need to return similar # object to a client anyway. return db_models.ActionExecution(name=action_name, description=description, input=action_input, output=output.to_dict(), state=state) action_ex_id = u.generate_unicode_uuid() values = { 'id': action_ex_id, 'name': action_name, 'description': description, 'input': action_input, 'output': output.to_dict(), 'state': state, } return db_api.create_action_execution(values) @db_utils.retry_on_deadlock @action_queue.process @u.log_exec(LOG) @profiler.trace('engine-on-action-complete') def on_action_complete(self, action_ex_id, result, wf_action=False, async=False): with db_api.transaction(): if wf_action: action_ex = db_api.get_workflow_execution(action_ex_id) else: action_ex = db_api.get_action_execution(action_ex_id) action_handler.on_action_complete(action_ex, result) return action_ex.get_clone()