@Override
  public void run() {
    // 判断有没有连接
    if (client.isConnected()) {
      // 已经建立连接
      TaskExecutor.getInstance().submitTask(new Online(client));
      Log.i("Mina", "------------>连接成功");
    } else {
      // 建立连接
      Log.d("Mina", "------------>建立连接");
      if (SystemConfig.loginResponse != null) {
        Log.d(
            "Mina",
            "------------>"
                + SystemConfig.loginResponse.getMinaIp()
                + ":"
                + SystemConfig.loginResponse.getMinaPort());
        client.connect(
            SystemConfig.loginResponse.getMinaIp(),
            Integer.parseInt(SystemConfig.loginResponse.getMinaPort()));
      } else {
        Log.e("Mina", "------------>无Mina地址和端口信息");
      }

      // 判断连接是否连接成功,上线
      if (client.isConnected()) {
        // 校验建立成功
        Log.i("Mina", "------------>已经连接成功");
        TaskExecutor.getInstance().submitTask(new Online(client));
      } else {
        Log.e("Mina", "------------>连接失败");
      }
    }
  }
示例#2
0
 /**
  * Starts the given task within a task executor.
  *
  * @param task The task.
  * @return The spawned task executor.
  */
 TaskExecutor spawnExecutor(Task task) {
   TaskExecutor e = new TaskExecutor(this, task);
   synchronized (executors) {
     executors.add(e);
   }
   e.start(daemon);
   return e;
 }
示例#3
0
 private boolean isAllTaskDone(List<TaskExecutor> taskList) {
   for (TaskExecutor taskExecutor : taskList) {
     if (!taskExecutor.isTaskFinished()) {
       return false;
     }
   }
   return true;
 }
示例#4
0
 private TaskExecutor removeTask(List<TaskExecutor> taskList, int taskId) {
   Iterator<TaskExecutor> iterator = taskList.iterator();
   while (iterator.hasNext()) {
     TaskExecutor taskExecutor = iterator.next();
     if (taskExecutor.getTaskId() == taskId) {
       iterator.remove();
       return taskExecutor;
     }
   }
   return null;
 }
示例#5
0
 /**
  * Returns the error message count.
  *
  * @param correlationId correlation Id.
  * @return the error message count.
  */
 @ManagedOperation
 @ManagedOperationParameters({
   @ManagedOperationParameter(name = "correlationId", description = "Correlation ID")
 })
 public int getTaskErrorMessageCount(String correlationId) {
   return taskExecutor.getTaskResult(correlationId).getErrorMessageCount();
 }
示例#6
0
  private static void runScanExercise(Map<String, Path> paths) {
    // Exercise name, should it be something else than directory name?
    String exerciseName = paths.get(EXERCISE_PATH).toFile().getName();
    Optional<ExerciseDesc> exerciseDesc = Optional.absent();
    try {
      exerciseDesc = executor.scanExercise(paths.get(EXERCISE_PATH), exerciseName);

      if (!exerciseDesc.isPresent()) {
        log.error("Absent exercise description after running scanExercise");
        printErrAndExit("ERROR: Could not scan the exercises.");
      }
    } catch (NoLanguagePluginFoundException e) {
      log.error("No suitable language plugin for project at {}", paths.get(EXERCISE_PATH), e);
      printErrAndExit(
          "ERROR: Could not find suitable language plugin for the given " + "exercise path.");
    }

    try {
      JsonWriter.writeObjectIntoJsonFormat(exerciseDesc.get(), paths.get(OUTPUT_PATH));
      System.out.println(
          "Exercises scanned successfully, results can be found in "
              + paths.get(OUTPUT_PATH).toString());
    } catch (IOException e) {
      log.error("Could not write output to {}", paths.get(OUTPUT_PATH), e);
      printErrAndExit("ERROR: Could not write the results to the given file.");
    }
  }
  public void update(Vector3f center) {
    List<ChunkUpdateTask> unloadChunksTasks;
    List<ChunkUpdateTask> generateTerrainTasks;
    List<ChunkUpdateTask> generateStructuresTasks;
    List<ChunkUpdateTask> generateMeshesTasks;
    synchronized (pagination) {
      unloadChunksTasks = pagination.generateDelTasks(center);
      generateTerrainTasks = pagination.generateTasks0(center);
      generateStructuresTasks = pagination.generateTasks1(center);
      generateMeshesTasks = pagination.generateTasks2(center);
      pagination.setNewCenter(center);
    }

    ChunkPosition[] positions = invalidChunks.toArray(new ChunkPosition[0]);
    for (ChunkPosition chunkPosition : positions) {
      generateMeshesTasks.add(new ChunkUpdateTask(chunkPosition, 2));
    }
    invalidChunks.removeAll(Arrays.asList(positions));

    executor.submitTasks(convertTasks(unloadChunksTasks));
    executor.submitTasks(convertTasks(generateTerrainTasks));
    executor.blockUntilFinished();
    executor.submitTasks(convertTasks(generateStructuresTasks));
    executor.blockUntilFinished();
    executor.submitTasks(convertTasks(generateMeshesTasks));
    executor.blockUntilFinished();
  }
