英文:
Java - Running a subprocess works locally but fails with "broken pipe" when ran on Heroku?
问题
正如背景所述,我有一个基于Java的Discord机器人,在Heroku上部署,使用一个免费的worker dyno。我需要运行一个.exe文件(stockfish 12可执行文件),将输入传递给它并处理输出。我正在使用Java RunTime来创建这个进程,但是当我尝试使用flush()方法向其发送输入时,会抛出"broken pipe"错误。我猜想Heroku可能会在某种程度上关闭输入/输出流,因为此代码在本地运行正常。Heroku是否对创建子进程有限制?
EDIT:我尝试通过硬编码单个命令来简化程序,但仍无法在writer.flush()行之后执行。没有任何输出被打印。
Process process = new ProcessBuilder().command("bin/stockfish_20090216_x64_bmi2.exe").start();
StringBuilder output = new StringBuilder();
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
writer.write("position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + "\n");
writer.write("go movetime 1000");
writer.flush();
String line;
while ((line = input.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("success");
System.out.println(output.toString());
} else {
System.out.println("error");
}
英文:
Just as a background, I have a Java-based Discord bot deployed on Heroku using the 1 free worker dyno. I need to run a .exe file (stockfish 12 executable), pass input into it and process output from it. I'm using Java RunTime to create this Process but when I try to send input to it with the flush() method the broken pipe error is thrown. I assume Heroku must be closing the input / output stream somehow because this code runs fine locally. Does Heroku have a limit on creating sub processes?
app[worker.1]: chess.player.ai.stockfish.exception.StockfishEngineException: java.io.IOException: Broken pipe
app[worker.1]: at chess.player.ai.stockfish.engine.UCIEngine.sendCommand(UCIEngine.java:39)
app[worker.1]: at chess.player.ai.stockfish.engine.UCIEngine.passOption(UCIEngine.java:77)
app[worker.1]: at chess.player.ai.stockfish.engine.UCIEngine.<init>(UCIEngine.java:23)
app[worker.1]: at chess.player.ai.stockfish.engine.Stockfish.<init>(Stockfish.java:13)
app[worker.1]: at chess.player.ai.stockfish.StockFishClient.<init>(StockFishClient.java:21)
app[worker.1]: at chess.player.ai.stockfish.StockFishClient$Builder.build(StockFishClient.java:80)
EDIT: I tried to simplify the program by hard coding a single command and it still fails to get past the writer.flush() line. Nothing is printed.
Process process = new ProcessBuilder().command("bin/stockfish_20090216_x64_bmi2.exe").start();
StringBuilder output = new StringBuilder();
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
writer.write("position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + "\n");
writer.write("go movetime 1000");
writer.flush();
String line;
while ((line = input.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
System.out.println("success");
System.out.println(output.toString());
}
else {
System.out.println("error");
}
答案1
得分: 0
output
流会自行关闭。当您运行一个命令、创建一个新进程或者此命令必须阻塞流并等待输入时,请使用ProcessBuilder
,它更易于配置:
new ProcessBuilder().command("cmd.exe", "/c", "command")
.directory(new File(path))
.redirectInput(new File(path, "input.txt"))
.redirectOutput(new File(path, "output.txt"))
.redirectError(new File(path, "runtime_error.txt"))
.start()
.waitFor();
英文:
output
stream closes itself. When you run a command, create a new process or this command must block a stream and await an input.
Recommend ProcessBuilder, it is more easily to configure:
new ProcessBuilder().command("cmd.exe", "/c", "command")
.directory(new File(path))
.redirectInput(new File(path, "input.txt"))
.redirectOutput(new File(path, "output.txt"))
.redirectError(new File(path, "runtime_error.txt"))
.start()
.waitFor();
答案2
得分: 0
原来我使用的是错误的二进制文件。Stockfish 二进制文件有许多不同的格式,显然在我的本地运行的那个在 Heroku 上不起作用。
英文:
Turns out I was using the wrong binary file. Stockfish binary comes in many different formats and apparently the one that works for my local didn't work on Heroku.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论