Ejemplo n.º 1
0
 def run(self, task_list):
     """Poll decision task from SWF and process.
     """
     events = self.poll(task_list)
     if not events:
         return
     self.handler = StepHandler(
         events,
         activity_max_retry=config.ACTIVITY_MAX_RETRY,
         workflow_max_retry=config.WORKFLOW_MAX_RETRY)
     try:
         result = self.execute()
         if self.handler.is_waiting():
             raise TaskWait
     except TaskWait:
         self.suspend()
     except TaskError:
         _, error, _ = sys.exc_info()
         self.fail(error.reason, error.details)
     except:
         _, error, _ = sys.exc_info()
         self.fail(repr(error), json.dumps(traceback.format_exc()))
     else:
         self.complete(result)
Ejemplo n.º 2
0
 def run(self, task_list):
     """Poll decision task from SWF and process.
     """
     events = self.poll(task_list)
     if not events:
         return
     self.handler = StepHandler(
         events,
         activity_max_retry=config.ACTIVITY_MAX_RETRY,
         workflow_max_retry=config.WORKFLOW_MAX_RETRY)
     try:
         result = self.execute()
         if self.handler.is_waiting():
             raise TaskWait
     except TaskWait:
         self.suspend()
     except TaskError:
         _, error, _ = sys.exc_info()
         self.fail(error.reason, error.details)
     except:
         _, error, _ = sys.exc_info()
         self.fail(repr(error), json.dumps(traceback.format_exc()))
     else:
         self.complete(result)
Ejemplo n.º 3
0
class SWFDecider(Decider):

    def run(self, task_list):
        """Poll decision task from SWF and process.
        """
        events = self.poll(task_list)
        if not events:
            return
        self.handler = StepHandler(
            events,
            activity_max_retry=config.ACTIVITY_MAX_RETRY,
            workflow_max_retry=config.WORKFLOW_MAX_RETRY)
        try:
            result = self.execute()
            if self.handler.is_waiting():
                raise TaskWait
        except TaskWait:
            self.suspend()
        except TaskError:
            _, error, _ = sys.exc_info()
            self.fail(error.reason, error.details)
        except:
            _, error, _ = sys.exc_info()
            self.fail(repr(error), json.dumps(traceback.format_exc()))
        else:
            self.complete(result)

    def execute(self):
        """Execute input of SWF workflow.
        """
        type_ = 'Job' if 'Job' in self.handler.input else 'Task'
        parallel = self.handler.input[type_].get('parallel', False)
        for i, child in enumerate(self.handler.input[type_]['children']):
            priority = get_priority(self.handler.input, self.handler.priority, i)
            if 'Task' in child:
                self.execute_task(child, priority)
            elif 'Action' in child and not child['Action']['_whenerror']:
                self.execute_action(child, priority)

            if not parallel:
                self.wait()
        if parallel:
            for child in self.handler.input[type_]['children']:
                self.wait()

    def execute_task(self, task, priority):
        """Schedule task to SWF as child workflow and wait. If the task is not
        completed, raise TaskWait.
        """
        if self.handler.is_waiting():
            raise TaskWait
        elif self.handler.is_scheduled():
            return
        else:
            handler = InputHandler(self.handler.protocol)
            ChildWorkflowExecution.start(
                decisions=self.decisions,
                name=self.handler.get_next_workflow_name(task['Task']['title']),
                input_data={
                    'protocol': self.handler.protocol,
                    'body': handler.save(
                        data=task,
                        genealogy=self.handler.tag_list + [task['Task']['title']])
                },
                tag_list=self.handler.tag_list + [task['Task']['title']],
                priority=priority)

    def execute_action(self, action, priority):
        """Schedule action to SWF as activity task and wait. If action is not
        completed, raise TaskWait.
        """
        if self.handler.is_waiting():
            raise TaskWait
        elif self.handler.is_scheduled():
            return
        else:
            handler = InputHandler(self.handler.protocol)
            action_name = self.handler.get_next_activity_name()
            ActivityTask.schedule(
                self.decisions,
                name=action_name,
                input_data={
                    'protocol': self.handler.protocol,
                    'body': handler.save(
                        data=action,
                        genealogy=self.handler.tag_list + ['Action%s' % action_name])
                },
                task_list=action['Action'].get('_role', config.ACTIVITY_TASK_LIST),
                priority=priority
            )

    def fail(self, reason, details):
        try:
            type_ = 'Job' if 'Job' in self.handler.input else 'Task'
            actions = filter(lambda c: 'Action' in c, self.handler.input[type_]['children'])
            for i, child in enumerate(self.handler.input[type_]['children']):
                if 'Action' not in child:
                    continue
                if child['Action']['_whenerror'] is False:
                    continue
                priority = get_priority(self.handler.input, self.handler.priority, i)
                self.execute_action(child, priority)
                self.wait()
        except TaskWait:
            self.suspend()
        except TaskError:
            _, error, _ = sys.exc_info()
            super(SWFDecider, self).fail(
                error.reason[:config.MAX_REASON_SIZE] if error.reason else error.reason,
                error.details[:config.MAX_DETAIL_SIZE] if error.details else error.details)
        except:
            _, error, _ = sys.exc_info()
            super(SWFDecider, self).fail(
                repr(error)[:config.MAX_REASON_SIZE],
                traceback.format_exc()[:config.MAX_DETAIL_SIZE])
        else:
            super(SWFDecider, self).fail(
                reason[:config.MAX_REASON_SIZE] if reason else reason,
                details[:config.MAX_DETAIL_SIZE] if details else details)

    def wait(self):
        """Check if the next step could be processed. If the previous step
        is submitted to SWF, processed and successful, return result.
        """
        if self.decisions._data:
            raise TaskWait

        with self.handler.pop() as step:
            if not step:
                return
            if step.status() in ['Failed', 'TimedOut']:
                if step.should_retry():
                    step.retry(self.decisions)
                    raise TaskWait
                else:
                    error = step.error()
                    step.is_checked = True
                    raise TaskError(error.reason, error.details)
            else:
                return step.result()