示例#8
0
 private static void runPrepareSolution(Map<String, Path> paths) {
   try {
     executor.prepareSolution(paths.get(EXERCISE_PATH));
   } catch (NoLanguagePluginFoundException e) {
     log.error("No suitable language plugin for project at {}", paths.get(EXERCISE_PATH), e);
     printErrAndExit(
         "ERROR: Could not find suitable language plugin for the given " + "exercise path.");
   }
 }
示例#9
0
 /**
  * It waits until the given task executor is dead. It is similar to {@link TaskExecutor#join()},
  * but this one avoids {@link InterruptedException} instances.
  *
  * @param executor The task executor.
  */
 private void tillExecutorDies(TaskExecutor executor) {
   boolean dead = false;
   do {
     try {
       executor.join();
       dead = true;
     } catch (InterruptedException e) {;
     }
   } while (!dead);
 }
示例#10
0
 /**
  * This method stops the scheduler execution. Before returning, it waits the end of all the
  * running tasks previously launched. Once the scheduler has been stopped it can be started again
  * with a start() call.
  *
  * @throws IllegalStateException Thrown if this scheduler is not started.
  */
 public void stop() throws IllegalStateException {
   synchronized (lock) {
     if (!started) {
       throw new IllegalStateException("Scheduler not started");
     }
     // Interrupts the timer and waits for its death.
     timer.interrupt();
     tillThreadDies(timer);
     timer = null;
     // Interrupts any running launcher and waits for its death.
     for (; ; ) {
       LauncherThread launcher = null;
       synchronized (launchers) {
         if (launchers.size() == 0) {
           break;
         }
         launcher = (LauncherThread) launchers.remove(0);
       }
       launcher.interrupt();
       tillThreadDies(launcher);
     }
     launchers = null;
     // Interrupts any running executor and waits for its death.
     // Before exiting wait for all the active tasks end.
     for (; ; ) {
       TaskExecutor executor = null;
       synchronized (executors) {
         if (executors.size() == 0) {
           break;
         }
         executor = (TaskExecutor) executors.remove(0);
       }
       if (executor.canBeStopped()) {
         executor.stop();
       }
       tillExecutorDies(executor);
     }
     executors = null;
     // Change the state of the object.
     started = false;
   }
 }
示例#11
0
 public void start() {
   if (isStart) {
     return;
   }
   synchronized (LOCK) {
     if (isStart) {
       return;
     }
     taskExecutor.exec();
   }
 }
示例#12
0
 /**
  * Instantiate a new {@link Task}.
  *
  * @param context a {@link TaskContext} containing all necessary information to construct and run
  *     a {@link Task}
  * @param taskStateTracker a {@link TaskStateTracker} for tracking task state
  * @param taskExecutor a {@link TaskExecutor} for executing the {@link Task} and its {@link Fork}s
  * @param countDownLatch an optional {@link java.util.concurrent.CountDownLatch} used to signal
  *     the task completion
  */
 public Task(
     TaskContext context,
     TaskStateTracker taskStateTracker,
     TaskExecutor taskExecutor,
     Optional<CountDownLatch> countDownLatch) {
   this.taskContext = context;
   this.taskState = context.getTaskState();
   this.jobId = this.taskState.getJobId();
   this.taskId = this.taskState.getTaskId();
   this.taskStateTracker = taskStateTracker;
   this.forkCompletionService = new ExecutorCompletionService(taskExecutor.getForkExecutor());
   this.countDownLatch = countDownLatch;
 }
