From 2c4104a4b6f1195255eca048ac83eb5eb7e7c767 Mon Sep 17 00:00:00 2001 From: Maninthmire <81275874@qq.com> Date: Tue, 20 Aug 2024 12:19:07 +0800 Subject: [PATCH] Using threads to asynchronously read output and error streams before waitFor() --- .../tencent/trpc/codegen/protoc/Protoc.java | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/trpc-code-generator/src/main/java/com/tencent/trpc/codegen/protoc/Protoc.java b/trpc-code-generator/src/main/java/com/tencent/trpc/codegen/protoc/Protoc.java index b36f2ab048..370550f828 100644 --- a/trpc-code-generator/src/main/java/com/tencent/trpc/codegen/protoc/Protoc.java +++ b/trpc-code-generator/src/main/java/com/tencent/trpc/codegen/protoc/Protoc.java @@ -11,6 +11,8 @@ package com.tencent.trpc.codegen.protoc; +import java.io.BufferedReader; +import java.io.InputStreamReader; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -111,15 +113,50 @@ private ProtocExecutionResult runProtoc(ProcessBuilder processBuilder) { } private ProtocExecutionResult fetchProcessResult(Process p) { + StringBuilder outputBuilder = new StringBuilder(); + StringBuilder errorBuilder = new StringBuilder(); + + // Using threads to asynchronously read output and error streams. + Thread outputThread = new Thread(() -> { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + outputBuilder.append(line).append(System.lineSeparator()); + } + } catch (IOException e) { + log.error("failed to read output stream", e); + } + }); + + Thread errorThread = new Thread(() -> { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + errorBuilder.append(line).append(System.lineSeparator()); + } + } catch (IOException e) { + log.error("failed to read error stream", e); + } + }); + + outputThread.start(); + errorThread.start(); + try { int code = p.waitFor(); + outputThread.join(); + errorThread.join(); + if (code == 0) { - return ProtocExecutionResult.success(IOUtils.toString(p.getInputStream(), StandardCharsets.UTF_8)); + return ProtocExecutionResult.success(outputBuilder.toString()); } else { return ProtocExecutionResult.fail("run protoc failed with exit-code " + code, - IOUtils.toString(p.getErrorStream(), StandardCharsets.UTF_8), null); + errorBuilder.toString(), null); } - } catch (IOException | InterruptedException e) { + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); return ProtocExecutionResult.fail("execute protoc failed", null, e); } }