Программа зависает при попытке убить процесс, пока в конце концов он не будет убит - PullRequest
1 голос
/ 08 февраля 2020

Я работаю над исправлением ошибки, которая приводит к сбою нашего конвейера CI / CD. Во время интеграционного теста мы раскручиваем экземпляр локальной базы данных. Для этого мы используем несколько оболочек mariadb, чтобы запустить его из java кодовой базы.

Этот процесс (потенциально) может занять много времени до завершения sh, что приведет к тайм-ауту наших тестов. В этом случае мы добавили функцию уничтожения процесса, если он не может быть установлен в течение 20 секунд и должен повторить попытку.

Эта часть, кажется, работает.

Странный бит возникает при попытке уничтожить процесс. Кажется, что случайным образом занимает ~ 2-3 минуты, чтобы разблокировать. Это проблематично c по той же причине, что вышеуказанная проблема была проблематична c.

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

watchDog.destroyProcess();
// this part usually returns nearly instantly

try {
  // this part can take minutes...
  resultHandler.waitFor();
} catch (InterruptedException e) {
  throw handleInterruptedException(e);
}

В дополнение к этому, в Mac / Linux есть другое поведение. Если я сделаю что-то вроде resultHandler.waitFor(1000) // Wait with 1000ms timeout before just exiting, на MacBook это будет нормально работать, но на linux я вижу ошибку вроде: java.io.FileNotFoundException: {{executable}} (Text file busy)

Есть идеи по этому поводу?

Я провел некоторое исследование, и похоже, что watchDog.destroyProcess отправляет SIGTERM вместо SIGKILL. Но у меня нет никаких хуков, чтобы получить объект Process, чтобы вместо этого отправить его в KILL.

Спасибо.

1 Ответ

0 голосов
/ 08 февраля 2020

Распространенной причиной блокировки при работе с процессами является то, что процесс блокируется на выходе, либо в stdout, либо (с большей вероятностью игнорируется) stderr.

В этом контексте настройка тестов на CI-сервер, вы можете попробовать установить output и error output в INHERIT.

Обратите внимание, что это означает, что вы не будете быть в состоянии прочитать вывод подпроцесса или поток ошибок в вашем коде Java. Я предполагаю, что вы все равно не пытаетесь это сделать, и поэтому процесс зависает. Вместо этого этот вывод будет перенаправлен на вывод процесса Java, и я ожидаю, что ваш CI-сервер зарегистрирует его как часть сборки.

...