示例#13
0
 /**
  * Returns task error messages.
  *
  * @param correlationId correlation Id.
  * @return task error messages.
  */
 @ManagedOperation
 @ManagedOperationParameters({
   @ManagedOperationParameter(name = "correlationId", description = "Correlation ID")
 })
 public String getTaskErrorMessages(String correlationId) {
   Map<String, TaskItemResult> taskItems =
       taskExecutor.getTaskResult(correlationId).getTaskItems();
   if (!taskItems.isEmpty()) {
     StringBuilder errors = new StringBuilder();
     for (TaskItemResult taskItemResult : taskItems.values()) {
       errors.append("[").append(taskItemResult).append("]");
     }
     return errors.toString();
   }
   return "";
 }
示例#14
0
  private static void runTests(Map<String, Path> paths) {
    RunResult runResult = null;
    try {
      runResult = executor.runTests(paths.get(EXERCISE_PATH));
    } catch (NoLanguagePluginFoundException e) {
      log.error("No suitable language plugin for project at {}", paths.get(EXERCISE_PATH), e);
      printErrAndExit(
          "ERROR: Could not find suitable language plugin for the given " + "exercise path.");
    }

    try {
      JsonWriter.writeObjectIntoJsonFormat(runResult, paths.get(OUTPUT_PATH));
      System.out.println("Test results can be found in " + paths.get(OUTPUT_PATH));
    } catch (IOException e) {
      log.error("Could not write output to {}", paths.get(OUTPUT_PATH), e);
      printErrAndExit("ERROR: Could not write the results to the given file.");
    }
  }
  private void checkLicense() {
    if (preferences.getLicenseCount() >= 2) {
      return;
    }

    if (System.currentTimeMillis() - preferences.getLastLicenseTime() <= 1000 * 60 * 30) {
      return;
    }

    // over half hour since last registration, register again to prevent 15 minute return policy
    // abuse
    LicenseCheckingTask task = new LicenseCheckingTask(this);
    task.setCallback(
        new Callback<LicenseCheckingTask.LicenseCheckingMessage>() {
          @Override
          public void doStuff(LicenseCheckingTask.LicenseCheckingMessage param) {
            backgroundOperationEnded();

            switch (param.licenseCheckingStatus) {
              case Allow:
                // yay! do nothing
                break;
              case Disallow:
                preferences.setLicenseCount(0);
                MessageBox.Show(
                    IrssiNotifierActivity.this,
                    getText(R.string.not_licensed_title),
                    getText(R.string.not_licensed),
                    new Callback<Void>() {
                      @Override
                      public void doStuff(Void param) {
                        IrssiNotifierActivity.this.finish();
                      }
                    });
                break;
              case Error:
                // do nothing, on next startup licensing will be retried
                break;
            }
          }
        });
    TaskExecutor.executeOnThreadPoolIfPossible(task);
    backgroundOperationStarted();
  }
示例#16
0
  private static void runCheckCodeStyle(Map<String, Path> paths) {
    ValidationResult validationResult = null;
    try {
      validationResult = executor.runCheckCodeStyle(paths.get(EXERCISE_PATH));
    } catch (NoLanguagePluginFoundException e) {
      log.error(
          "Could not find a language plugin for the project at {}", paths.get(EXERCISE_PATH), e);
      printErrAndExit(
          "ERROR: Could not find suitable language plugin for the given exercise " + "path.");
    }

    try {
      JsonWriter.writeObjectIntoJsonFormat(validationResult, paths.get(OUTPUT_PATH));
      System.out.println("Codestyle report can be found at " + paths.get(OUTPUT_PATH));
    } catch (IOException e) {
      log.error("Could not write result into {}", paths.get(OUTPUT_PATH), e);
      printErrAndExit("ERROR: Could not write the results to the given file.");
    }
  }
  private void sendSettings() {
    SettingsSendingTask task =
        new SettingsSendingTask(this, "", getString(R.string.sending_settings_to_server));

    final Context ctx = this;
    task.setCallback(
        new Callback<ServerResponse>() {
          public void doStuff(ServerResponse result) {
            backgroundOperationEnded();
            if (result.getException() != null) {
              handleNetworkException(result.getException());
              return;
            }

            if (!result.wasSuccesful()) {
              MessageBox.Show(ctx, null, getString(R.string.unable_to_send_settings), null);
            }
          }
        });

    TaskExecutor.executeOnThreadPoolIfPossible(task);
    backgroundOperationStarted();
  }
