Некоторые вопросы по запуску ProcessBuilder через веб-приложение - PullRequest
1 голос
/ 28 октября 2011

Я пишу веб-приложение, которое в основном позволяет пользователям запускать сценарии оболочки с параметрами, которые они вводят в различных формах. Проведя некоторые исследования, я считаю, что ProcessBuilder - лучший способ запуска сценариев оболочки, однако у меня есть некоторые условия, которые мне необходимо выполнить, и я надеялся, что некоторые другие могут сказать мне, если я думаю в правильном направлении.

Запуск сценариев может буквально занять несколько часов. Поэтому, очевидно, я не могу заставить приложение остановиться и ждать так долго. Так что мне интересно, если темы является ответом на эту проблему? Я не очень опытен в использовании тем и ищу несколько советов. Должен ли я запустить ProcessBuilder в новом потоке, чтобы основное веб-приложение продолжало работать? Будет ли это даже работать? Это так же просто, как просто объявить новый поток и назначить ему построитель процессов? Должен ли я беспокоиться о запуске или создании различных потоков? Просто не уверен в том, на что следует обращать внимание или какие подводные камни нужно знать.

Кроме того, мне действительно нужен способ, чтобы хотя бы проверить состояние процесса после его запуска. Требования требуют некоторого способа показать, насколько далеко продвинулся процесс, но я не знаю, возможно ли это. Я считаю, что возможность, по крайней мере, показать, что он все еще работает, должна быть приемлемой. Как бы я узнал об этом?

Для получения дополнительной информации это веб-приложение на Java / Spring, которое будет работать на Unix. Спасибо за любые мысли и помощь.

1 Ответ

3 голосов
/ 28 октября 2011

Вы можете реализовать что-то вроде JobManager и Job.

A Job может быть Runnable с ProcessBuilder. В его методе run он запускает процесс (ProcessBuilder.start), ожидает его завершения и вызывает обратно к JobManager после завершения, возможно возвращая статус завершения процесса.

JobManager создает Jobs (каждый в новом Thread), поддерживает набор текущих заданий (и, возможно, набор недавно выполненных заданий, может быть список невыполненных заданий). Клиенты могут давать задания JobManager для выполнения и запрашивать состояние (запущен, завершен, не выполнен) всех заданий или определенного задания.

Что касается статуса процесса, задание может иметь переменные startTime, endTime и exitStatus и связанные методы get. Вы можете вернуть их клиенту для отображения таблицы статуса задания.

Ваш Job.run метод может выглядеть примерно так.

public void run() {
  startTime = System.currentTimeMillis();  
  process = processBuilder.start();

  // spawn threads to consume process output streams
  // even if you're not going to read them

  while (running) {
    try {
      process.waitFor();
      running = false;
    } catch (InterruptedException e) {
      // you could stop a process by interrupting it's Job thread
      process.destroy();
    }
  }
  exitStatus = process.exitValue();
  endTime = System.currentTimeMillis();
  jobManager.onExit(this);
}

Относительно "% complete", это будет возможно, только если у вас есть какой-то способ его измерения.

Если задача должна быть выполнена в течение определенного времени, вы можете использовать это как грубый способ сообщить ожидаемое время завершения / процент выполнения.

Или, возможно, вы могли бы захватить выходные данные процессов, используя это для установки переменной процентаComplete в вашем задании. Например, когда вы видите «сообщение X» в выводе, установите процентComplete = 25%. Это будет означать реализацию пользовательского кода для каждого типа скрипта - может быть, подкласс Job или дать Job переменную-член, отвечающую за анализ выходных данных.

...