def _restart(self, my_task): """ Abort celery task and retry it""" if not my_task._has_state(Task.WAITING): raise WorkflowException( my_task, "Cannot refire a task that is not" "in WAITING state") # Check state of existing call and abort it (save history) if my_task._get_internal_data('task_id') is not None: if not hasattr(my_task, 'async_call'): task_id = my_task._get_internal_data('task_id') my_task.async_call = default_app.AsyncResult(task_id) my_task.deserialized = True my_task.async_call.state # manually refresh async_call = my_task.async_call if async_call.state == 'FAILED': pass elif async_call.state in ['RETRY', 'PENDING', 'STARTED']: async_call.revoke() LOG.info("Celery task '%s' was in %s state and was revoked" % (async_call.state, async_call)) elif async_call.state == 'SUCCESS': LOG.warning("Celery task '%s' succeeded, but a refire was " "requested" % async_call) self._clear_celery_task_data(my_task) # Retrigger return self._start(my_task)
def _start(self, my_task, force=False): """Returns False when successfully fired, True otherwise""" # Deserialize async call if necessary if not hasattr(my_task, 'async_call') and \ my_task._get_internal_data('task_id') is not None: task_id = my_task._get_internal_data('task_id') my_task.async_call = default_app.AsyncResult(task_id) my_task.deserialized = True LOG.debug("Reanimate AsyncCall %s" % task_id) # Make the call if not already done if not hasattr(my_task, 'async_call'): self._send_call(my_task) # Get call status (and manually refresh if deserialized) if getattr(my_task, "deserialized", False): my_task.async_call.state # must manually refresh if deserialized if my_task.async_call.state == 'FAILURE': LOG.debug("Async Call for task '%s' failed: %s" % (my_task.get_name(), my_task.async_call.info)) info = {} info['traceback'] = my_task.async_call.traceback info['info'] = Serializable(my_task.async_call.info) info['state'] = my_task.async_call.state my_task._set_internal_data(task_state=info) elif my_task.async_call.state == 'RETRY': info = {} info['traceback'] = my_task.async_call.traceback info['info'] = Serializable(my_task.async_call.info) info['state'] = my_task.async_call.state my_task._set_internal_data(task_state=info) elif my_task.async_call.ready(): result = my_task.async_call.result if isinstance(result, Exception): LOG.warn("Celery call %s failed: %s" % (self.call, result)) my_task._set_internal_data(error=Serializable(result)) return False LOG.debug("Completed celery call %s with result=%s" % (self.call, result)) # Format result if self.result_key: data = {self.result_key: result} else: if isinstance(result, dict): data = result else: data = {'result': result} # Load formatted result into internal_data if self.merge_results: merge_dictionary(my_task.internal_data, data) else: my_task.set_data(**data) return True else: LOG.debug("async_call.ready()=%s. TryFire for '%s' " "returning False" % (my_task.async_call.ready(), my_task.get_name())) return False
def try_fire(self, my_task, force=False): """Returns False when successfully fired, True otherwise""" # Deserialize async call if necessary if not hasattr(my_task, 'async_call') and \ my_task._get_internal_attribute('task_id') is not None: task_id = my_task._get_internal_attribute('task_id') if 'eager_task_data' in my_task.internal_attributes: async_call = default_app.EagerResult(task_id) async_call.__dict__ = copy.copy( my_task._get_internal_attribute('eager_task_data')) if async_call.state == 'FAILURE': #Get the exception from the traceback err_string = async_call.traceback.split("\n")[-2] # Store it in the reult to be processed later async_call._result = SpiffWorkflowCeleryException( err_string) my_task.async_call = async_call else: my_task.async_call = default_app.AsyncResult(task_id) my_task.deserialized = True LOG.debug("Reanimate AsyncCall %s" % task_id) # Make the call if not already done if not hasattr(my_task, 'async_call'): self._send_call(my_task) # Get call status (and manually refresh if deserialized) if getattr(my_task, "deserialized", False): my_task.async_call.state # must manually refresh if deserialized if my_task.async_call.state == 'FAILURE': LOG.debug("Async Call for task '%s' failed: %s" % (my_task.get_name(), my_task.async_call.result)) data = {} data['traceback'] = my_task.async_call.traceback data['info'] = Serializable(my_task.async_call.result) data['state'] = my_task.async_call.state my_task._set_internal_attribute(task_state=data) return False elif my_task.async_call.state == 'RETRY': data = {} data['traceback'] = my_task.async_call.traceback data['info'] = Serializable(my_task.async_call.result) data['state'] = my_task.async_call.state my_task._set_internal_attribute(task_state=data) elif my_task.async_call.ready(): result = my_task.async_call.result if isinstance(result, Exception): LOG.warn("Celery call %s failed: %s" % (self.call, result)) my_task._set_internal_attribute(error=Serializable(result)) return False LOG.debug("Completed celery call %s with result=%s" % (self.call, result)) # Format result if self.result_key: data = {self.result_key: result} else: if isinstance(result, dict): data = result else: data = {'result': result} # Load formatted result into attributes if self.merge_results: merge_dictionary(my_task.attributes, data) else: my_task.set_attribute(**data) return True else: LOG.debug("async_call.ready()=%s. TryFire for '%s' " "returning False" % (my_task.async_call.ready(), my_task.get_name())) return False