示例#18
0
 public void setExecutorId(int executorId) {
   this.mExecutorId = executorId;
   mExecutor = TaskExecutor.getInstance(mExecutorId);
 }
示例#19
0
  @Override
  public void execute(CancellationToken cancelToken, CancelableTask task, CleanupTask cleanupTask) {
    final TaskDef taskDef = new TaskDef(cancelToken, task, cleanupTask);

    final RefCollection.ElementRef<TaskDef> taskDefRef;
    queueLock.lock();
    try {
      taskDefRef = taskQueue.addLastGetReference(taskDef);
    } finally {
      queueLock.unlock();
    }

    final ListenerRef cancelRef;
    if (taskDef.hasCleanupTask()) {
      cancelRef =
          cancelToken.addCancellationListener(
              new Runnable() {
                @Override
                public void run() {
                  taskDef.removeTask();
                }
              });
    } else {
      cancelRef =
          cancelToken.addCancellationListener(
              new Runnable() {
                @Override
                public void run() {
                  queueLock.lock();
                  try {
                    taskDefRef.remove();
                  } finally {
                    queueLock.unlock();
                  }
                }
              });
    }

    final AtomicBoolean executorCancellation = new AtomicBoolean(true);
    // Notice that we pass an Cancellation.UNCANCELABLE_TOKEN and so we
    // assume if the submitted task gets canceled
    executor.execute(
        Cancellation.UNCANCELABLE_TOKEN,
        new CancelableTask() {
          @Override
          public void execute(CancellationToken cancelToken) {
            try {
              dispatchTasks(cancelToken);
            } finally {
              executorCancellation.set(false);
            }
          }
        },
        new CleanupTask() {
          @Override
          public void cleanup(boolean canceled, Throwable error) {
            try {
              cancelRef.unregister();
            } finally {
              // If the executor did not execute our task, this might be
              // our last chance to execute the cleanup tasks.
              // Note that since we pass CANCELED_TOKEN, only cleanup
              // tasks will be executed.
              if (executorCancellation.get()) {
                dispatchTasks(Cancellation.CANCELED_TOKEN);
              }
            }
          }
        });
  }
示例#20
0
 private void ensureExecutor() {
   if (mExecutor == null) {
     mExecutor = TaskExecutor.getInstance(mExecutorId);
   }
 }
示例#21
0
 /**
  * Returns the array of tasks correlation ids.
  *
  * @return String[] the array of tasks.
  * @throws Exception in case of exception happened.
  */
 @ManagedAttribute
 public String[] getTasksCorrelationIds() {
   return taskExecutor.getTasksCorrelationIds();
 }
示例#22
0
 /**
  * 将该任务排在队列最前面,如果线程暂停,会唤醒线程继续执行任务
  *
  * @param params
  */
 public void executeNow(PARAMS... params) {
   this.params = params;
   ensureExecutor();
   mExecutor.executeNow(this);
 }
