コード例 #1
0
ファイル: core.py プロジェクト: manlucas/atom
    def transit(self,
                id,
                to_state,
                is_pipeline=False,
                appoint=False,
                start=False,
                name='',
                version=None,
                unchanged_pass=False):
        """
        尝试改变某个节点的状态
        :param id: 节点 ID
        :param to_state: 目标状态
        :param is_pipeline: 该节点是否是 pipeline
        :param appoint: 该动作是否由用户发起(非引擎内部操作)
        :param start: 是否刷新其开始时间
        :param name: 节点名称
        :param version: 节点版本
        :param unchanged_pass: 当 to_state 与当前节点状态相同时则视为操作成功
        :return:
        """
        defaults = {'name': name, 'state': to_state, 'version': uniqid()}
        if start:
            defaults['started_time'] = timezone.now()
        status, created = self.get_or_create(id=id, defaults=defaults)

        # reservation or first creation
        if created:
            return ActionResult(result=True, message='success', extra=status)

        with transaction.atomic():
            kwargs = {'id': id}
            if version:
                kwargs['version'] = version

            try:
                status = self.select_for_update().get(**kwargs)

            except Status.DoesNotExist:
                return ActionResult(
                    result=False,
                    message='node not exists or not be executed yet')

            if unchanged_pass and status.state == to_state:
                return ActionResult(result=True,
                                    message='success',
                                    extra=status)

            if states.can_transit(from_state=status.state,
                                  to_state=to_state,
                                  is_pipeline=is_pipeline,
                                  appoint=appoint):

                # 在冻结状态下不能改变 pipeline 的状态
                if is_pipeline:
                    subprocess_rel = SubProcessRelationship.objects.filter(
                        subprocess_id=id)
                    if subprocess_rel:
                        process = PipelineProcess.objects.get(
                            id=subprocess_rel[0].process_id)
                        if process.is_frozen:
                            return ActionResult(
                                result=False,
                                message=
                                'engine is frozen, can not perform operation')

                    processes = PipelineProcess.objects.filter(
                        root_pipeline_id=id)
                    if processes and processes[0].is_frozen:
                        return ActionResult(
                            result=False,
                            message=
                            'engine is frozen, can not perform operation')

                if name:
                    status.name = name
                if start:
                    status.started_time = timezone.now()
                if to_state in states.ARCHIVED_STATES:
                    status.archived_time = timezone.now()

                # from FINISHED to RUNNING
                if states.is_rerunning(from_state=status.state,
                                       to_state=to_state):
                    history = History.objects.record(status, is_rerunning=True)
                    if history:
                        LogEntry.objects.link_history(node_id=status.id,
                                                      history_id=history.id)
                    status.loop += 1
                    status.skip = False
                    status.version = uniqid()

                status.state = to_state
                status.save()
                return ActionResult(result=True,
                                    message='success',
                                    extra=status)
            else:
                return ActionResult(
                    result=False,
                    message='can\'t transit state(%s) from %s to %s' %
                    (id, status.state, to_state),
                    extra=status)
コード例 #2
0
    def transit(self,
                id,
                to_state,
                is_pipeline=False,
                appoint=False,
                start=False,
                name='',
                version=None):
        """
        尝试改变某个节点的状态
        :param id: 节点 ID
        :param to_state: 目标状态
        :param is_pipeline: 该节点是否是 pipeline
        :param appoint: 该动作是否由用户发起(非引擎内部操作)
        :param start: 是否刷新其开始事件
        :param name: 节点名称
        :param version: 节点版本
        :return:
        """
        defaults = {'name': name, 'state': to_state, 'version': uniqid()}
        if start:
            defaults['started_time'] = timezone.now()
        _, created = self.get_or_create(id=id, defaults=defaults)

        # reservation or first creation
        if created:
            return True

        with transaction.atomic():
            kwargs = {'id': id}
            if version:
                kwargs['version'] = version

            try:
                status = self.select_for_update().get(**kwargs)
            except Status.DoesNotExist:
                return False

            if states.can_transit(from_state=status.state,
                                  to_state=to_state,
                                  is_pipeline=is_pipeline,
                                  appoint=appoint):
                # 在冻结状态下不能改变 pipeline 的状态

                if is_pipeline:
                    subprocess_rel = SubProcessRelationship.objects.filter(
                        subprocess_id=id)
                    if subprocess_rel:
                        process = PipelineProcess.objects.get(
                            id=subprocess_rel[0].process_id)
                        if process.is_frozen:
                            return False

                    processes = PipelineProcess.objects.filter(
                        root_pipeline_id=id)
                    if processes and processes[0].is_frozen:
                        return False

                status.state = to_state
                if name:
                    status.name = name
                if start:
                    status.started_time = timezone.now()
                if to_state in states.ARCHIVED_STATES:
                    status.archived_time = timezone.now()
                status.save()
                return True
            else:
                return False