From c7f0276005b033f299ca2c56f42c247697025ad6 Mon Sep 17 00:00:00 2001 From: Viktor Lofgren Date: Tue, 22 Aug 2023 11:48:54 +0200 Subject: [PATCH] (control) Don't spin on process output printing This is the "correct" way of copying stdout and stderr to the curren't process' output. --- .../control/process/ProcessService.java | 63 +++++++++++++++---- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/process/ProcessService.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/process/ProcessService.java index 25583f43..14403dfb 100644 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/process/ProcessService.java +++ b/code/services-core/control-service/src/main/java/nu/marginalia/control/process/ProcessService.java @@ -11,6 +11,7 @@ import org.slf4j.MarkerFactory; import javax.inject.Inject; import javax.inject.Singleton; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; @@ -72,24 +73,16 @@ public class ProcessService { processes.put(processId, process); } - try (var es = new BufferedReader(new InputStreamReader(process.getErrorStream())); - var os = new BufferedReader(new InputStreamReader(process.getInputStream())) - ) { - eventLog.logEvent("PROCESS-STARTED", processId.toString()); - - while (process.isAlive()) { - if (es.ready()) - logger.warn(processMarker, es.readLine()); - if (os.ready()) - logger.info(processMarker, os.readLine()); - } + try { + new Thread(new ProcessLogStderr(process)).start(); + new Thread(new ProcessLogStdout(process)).start(); final int returnCode = process.waitFor(); logger.info("Process {} terminated with code {}", processId, returnCode); return 0 == returnCode; } catch (Exception ex) { - logger.info("Process {} terminated with code exception", processId); + logger.info("Process {} terminated with exception", processId); throw ex; } finally { @@ -98,6 +91,7 @@ public class ProcessService { } } + private String[] createCommandArguments(String processPath, String[] parameters) { final String[] args = new String[parameters.length + 1]; args[0] = processPath; @@ -153,4 +147,49 @@ public class ProcessService { return key + "=" + val; } + + + + class ProcessLogStderr implements Runnable { + private final Process process; + + public ProcessLogStderr(Process process) { + this.process = process; + } + + @Override + public void run() { + try (var es = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { + String line; + while (((line = es.readLine()) != null)) { + logger.warn(processMarker, line); + } + } + catch (IOException ex) { + logger.error("Error reading process error stream", ex); + } + } + } + + class ProcessLogStdout implements Runnable { + private final Process process; + + public ProcessLogStdout(Process process) { + this.process = process; + } + + @Override + public void run() { + try (var is = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + while (((line = is.readLine()) != null)) { + logger.info(processMarker, line); + } + } + catch (IOException ex) { + logger.error("Error reading process output stream", ex); + } + } + } + }