def _fail_workflow(wf_ex_id, err, action_ex_id=None): """Private helper to fail workflow on exceptions.""" err_msg = str(err) with db_api.transaction(): wf_ex = db_api.load_workflow_execution(wf_ex_id) if wf_ex is None: LOG.error( "Cant fail workflow execution with id='%s': not found.", wf_ex_id) return wf_handler.set_execution_state(wf_ex, states.ERROR, err_msg) if action_ex_id: # Note(dzimine): Don't call self.engine_client: # 1) to avoid computing and triggering next tasks # 2) to avoid a loop in case of error in transport action_ex = db_api.get_action_execution(action_ex_id) task_handler.on_action_complete(action_ex, wf_utils.Result(error=err_msg)) return wf_ex
def _fail_workflow(wf_ex_id, err, action_ex_id=None): """Private helper to fail workflow on exceptions.""" with db_api.transaction(): err_msg = str(err) wf_ex = db_api.load_workflow_execution(wf_ex_id) if wf_ex is None: LOG.error( "Cant fail workflow execution with id='%s': not found.", wf_ex_id ) return wf_handler.set_execution_state(wf_ex, states.ERROR, err_msg) if action_ex_id: # Note(dzimine): Don't call self.engine_client: # 1) to avoid computing and triggering next tasks # 2) to avoid a loop in case of error in transport action_ex = db_api.get_action_execution(action_ex_id) task_handler.on_action_complete( action_ex, wf_utils.Result(error=err_msg) )
def on_action_complete(self, action_ex_id, result): wf_ex_id = None try: with db_api.transaction(): action_ex = db_api.get_action_execution(action_ex_id) wf_ex_id = action_ex.task_execution.workflow_execution_id # Must be before loading the object itself (see method doc). self._lock_workflow_execution(wf_ex_id) wf_ex = action_ex.task_execution.workflow_execution task_ex = task_handler.on_action_complete(action_ex, result) # If workflow is on pause or completed then there's no # need to continue workflow. if states.is_paused_or_completed(wf_ex.state): return action_ex self._on_task_state_change(task_ex, wf_ex, action_ex) return action_ex.get_clone() except Exception as e: # TODO(dzimine): try to find out which command caused failure. # TODO(rakhmerov): Need to refactor logging in a more elegant way. LOG.error( "Failed to handle action execution result [id=%s]: %s\n%s", action_ex_id, e, traceback.format_exc() ) self._fail_workflow(wf_ex_id, e) raise e
def on_action_complete(action_ex, result): task_ex = action_ex.task_execution action = _build_action(action_ex) try: action.complete(result) except exc.MistralException as e: msg = ("Failed to complete action [action=%s, task=%s]: %s\n%s" % (action_ex.name, task_ex.name, e, tb.format_exc())) LOG.error(msg) action.fail(msg) if task_ex: task_handler.fail_task(task_ex, msg) return if task_ex: task_handler.on_action_complete(action_ex)
def on_action_complete(self, action_ex_id, result): wf_ex_id = None try: with db_api.transaction(): action_ex = db_api.get_action_execution(action_ex_id) # In case of single action execution there is no # assigned task execution. if not action_ex.task_execution: return action_handler.store_action_result( action_ex, result).get_clone() wf_ex_id = action_ex.task_execution.workflow_execution_id wf_ex = wf_handler.lock_workflow_execution(wf_ex_id) task_ex = task_handler.on_action_complete(action_ex, result) # If workflow is on pause or completed then there's no # need to continue workflow. if states.is_paused_or_completed(wf_ex.state): return action_ex.get_clone() prev_task_state = task_ex.state # Separate the task transition in a separate transaction. The task # has already completed for better or worst. The task state should # not be affected by errors during transition on conditions such as # on-success and on-error. with db_api.transaction(): wf_ex = wf_handler.lock_workflow_execution(wf_ex_id) action_ex = db_api.get_action_execution(action_ex_id) task_ex = action_ex.task_execution self._on_task_state_change(task_ex, wf_ex, task_state=prev_task_state) return action_ex.get_clone() except Exception as e: # TODO(dzimine): try to find out which command caused failure. # TODO(rakhmerov): Need to refactor logging in a more elegant way. LOG.error( "Failed to handle action execution result [id=%s]: %s\n%s", action_ex_id, e, traceback.format_exc()) # If an exception was thrown after we got the wf_ex_id if wf_ex_id: self._fail_workflow(wf_ex_id, e) raise e
def on_action_complete(self, action_ex_id, result): wf_ex_id = None try: with db_api.transaction(): action_ex = db_api.get_action_execution(action_ex_id) # In case of single action execution there is no # assigned task execution. if not action_ex.task_execution: return action_handler.store_action_result( action_ex, result ).get_clone() wf_ex_id = action_ex.task_execution.workflow_execution_id wf_ex = wf_handler.lock_workflow_execution(wf_ex_id) wf_spec = spec_parser.get_workflow_spec(wf_ex.spec) task_ex = task_handler.on_action_complete( action_ex, wf_spec, result ) # If workflow is on pause or completed then there's no # need to continue workflow. if states.is_paused_or_completed(wf_ex.state): return action_ex.get_clone() self._on_task_state_change(task_ex, wf_ex, wf_spec) return action_ex.get_clone() except Exception as e: # TODO(rakhmerov): Need to refactor logging in a more elegant way. LOG.error( 'Failed to handle action execution result [id=%s]: %s\n%s', action_ex_id, e, traceback.format_exc() ) # If an exception was thrown after we got the wf_ex_id if wf_ex_id: self._fail_workflow(wf_ex_id, e) raise e
def on_action_complete(self, action_ex_id, result): wf_ex_id = None try: with db_api.transaction(): action_ex = db_api.get_action_execution(action_ex_id) # In case of single action execution there is no # assigned task execution. if not action_ex.task_execution: return action_handler.store_action_result( action_ex, result).get_clone() wf_ex_id = action_ex.task_execution.workflow_execution_id # Must be before loading the object itself (see method doc). self._lock_workflow_execution(wf_ex_id) wf_ex = action_ex.task_execution.workflow_execution task_ex = task_handler.on_action_complete(action_ex, result) # If workflow is on pause or completed then there's no # need to continue workflow. if states.is_paused_or_completed(wf_ex.state): return action_ex self._on_task_state_change(task_ex, wf_ex, action_ex) return action_ex.get_clone() except Exception as e: # TODO(dzimine): try to find out which command caused failure. # TODO(rakhmerov): Need to refactor logging in a more elegant way. LOG.error( "Failed to handle action execution result [id=%s]: %s\n%s", action_ex_id, e, traceback.format_exc()) self._fail_workflow(wf_ex_id, e) raise e