Некоторые вопросы о запуске ProcessBuilder через веб-приложение

#java #multithreading #spring #thread-safety

#java #многопоточность #весна #безопасность потоков

Вопрос:

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

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

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

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

Ответ №1:

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

A Job может быть a Runnable , который имеет a ProcessBuilder . В этом run методе он запускает process ( 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», это будет возможно только в том случае, если у вас есть какой-то способ его измерения.

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

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

Комментарии:

1. Очень умная идея, большое вам спасибо за вклад. Мне обязательно нужно будет больше читать о потоках и тому подобное, но это кажется самым разумным способом справиться с тем, что я хочу. Является ли JobManager просто именем или это реальный класс, который я мог бы где-нибудь посмотреть? Любые другие мысли о том, куда я мог бы пойти, чтобы посмотреть на некоторые примеры чего-то подобного?

2. Боюсь, JobManager — это просто имя. Google для «java process management» или аналогичного будет полезен. Возможно, Apache Commons Exec [ commons.apache.org/exec /] может помочь? Я сам им не пользовался.

3. Еще раз большое спасибо. Я изучу это и начну больше читать, и, надеюсь, я смогу получить рабочее решение. Ваш ответ определенно даст мне больше внимания.