/**
   * 处理工作流中的下游节点
   *
   * @param multiExit
   * @throws Exception
   */
  private void processNextNodes(List<String> multiExit) throws Exception {
    if (status.isEndState()) {
      return;
    }
    for (String name : multiExit) {
      JobPlanNode nextNode = workflowManager.getNode(name);
      if (null != nextNode) {
        NodeContext nextcontext = new JobPlanNodeContext(this);
        if (!nextNode.getTypeEnum().isFinalType()) {
          signal(nextNode.getName(), nextcontext);
        } else {
          NodeHandler nextnodeHandler =
              NodeHandlerFactory.createNodeHandler(jobEventManager, nextNode);
          nextnodeHandler.enter(nextcontext);
          if (nextNode.getTypeEnum() == JobPlanNodeType.end) {
            nextnodeHandler.exit(nextcontext);
            status = WorkflowStatus.SUCCEEDED;
          }

          if (nextNode.getTypeEnum() == JobPlanNodeType.fail) {
            nextnodeHandler.exit(nextcontext);
            status = WorkflowStatus.FAILED;
          }
        }
      }
    }
  }
  @Override
  public void completeJobPlanNode(String nodeName, NodeContext context) {
    try {
      NodeHandler pnodeHandler =
          NodeHandlerFactory.createNodeHandler(jobEventManager, workflowManager.getNode(nodeName));
      List<String> multiExit = pnodeHandler.multiExit(context);
      processNextNodes(multiExit);
    } catch (Exception e) {
      LOG.error("Fail to execute complete job node!", e);
      status = WorkflowStatus.FAILED;
    }

    if (status.isEndState()) {
      WorkflowContext.getInstance().removeWorkflow(this.getWorkflowKey());
    }
  }
 public synchronized void fail() throws WorkflowException {
   if (status.isEndState()) {
     throw new WorkflowException("this Workflow has end,so can not make it failed");
   }
   status = WorkflowStatus.FAILED;
 }