Reputation: 5102
Here is my workflow:
I get job from DB, I run a few tasks, I run an external program that reads a file and produces another one (this usually takes under 10 seconds). Here is the code:
Process p = Runtime.getRuntime().exec(prog, null, new File(path));
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String s;
String errorString = "";
while((s = stdInput.readLine()) != null) {
if(s.toLowerCase().contains("error")) {
Log.writeLog("error: " + s);
errorString += s + "\r\n";
}
}
if(errorString.length() > 1) {
Emailer.email(name + "*" + errorString, "ERROR");
}
while((s = stdError.readLine()) != null) {
Log.writeLog("ERROR: " + s);
}
However, the snippet hanged. I control the server that the code runs on through LogMeIn, once I logged in, the process unblocked (total running time around 280 seconds) and continued. The process did not produce an ERROR
results. This happens from time to time more often than we would like to. We do quite a bit of small IOs operation in the program and the harddrive gets pretty full from time to time.
Any idea what could be happening?
Thanks!
EDIT: the server is a just a regular computer that is connected to LogMeIn. My fear is that since it is a regular computer, it may powerdown the CPU/hard drive when not in use (not sure the correct terminology). This would somewhat explain why it would continue once I logged in to LogMeIn and had access to a computer.
EDIT2: directly following the process, I run this. And this hangs for an absurd amount of time as well (usually 5 seconds, took 200+ seconds). Makes me thing that the hard drive is decided to take a nap?
private void cleanup(String path) {
File srcPath = new File(path);
File[] files = srcPath.listFiles();
if(files != null) {
for(File file : files) {
if(file.isDirectory()) {
cleanup(file.getAbsolutePath());
} else {
if(file.getAbsolutePath().endsWith(".original")) {
String fileName = file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".original"));
IO.delete(fileName);
if(!IO.renameFile(file.getAbsolutePath(), new File(fileName).getAbsolutePath())) {
Log.writeLogSevere("Failed to rename file, this could be a problem..." + fileName);
} else {
Log.writeLog("Cleaned up: " + fileName);
}
}
}
}
}
}
Upvotes: 0
Views: 898
Reputation: 200148
You are not draining the error stream. You do it at the end, which may often be too late. The output buffer of the process fills up and the process blocks waiting to get more space in the stderr
output buffer.
You must either use a separate thread for that, or (much simpler) redirectErrorStream
using ProcessBuilder
.
Upvotes: 1
Reputation: 21902
The most likely thing is that the thread running p
didn't die and p.getInputStream()
is not null, and but not data on it.
While it's hanging, I would check the current running processes (ps
command on Unix) or Task manager on windows. This will tell you if p
is done or not. If it is not, then whatever that program is, has issues and it's holding up the rest of your code.
Upvotes: 0