Ejemplo n.º 4
0
class SWFDecider(Decider):
    def run(self, task_list):
        """Poll decision task from SWF and process.
        """
        events = self.poll(task_list)
        if not events:
            return
        self.handler = StepHandler(
            events,
            activity_max_retry=config.ACTIVITY_MAX_RETRY,
            workflow_max_retry=config.WORKFLOW_MAX_RETRY)
        try:
            result = self.execute()
            if self.handler.is_waiting():
                raise TaskWait
        except TaskWait:
            self.suspend()
        except TaskError:
            _, error, _ = sys.exc_info()
            self.fail(error.reason, error.details)
        except:
            _, error, _ = sys.exc_info()
            self.fail(repr(error), json.dumps(traceback.format_exc()))
        else:
            self.complete(result)

    def execute(self):
        """Execute input of SWF workflow.
        """
        type_ = 'Job' if 'Job' in self.handler.input else 'Task'
        parallel = self.handler.input[type_].get('parallel', False)
        for i, child in enumerate(self.handler.input[type_]['children']):
            priority = get_priority(self.handler.input, self.handler.priority,
                                    i)
            if 'Task' in child:
                self.execute_task(child, priority)
            elif 'Action' in child and not child['Action']['_whenerror']:
                self.execute_action(child, priority)

            if not parallel:
                self.wait()
        if parallel:
            for child in self.handler.input[type_]['children']:
                self.wait()

    def execute_task(self, task, priority):
        """Schedule task to SWF as child workflow and wait. If the task is not
        completed, raise TaskWait.
        """
        if self.handler.is_waiting():
            raise TaskWait
        elif self.handler.is_scheduled():
            return
        else:
            handler = InputHandler(self.handler.protocol)
            ChildWorkflowExecution.start(
                decisions=self.decisions,
                name=self.handler.get_next_workflow_name(
                    task['Task']['title']),
                input_data={
                    'protocol':
                    self.handler.protocol,
                    'body':
                    handler.save(data=task,
                                 genealogy=self.handler.tag_list +
                                 [task['Task']['title']])
                },
                tag_list=self.handler.tag_list + [task['Task']['title']],
                priority=priority)

    def execute_action(self, action, priority):
        """Schedule action to SWF as activity task and wait. If action is not
        completed, raise TaskWait.
        """
        if self.handler.is_waiting():
            raise TaskWait
        elif self.handler.is_scheduled():
            return
        else:
            handler = InputHandler(self.handler.protocol)
            action_name = self.handler.get_next_activity_name()
            ActivityTask.schedule(
                self.decisions,
                name=action_name,
                input_data={
                    'protocol':
                    self.handler.protocol,
                    'body':
                    handler.save(data=action,
                                 genealogy=self.handler.tag_list +
                                 ['Action%s' % action_name])
                },
                task_list=action['Action'].get('_role',
                                               config.ACTIVITY_TASK_LIST),
                priority=priority)

    def fail(self, reason, details):
        try:
            type_ = 'Job' if 'Job' in self.handler.input else 'Task'
            actions = filter(lambda c: 'Action' in c,
                             self.handler.input[type_]['children'])
            for i, child in enumerate(self.handler.input[type_]['children']):
                if 'Action' not in child:
                    continue
                if child['Action']['_whenerror'] is False:
                    continue
                priority = get_priority(self.handler.input,
                                        self.handler.priority, i)
                self.execute_action(child, priority)
                self.wait()
        except TaskWait:
            self.suspend()
        except TaskError:
            _, error, _ = sys.exc_info()
            super(SWFDecider, self).fail(
                error.reason[:config.MAX_REASON_SIZE] if error.reason else
                error.reason, error.details[:config.MAX_DETAIL_SIZE]
                if error.details else error.details)
        except:
            _, error, _ = sys.exc_info()
            super(SWFDecider, self).fail(
                repr(error)[:config.MAX_REASON_SIZE],
                traceback.format_exc()[:config.MAX_DETAIL_SIZE])
        else:
            super(SWFDecider, self).fail(
                reason[:config.MAX_REASON_SIZE] if reason else reason,
                details[:config.MAX_DETAIL_SIZE] if details else details)

    def wait(self):
        """Check if the next step could be processed. If the previous step
        is submitted to SWF, processed and successful, return result.
        """
        if self.decisions._data:
            raise TaskWait

        with self.handler.pop() as step:
            if not step:
                return
            if step.status() in ['Failed', 'TimedOut']:
                if step.should_retry():
                    step.retry(self.decisions)
                    raise TaskWait
                else:
                    error = step.error()
                    step.is_checked = True
                    raise TaskError(error.reason, error.details)
            else:
                return step.result()