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)
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