use of jetbrains.buildServer.buildTriggers.vcs.git.process.GitProcessStuckMonitor in project teamcity-git by JetBrains.
the class FetchCommandImpl method fetchInSeparateProcess.
private void fetchInSeparateProcess(@NotNull Repository repository, @NotNull URIish uri, @NotNull FetchSettings settings) throws VcsException {
final Collection<RefSpec> specs = settings.getRefSpecs();
final String debugInfo = getDebugInfo(repository, uri, specs);
final ProcessXmxProvider xmxProvider = new ProcessXmxProvider(new RepositoryXmxStorage(repository, "fetch"), myConfig, "fetch", debugInfo);
Integer xmx = xmxProvider.getNextXmx();
int attempt = 0;
while (xmx != null) {
attempt++;
File gitPropertiesFile = null;
File teamcityPrivateKey = null;
GitProcessStuckMonitor processStuckMonitor = null;
try {
File gcDump = getDumpFile(repository, "gc");
gitPropertiesFile = myFetcherProperties.getPropertiesFile();
teamcityPrivateKey = getTeamCityPrivateKey(settings.getAuthSettings());
final GeneralCommandLine cl = createFetcherCommandLine(repository, uri, xmx);
final String commandLineString = cl.getCommandLineString();
final GitProcessExecutor processExecutor = new GitProcessExecutor(cl);
processStuckMonitor = new GitProcessStuckMonitor(gcDump, xmx.longValue(), commandLineString) {
@Override
protected void stuckDetected() {
processExecutor.interrupt();
}
};
processStuckMonitor.start();
final GitProcessExecutor.GitExecResult gitResult = processExecutor.runProcess(getFetchProcessInputBytes(getAuthSettings(settings, teamcityPrivateKey), repository.getDirectory(), uri, specs, getDumpFile(repository, null), gcDump, gitPropertiesFile), myConfig.getFetchTimeout(), settings.createStdoutBuffer(), new ByteArrayOutputStream(), new GitProcessExecutor.ProcessExecutorAdapter() {
@Override
public void processStarted() {
if (LOG.isDebugEnabled())
LOG.debug("git fetch process for " + debugInfo + " started in separate process with command line: " + commandLineString);
settings.getProgress().reportProgress("git fetch " + uri);
}
@Override
public void processFinished() {
if (LOG.isDebugEnabled())
LOG.debug("git fetch process for " + debugInfo + " finished");
settings.getProgress().reportProgress("git fetch " + uri + " finished");
}
@Override
public void processFailed(@NotNull final ExecutionException e) {
if (LOG.isDebugEnabled())
LOG.debug("git fetch process for " + debugInfo + " failed");
settings.getProgress().reportProgress("git fetch " + uri + " failed");
}
});
final ExecResult result = gitResult.getExecResult();
VcsException commandError = CommandLineUtil.getCommandLineError("git fetch", " (repository dir: <TeamCity data dir>/system/caches/git/" + repository.getDirectory().getName() + ")", result, true, true);
if (commandError != null) {
commandError.setRecoverable(isRecoverable(commandError));
/* if the process had not enough memory or we killed it because gc */
if (gitResult.isOutOfMemoryError() || gitResult.isInterrupted()) {
final Integer nextXmx = xmxProvider.getNextXmx();
if (nextXmx != null) {
xmx = nextXmx;
clean(repository);
continue;
}
commandError = new VcsException("There is not enough memory for git fetch (last attempted -Xmx" + xmx + "M). Please contact your system administrator", commandError);
} else if (attempt == 1 && settings.getAuthSettings().doesTokenNeedRefresh()) {
LOG.debug("git fetch process failed due to suspected token expiration for \"" + uri + "\" in directory \"" + repository.getDirectory() + "\", took " + TimePrinter.createMillisecondsFormatter().formatTime(gitResult.getDuration()) + ". Retrying with token refresh.");
continue;
}
LOG.info("git fetch process failed for \"" + uri + "\" in directory \"" + repository.getDirectory() + "\", took " + TimePrinter.createMillisecondsFormatter().formatTime(gitResult.getDuration()));
if (gitResult.isTimeout()) {
logTimeout(debugInfo, getDumpFile(repository, null));
}
clean(repository);
throw commandError;
}
LOG.info("git fetch process finished for: " + uri + " in directory: " + repository.getDirectory() + ", took " + gitResult.getDuration() + "ms");
if (result.getStderr().length() > 0) {
LOG.warn("Error output produced by git fetch:\n" + result.getStderr());
}
LOG.debug("git fetch process output:\n" + result.getStdout());
break;
} finally {
if (teamcityPrivateKey != null) {
FileUtil.delete(teamcityPrivateKey);
}
if (gitPropertiesFile != null) {
FileUtil.delete(gitPropertiesFile);
}
if (processStuckMonitor != null) {
processStuckMonitor.finish();
}
}
}
}
Aggregations