logic: improved Maven timeout policy (issue #449)

* only timeout if Maven did not generate output during the last 60 seconds
This commit is contained in:
mlangkabel
2017-08-29 14:15:11 +02:00
parent d8413b1cb4
commit 64efa00054
4 changed files with 81 additions and 16 deletions
+45 -2
View File
@@ -18,7 +18,7 @@ namespace utility
std::set<QProcess*> s_runningProcesses;
}
std::string utility::executeProcess(const std::string& command, const std::string& workingDirectory, int timeout)
std::string utility::executeProcess(const std::string& command, const std::string& workingDirectory, const int timeout)
{
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
@@ -47,7 +47,50 @@ std::string utility::executeProcess(const std::string& command, const std::strin
return processoutput;
}
int utility::executeProcessAndGetExitCode(const std::string& command, const std::string& workingDirectory, int timeout)
std::string utility::executeProcessUntilNoOutput(const std::string& command, const std::string& workingDirectory, const int waitTime)
{
QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels);
if (!workingDirectory.empty())
{
process.setWorkingDirectory(workingDirectory.c_str());
}
{
std::lock_guard<std::mutex> lock(s_runningProcessesMutex);
process.start(command.c_str());
s_runningProcesses.insert(&process);
}
std::string processoutput = "";
while (!process.waitForFinished(waitTime))
{
const std::string currentOutput = process.readAll().toStdString();
if (currentOutput.empty())
{
LOG_WARNING("Canceling process because it did not generate any output during the last " + std::to_string(waitTime / 1000) + " seconds.");
break;
}
else
{
processoutput += currentOutput;
}
}
{
std::lock_guard<std::mutex> lock(s_runningProcessesMutex);
s_runningProcesses.erase(&process);
}
processoutput += process.readAll().toStdString();
process.close();
processoutput = utility::trim(processoutput);
return processoutput;
}
int utility::executeProcessAndGetExitCode(const std::string& command, const std::string& workingDirectory, const int timeout)
{
QProcess process;
+3 -2
View File
@@ -11,8 +11,9 @@ class License;
namespace utility
{
std::string executeProcess(const std::string& command, const std::string& workingDirectory = "", int timeout = 30000);
int executeProcessAndGetExitCode(const std::string& command, const std::string& workingDirectory = "", int timeout = 30000);
std::string executeProcess(const std::string& command, const std::string& workingDirectory = "", const int timeout = 30000);
std::string executeProcessUntilNoOutput(const std::string& command, const std::string& workingDirectory, int waitTime = 10000);
int executeProcessAndGetExitCode(const std::string& command, const std::string& workingDirectory = "", const int timeout = 30000);
void killRunningProcesses();
+9 -6
View File
@@ -162,16 +162,19 @@ bool SourceGroupJava::prepareMavenData()
"Please make sure to provide the correct Maven Path in the preferences.";
MessageStatus(dialogMessage, true, false).dispatch();
Application::getInstance()->handleDialog(dialogMessage);
return false;
}
dialogView->showUnknownProgressDialog("Preparing Project", "Maven\nExporting Dependencies");
if (success)
{
dialogView->showUnknownProgressDialog("Preparing Project", "Maven\nExporting Dependencies");
utility::mavenCopyDependencies(
mavenPath, projectRootPath, m_settings->getMavenDependenciesDirectoryExpandedAndAbsolute()
);
success = utility::mavenCopyDependencies(
mavenPath, projectRootPath, m_settings->getMavenDependenciesDirectoryExpandedAndAbsolute()
);
}
return success;
}
return true;
+24 -6
View File
@@ -66,9 +66,10 @@ namespace utility
{
setJavaHomeVariableIfNotExists();
const std::string output = utility::executeProcess(
const std::string output = utility::executeProcessUntilNoOutput(
"\"" + mavenPath.str() + "\" generate-sources",
projectDirectoryPath.str()
projectDirectoryPath.str(),
60000
);
return !output.empty();
}
@@ -77,10 +78,26 @@ namespace utility
{
setJavaHomeVariableIfNotExists();
const std::string output = utility::executeProcess(
const std::string output = utility::executeProcessUntilNoOutput(
"\"" + mavenPath.str() + "\" dependency:copy-dependencies -DoutputDirectory=" + outputDirectoryPath.str(),
projectDirectoryPath.str()
projectDirectoryPath.str(),
60000
);
std::shared_ptr<TextAccess> outputAccess = TextAccess::createFromString(output);
for (const std::string& line: outputAccess->getAllLines())
{
if (utility::isPrefix("[ERROR]", utility::trim(line)))
{
// TODO: move error handling to caller of this function
const std::string dialogMessage =
"The following error occurred while executing a Maven command:\n\n" + utility::replace(line, "\r\n", "\n");
MessageStatus(dialogMessage, true, false).dispatch();
Application::getInstance()->handleDialog(dialogMessage);
return false;
}
}
return !output.empty();
}
@@ -88,9 +105,10 @@ namespace utility
{
setJavaHomeVariableIfNotExists();
std::shared_ptr<TextAccess> outputAccess = TextAccess::createFromString(utility::executeProcess(
std::shared_ptr<TextAccess> outputAccess = TextAccess::createFromString(utility::executeProcessUntilNoOutput(
"\"" + mavenPath.str() + "\" help:effective-pom",
projectDirectoryPath.str()
projectDirectoryPath.str(),
60000
));
if (outputAccess->getLineCount() > 0 && utility::isPrefix("Error", utility::trim(outputAccess->getLine(1))))