Skip to content

Commit 16803bc

Browse files
author
Vladimir Kotal
committed
Merge pull request #705 from vladak/timeout
timeout for command execution
2 parents 7ebcc5a + 74863c5 commit 16803bc

File tree

3 files changed

+54
-12
lines changed

3 files changed

+54
-12
lines changed

src/org/opensolaris/opengrok/configuration/Configuration.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ public final class Configuration {
119119
private boolean chattyStatusPage;
120120
private final Map<String, String> cmds;
121121
private int tabSize;
122+
private int command_timeout;
122123
private static final Logger logger = Logger.getLogger(Configuration.class.getName());
123124

124125
/**
@@ -161,6 +162,14 @@ public void setScanningDepth(int scanningDepth) {
161162
this.scanningDepth = scanningDepth;
162163
}
163164

165+
public int getCommandTimeout() {
166+
return command_timeout;
167+
}
168+
169+
public void setCommandTimeout(int timeout) {
170+
this.command_timeout = timeout;
171+
}
172+
164173
/**
165174
* Creates a new instance of Configuration
166175
*/
@@ -202,6 +211,7 @@ public Configuration() {
202211
cmds = new HashMap<String, String>();
203212
setSourceRoot(null);
204213
setDataRoot(null);
214+
setCommandTimeout(600); // 10 minutes
205215
}
206216

207217
public String getRepoCmd(String clazzName) {

src/org/opensolaris/opengrok/configuration/RuntimeEnvironment.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ public void setScanningDepth(int scanningDepth) {
103103
threadConfig.get().setScanningDepth(scanningDepth);
104104
}
105105

106+
public int getCommandTimeout() {
107+
return threadConfig.get().getCommandTimeout();
108+
}
109+
110+
public void setCommandTimeout(int timeout) {
111+
threadConfig.get().setCommandTimeout(timeout);
112+
}
113+
106114
/**
107115
* Get the path to the where the index database is stored
108116
*
@@ -894,7 +902,8 @@ public void run() {
894902

895903
if (obj instanceof Configuration) {
896904
setConfiguration((Configuration) obj);
897-
log.log(Level.INFO, "Configuration updated: {0}", configuration.getSourceRoot());
905+
log.log(Level.INFO, "Configuration updated: {0}",
906+
configuration.getSourceRoot());
898907
}
899908
} catch (IOException e) {
900909
log.log(Level.SEVERE, "Error reading config file: ", e);

src/org/opensolaris/opengrok/util/Executor.java

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@
3333
import java.lang.Thread.UncaughtExceptionHandler;
3434
import java.util.Arrays;
3535
import java.util.List;
36+
import java.util.Timer;
37+
import java.util.TimerTask;
3638
import java.util.logging.Level;
3739
import java.util.logging.Logger;
3840

41+
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
3942
import org.opensolaris.opengrok.OpenGrokLogger;
4043

4144
/**
@@ -110,12 +113,21 @@ public int exec(boolean reportExceptions) {
110113
*/
111114
public int exec(final boolean reportExceptions, StreamHandler handler) {
112115
int ret = -1;
113-
114116
ProcessBuilder processBuilder = new ProcessBuilder(cmdList);
117+
final String cmd_str = processBuilder.command().toString();
118+
final String dir_str;
119+
File cwd = processBuilder.directory();
120+
if (cwd == null) {
121+
dir_str = System.getProperty("user.dir");
122+
} else {
123+
dir_str = cwd.toString();
124+
}
125+
115126
if (workingDirectory != null) {
116127
processBuilder.directory(workingDirectory);
117128
if (processBuilder.environment().containsKey("PWD")) {
118-
processBuilder.environment().put("PWD", workingDirectory.getAbsolutePath());
129+
processBuilder.environment().put("PWD",
130+
workingDirectory.getAbsolutePath());
119131
}
120132
}
121133

@@ -129,6 +141,7 @@ public int exec(final boolean reportExceptions, StreamHandler handler) {
129141
Process process = null;
130142
try {
131143
process = processBuilder.start();
144+
final Process proc = process;
132145

133146
final InputStream errorStream = process.getErrorStream();
134147
final SpoolHandler err = new SpoolHandler();
@@ -148,9 +161,24 @@ public void run() {
148161
});
149162
thread.start();
150163

164+
/*
165+
* Setup timer so if the process get stuck we can terminate it and
166+
* make progress instead of hanging the whole indexer.
167+
*/
168+
Timer t = new Timer();
169+
t.schedule(new TimerTask() {
170+
@Override public void run() {
171+
OpenGrokLogger.getLogger().log(Level.INFO,
172+
"Terminating process of command {0} in directory {1} " +
173+
"due to timeout", new Object[]{cmd_str, dir_str});
174+
proc.destroy();
175+
}
176+
}, RuntimeEnvironment.getInstance().getCommandTimeout() * 1000);
177+
151178
handler.processStream(process.getInputStream());
152179

153180
ret = process.waitFor();
181+
t.cancel();
154182
process = null;
155183
thread.join();
156184
stderr = err.getBytes();
@@ -175,17 +203,12 @@ public void run() {
175203
}
176204

177205
if (ret != 0 && reportExceptions) {
178-
int MAX_MSG_SZ = 512; /* limit to avoid floodding the logs */
206+
int MAX_MSG_SZ = 512; /* limit to avoid flooding the logs */
179207
StringBuilder msg = new StringBuilder("Non-zero exit status ")
180208
.append(ret).append(" from command ")
181-
.append(processBuilder.command().toString())
182-
.append(" in directory ");
183-
File cwd = processBuilder.directory();
184-
if (cwd == null) {
185-
msg.append(System.getProperty("user.dir"));
186-
} else {
187-
msg.append(cwd.toString());
188-
}
209+
.append(cmd_str)
210+
.append(" in directory ")
211+
.append(dir_str);
189212
if (stderr != null && stderr.length > 0) {
190213
msg.append(": ");
191214
if (stderr.length > MAX_MSG_SZ) {

0 commit comments

Comments
 (0)