示例#23
0
  @Override
  public void start() {
    try {
      /** 状态check时间间隔,较短,可以把任务及时分发到对应channel中 */
      int sleepIntervalInMillSec =
          this.configuration.getInt(CoreConstant.DATAX_CORE_CONTAINER_TASKGROUP_SLEEPINTERVAL, 100);
      /** 状态汇报时间间隔,稍长,避免大量汇报 */
      long reportIntervalInMillSec =
          this.configuration.getLong(
              CoreConstant.DATAX_CORE_CONTAINER_TASKGROUP_REPORTINTERVAL, 5000);

      // 获取channel数目
      int channelNumber =
          this.configuration.getInt(CoreConstant.DATAX_CORE_CONTAINER_TASKGROUP_CHANNEL);

      int taskMaxRetryTimes =
          this.configuration.getInt(
              CoreConstant.DATAX_CORE_CONTAINER_TASK_FAILOVER_MAXRETRYTIMES, 1);

      long taskRetryIntervalInMsec =
          this.configuration.getLong(
              CoreConstant.DATAX_CORE_CONTAINER_TASK_FAILOVER_RETRYINTERVALINMSEC, 10000);

      long taskMaxWaitInMsec =
          this.configuration.getLong(
              CoreConstant.DATAX_CORE_CONTAINER_TASK_FAILOVER_MAXWAITINMSEC, 60000);

      List<Configuration> taskConfigs =
          this.configuration.getListConfiguration(CoreConstant.DATAX_JOB_CONTENT);

      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "taskGroup[{}]'s task configs[{}]", this.taskGroupId, JSON.toJSONString(taskConfigs));
      }

      int taskCountInThisTaskGroup = taskConfigs.size();
      LOG.info(
          String.format(
              "taskGroupId=[%d] start [%d] channels for [%d] tasks.",
              this.taskGroupId, channelNumber, taskCountInThisTaskGroup));

      this.containerCommunicator.registerCommunication(taskConfigs);

      Map<Integer, Configuration> taskConfigMap = buildTaskConfigMap(taskConfigs); // taskId与task配置
      List<Configuration> taskQueue = buildRemainTasks(taskConfigs); // 待运行task列表
      Map<Integer, TaskExecutor> taskFailedExecutorMap =
          new HashMap<Integer, TaskExecutor>(); // taskId与上次失败实例
      List<TaskExecutor> runTasks = new ArrayList<TaskExecutor>(channelNumber); // 正在运行task
      Map<Integer, Long> taskStartTimeMap = new HashMap<Integer, Long>(); // 任务开始时间

      long lastReportTimeStamp = 0;
      Communication lastTaskGroupContainerCommunication = new Communication();

      while (true) {
        // 1.判断task状态
        boolean failedOrKilled = false;
        Map<Integer, Communication> communicationMap = containerCommunicator.getCommunicationMap();
        for (Map.Entry<Integer, Communication> entry : communicationMap.entrySet()) {
          Integer taskId = entry.getKey();
          Communication taskCommunication = entry.getValue();
          if (!taskCommunication.isFinished()) {
            continue;
          }
          TaskExecutor taskExecutor = removeTask(runTasks, taskId);

          // 上面从runTasks里移除了,因此对应在monitor里移除
          taskMonitor.removeTask(taskId);

          // 失败,看task是否支持failover,重试次数未超过最大限制
          if (taskCommunication.getState() == State.FAILED) {
            taskFailedExecutorMap.put(taskId, taskExecutor);
            if (taskExecutor.supportFailOver()
                && taskExecutor.getAttemptCount() < taskMaxRetryTimes) {
              taskExecutor.shutdown(); // 关闭老的executor
              containerCommunicator.resetCommunication(taskId); // 将task的状态重置
              Configuration taskConfig = taskConfigMap.get(taskId);
              taskQueue.add(taskConfig); // 重新加入任务列表
            } else {
              failedOrKilled = true;
              break;
            }
          } else if (taskCommunication.getState() == State.KILLED) {
            failedOrKilled = true;
            break;
          } else if (taskCommunication.getState() == State.SUCCEEDED) {
            Long taskStartTime = taskStartTimeMap.get(taskId);
            if (taskStartTime != null) {
              Long usedTime = System.currentTimeMillis() - taskStartTime;
              LOG.info(
                  "taskGroup[{}] taskId[{}] is successed, used[{}]ms",
                  this.taskGroupId,
                  taskId,
                  usedTime);
              // usedTime*1000*1000 转换成PerfRecord记录的ns,这里主要是简单登记,进行最长任务的打印。因此增加特定静态方法
              PerfRecord.addPerfRecord(
                  taskGroupId,
                  taskId,
                  PerfRecord.PHASE.TASK_TOTAL,
                  taskStartTime,
                  usedTime * 1000L * 1000L);
              taskStartTimeMap.remove(taskId);
              taskConfigMap.remove(taskId);
            }
          }
        }

        // 2.发现该taskGroup下taskExecutor的总状态失败则汇报错误
        if (failedOrKilled) {
          lastTaskGroupContainerCommunication =
              reportTaskGroupCommunication(
                  lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);

          throw DataXException.asDataXException(
              FrameworkErrorCode.PLUGIN_RUNTIME_ERROR,
              lastTaskGroupContainerCommunication.getThrowable());
        }

        // 3.有任务未执行,且正在运行的任务数小于最大通道限制
        Iterator<Configuration> iterator = taskQueue.iterator();
        while (iterator.hasNext() && runTasks.size() < channelNumber) {
          Configuration taskConfig = iterator.next();
          Integer taskId = taskConfig.getInt(CoreConstant.TASK_ID);
          int attemptCount = 1;
          TaskExecutor lastExecutor = taskFailedExecutorMap.get(taskId);
          if (lastExecutor != null) {
            attemptCount = lastExecutor.getAttemptCount() + 1;
            long now = System.currentTimeMillis();
            long failedTime = lastExecutor.getTimeStamp();
            if (now - failedTime < taskRetryIntervalInMsec) { // 未到等待时间,继续留在队列
              continue;
            }
            if (!lastExecutor.isShutdown()) { // 上次失败的task仍未结束
              if (now - failedTime > taskMaxWaitInMsec) {
                markCommunicationFailed(taskId);
                reportTaskGroupCommunication(
                    lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);
                throw DataXException.asDataXException(
                    CommonErrorCode.WAIT_TIME_EXCEED, "task failover等待超时");
              } else {
                lastExecutor.shutdown(); // 再次尝试关闭
                continue;
              }
            } else {
              LOG.info(
                  "taskGroup[{}] taskId[{}] attemptCount[{}] has already shutdown",
                  this.taskGroupId,
                  taskId,
                  lastExecutor.getAttemptCount());
            }
          }
          Configuration taskConfigForRun = taskMaxRetryTimes > 1 ? taskConfig.clone() : taskConfig;
          TaskExecutor taskExecutor = new TaskExecutor(taskConfigForRun, attemptCount);
          taskStartTimeMap.put(taskId, System.currentTimeMillis());
          taskExecutor.doStart();

          iterator.remove();
          runTasks.add(taskExecutor);

          // 上面,增加task到runTasks列表,因此在monitor里注册。
          taskMonitor.registerTask(taskId, this.containerCommunicator.getCommunication(taskId));

          taskFailedExecutorMap.remove(taskId);
          LOG.info(
              "taskGroup[{}] taskId[{}] attemptCount[{}] is started",
              this.taskGroupId,
              taskId,
              attemptCount);
        }

        // 4.任务列表为空,executor已结束, 搜集状态为success--->成功
        if (taskQueue.isEmpty()
            && isAllTaskDone(runTasks)
            && containerCommunicator.collectState() == State.SUCCEEDED) {
          // 成功的情况下,也需要汇报一次。否则在任务结束非常快的情况下,采集的信息将会不准确
          lastTaskGroupContainerCommunication =
              reportTaskGroupCommunication(
                  lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);

          LOG.info("taskGroup[{}] completed it's tasks.", this.taskGroupId);
          break;
        }

        // 5.如果当前时间已经超出汇报时间的interval,那么我们需要马上汇报
        long now = System.currentTimeMillis();
        if (now - lastReportTimeStamp > reportIntervalInMillSec) {
          lastTaskGroupContainerCommunication =
              reportTaskGroupCommunication(
                  lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);

          lastReportTimeStamp = now;

          // taskMonitor对于正在运行的task,每reportIntervalInMillSec进行检查
          for (TaskExecutor taskExecutor : runTasks) {
            taskMonitor.report(
                taskExecutor.getTaskId(),
                this.containerCommunicator.getCommunication(taskExecutor.getTaskId()));
          }
        }

        Thread.sleep(sleepIntervalInMillSec);
      }

      // 6.最后还要汇报一次
      reportTaskGroupCommunication(lastTaskGroupContainerCommunication, taskCountInThisTaskGroup);

    } catch (Throwable e) {
      Communication nowTaskGroupContainerCommunication = this.containerCommunicator.collect();

      if (nowTaskGroupContainerCommunication.getThrowable() == null) {
        nowTaskGroupContainerCommunication.setThrowable(e);
      }
      nowTaskGroupContainerCommunication.setState(State.FAILED);
      this.containerCommunicator.report(nowTaskGroupContainerCommunication);

      throw DataXException.asDataXException(FrameworkErrorCode.RUNTIME_ERROR, e);
    } finally {
      if (!PerfTrace.getInstance().isJob()) {
        // 最后打印cpu的平均消耗,GC的统计
        VMInfo vmInfo = VMInfo.getVmInfo();
        if (vmInfo != null) {
          vmInfo.getDelta(false);
          LOG.info(vmInfo.totalString());
        }

        LOG.info(PerfTrace.getInstance().summarizeNoException());
      }
    }
  }