
com.hubspot.singularity.runner.base.shared.SimpleProcessManager Maven / Gradle / Ivy
package com.hubspot.singularity.runner.base.shared;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.collect.Sets;
public class SimpleProcessManager extends SafeProcessManager {
public SimpleProcessManager(Logger log) {
super(log);
}
public void runCommand(final List command, final Set acceptableExitCodes) throws InterruptedException, ProcessFailedException {
runCommand(command, Redirect.INHERIT, acceptableExitCodes);
}
public void runCommand(final List command) throws InterruptedException, ProcessFailedException {
runCommand(command, Redirect.INHERIT, Sets.newHashSet(0));
}
public List runCommandWithOutput(final List command, final Set acceptableExitCodes) throws InterruptedException, ProcessFailedException {
return runCommand(command, Redirect.PIPE, acceptableExitCodes);
}
public List runCommandWithOutput(final List command) throws InterruptedException, ProcessFailedException {
return runCommand(command, Redirect.PIPE, Sets.newHashSet(0));
}
public List runCommand(final List command, final Redirect redirectOutput) throws InterruptedException, ProcessFailedException {
return runCommand(command, redirectOutput, Sets.newHashSet(0));
}
public List runCommand(final List command, final Redirect redirectOutput, final Set acceptableExitCodes) throws InterruptedException, ProcessFailedException {
final ProcessBuilder processBuilder = new ProcessBuilder(command);
Optional exitCode = Optional.absent();
Optional reader = Optional.absent();
String processToString = getCurrentProcessToString();
try {
processBuilder.redirectError(Redirect.INHERIT);
processBuilder.redirectOutput(redirectOutput);
final Process process = startProcess(processBuilder);
processToString = getCurrentProcessToString();
if (redirectOutput == Redirect.PIPE) {
reader = Optional.of(new OutputReader(process.getInputStream()));
reader.get().start();
}
exitCode = Optional.of(process.waitFor());
if (reader.isPresent()) {
reader.get().join();
if (reader.get().error.isPresent()) {
throw reader.get().error.get();
}
}
} catch (InterruptedException ie) {
signalKillToProcessIfActive();
throw ie;
} catch (Throwable t) {
getLog().error("Unexpected exception while running {}", processToString, t);
signalKillToProcessIfActive();
throw Throwables.propagate(t);
} finally {
processFinished(exitCode);
}
if (exitCode.isPresent() && !acceptableExitCodes.contains(exitCode.get())) {
throw new ProcessFailedException(String.format("Got unacceptable exit code %s while running %s", exitCode, processToString));
}
if (!reader.isPresent()) {
return Collections.emptyList();
}
return reader.get().output;
}
private static class OutputReader extends Thread {
private final List output;
private final InputStream inputStream;
private Optional error;
public OutputReader(InputStream inputStream) {
this.output = new ArrayList<>();
this.inputStream = inputStream;
this.error = Optional.absent();
}
@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
String line = br.readLine();
while (line != null) {
output.add(line);
line = br.readLine();
}
} catch (Throwable t) {
this.error = Optional.of(t);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy