Esempio n. 1
0
 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)
Esempio n. 2
0
    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
Esempio n. 3
0
    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