1
0
Fork 0

fix out-of-memory handling at startup

This commit is contained in:
jsteemann 2017-02-01 13:00:05 +01:00
parent 5939ff249f
commit e2a312450f
26 changed files with 193 additions and 138 deletions

View File

@ -22,9 +22,10 @@
#include "AuthenticationFeature.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "RestServer/QueryRegistryFeature.h"
#include "Random/RandomGenerator.h"
#include "RestServer/QueryRegistryFeature.h"
using namespace arangodb;
using namespace arangodb::options;

View File

@ -22,6 +22,7 @@
#include "CheckVersionFeature.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

View File

@ -23,6 +23,7 @@
#include "ConsoleFeature.h"
#include "Basics/messages.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/ConsoleThread.h"

View File

@ -26,6 +26,7 @@
#include "Basics/ArangoGlobalContext.h"
#include "Basics/FileUtils.h"
#include "Basics/StringUtils.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

View File

@ -23,6 +23,7 @@
#include "EndpointFeature.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/ServerFeature.h"

View File

@ -23,7 +23,7 @@
#include "InitDatabaseFeature.h"
#include "Basics/FileUtils.h"
#include "Logger/LoggerFeature.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

View File

@ -24,6 +24,7 @@
#include "Basics/Exceptions.h"
#include "Basics/FileUtils.h"
#include "Basics/files.h"
#include "Logger/Logger.h"
#include "RestServer/DatabasePathFeature.h"
using namespace arangodb;

View File

@ -23,6 +23,7 @@
#include "ScriptFeature.h"
#include "Basics/messages.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/ConsoleThread.h"

View File

@ -23,6 +23,7 @@
#include "UnitTestsFeature.h"
#include "Basics/messages.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/ConsoleThread.h"

View File

@ -92,114 +92,123 @@
using namespace arangodb;
static int runServer(int argc, char** argv) {
ArangoGlobalContext context(argc, argv, SBIN_DIRECTORY);
context.installSegv();
context.runStartupChecks();
try {
ArangoGlobalContext context(argc, argv, SBIN_DIRECTORY);
context.installSegv();
context.runStartupChecks();
std::string name = context.binaryName();
std::string name = context.binaryName();
auto options = std::make_shared<options::ProgramOptions>(
argv[0], "Usage: " + name + " [<options>]", "For more information use:",
SBIN_DIRECTORY);
auto options = std::make_shared<options::ProgramOptions>(
argv[0], "Usage: " + name + " [<options>]", "For more information use:",
SBIN_DIRECTORY);
application_features::ApplicationServer server(options, SBIN_DIRECTORY);
application_features::ApplicationServer server(options, SBIN_DIRECTORY);
std::vector<std::string> nonServerFeatures = {
"Action", "Affinity",
"Agency", "Authentication",
"Cluster", "Daemon",
"Dispatcher", "FoxxQueues",
"GeneralServer", "LoggerBufferFeature",
"Server", "SslServer",
"Statistics", "Supervisor"};
std::vector<std::string> nonServerFeatures = {
"Action", "Affinity",
"Agency", "Authentication",
"Cluster", "Daemon",
"Dispatcher", "FoxxQueues",
"GeneralServer", "LoggerBufferFeature",
"Server", "SslServer",
"Statistics", "Supervisor"};
int ret = EXIT_FAILURE;
int ret = EXIT_FAILURE;
server.addFeature(new ActionFeature(&server));
server.addFeature(new AgencyFeature(&server));
server.addFeature(new AuthenticationFeature(&server));
server.addFeature(new BootstrapFeature(&server));
server.addFeature(new CheckVersionFeature(&server, &ret, nonServerFeatures));
server.addFeature(new ClusterFeature(&server));
server.addFeature(new ConfigFeature(&server, name));
server.addFeature(new ConsoleFeature(&server));
server.addFeature(new DatabaseFeature(&server));
server.addFeature(new DatabasePathFeature(&server));
server.addFeature(new EndpointFeature(&server));
server.addFeature(new EngineSelectorFeature(&server));
server.addFeature(new FeatureCacheFeature(&server));
server.addFeature(new FileDescriptorsFeature(&server));
server.addFeature(new FoxxQueuesFeature(&server));
server.addFeature(new FrontendFeature(&server));
server.addFeature(new GeneralServerFeature(&server));
server.addFeature(new GreetingsFeature(&server, "arangod"));
server.addFeature(new InitDatabaseFeature(&server, nonServerFeatures));
server.addFeature(new LanguageFeature(&server));
server.addFeature(new LockfileFeature(&server));
server.addFeature(new MMFilesLogfileManager(&server));
server.addFeature(new LoggerBufferFeature(&server));
server.addFeature(new LoggerFeature(&server, true));
server.addFeature(new NonceFeature(&server));
server.addFeature(new PageSizeFeature(&server));
server.addFeature(new PrivilegeFeature(&server));
server.addFeature(new QueryRegistryFeature(&server));
server.addFeature(new TraverserEngineRegistryFeature(&server));
server.addFeature(new RandomFeature(&server));
server.addFeature(new RocksDBFeature(&server));
server.addFeature(new SchedulerFeature(&server));
server.addFeature(new ScriptFeature(&server, &ret));
server.addFeature(new ServerFeature(&server, &ret));
server.addFeature(new ServerIdFeature(&server));
server.addFeature(new ShutdownFeature(&server, {"UnitTests", "Script"}));
server.addFeature(new SslFeature(&server));
server.addFeature(new StatisticsFeature(&server));
server.addFeature(new TempFeature(&server, name));
server.addFeature(new TransactionManagerFeature(&server));
server.addFeature(new UnitTestsFeature(&server, &ret));
server.addFeature(new UpgradeFeature(&server, &ret, nonServerFeatures));
server.addFeature(new V8DealerFeature(&server));
server.addFeature(new V8PlatformFeature(&server));
server.addFeature(new VersionFeature(&server));
server.addFeature(new WorkMonitorFeature(&server));
server.addFeature(new ActionFeature(&server));
server.addFeature(new AgencyFeature(&server));
server.addFeature(new AuthenticationFeature(&server));
server.addFeature(new BootstrapFeature(&server));
server.addFeature(new CheckVersionFeature(&server, &ret, nonServerFeatures));
server.addFeature(new ClusterFeature(&server));
server.addFeature(new ConfigFeature(&server, name));
server.addFeature(new ConsoleFeature(&server));
server.addFeature(new DatabaseFeature(&server));
server.addFeature(new DatabasePathFeature(&server));
server.addFeature(new EndpointFeature(&server));
server.addFeature(new EngineSelectorFeature(&server));
server.addFeature(new FeatureCacheFeature(&server));
server.addFeature(new FileDescriptorsFeature(&server));
server.addFeature(new FoxxQueuesFeature(&server));
server.addFeature(new FrontendFeature(&server));
server.addFeature(new GeneralServerFeature(&server));
server.addFeature(new GreetingsFeature(&server, "arangod"));
server.addFeature(new InitDatabaseFeature(&server, nonServerFeatures));
server.addFeature(new LanguageFeature(&server));
server.addFeature(new LockfileFeature(&server));
server.addFeature(new MMFilesLogfileManager(&server));
server.addFeature(new LoggerBufferFeature(&server));
server.addFeature(new LoggerFeature(&server, true));
server.addFeature(new NonceFeature(&server));
server.addFeature(new PageSizeFeature(&server));
server.addFeature(new PrivilegeFeature(&server));
server.addFeature(new QueryRegistryFeature(&server));
server.addFeature(new TraverserEngineRegistryFeature(&server));
server.addFeature(new RandomFeature(&server));
server.addFeature(new RocksDBFeature(&server));
server.addFeature(new SchedulerFeature(&server));
server.addFeature(new ScriptFeature(&server, &ret));
server.addFeature(new ServerFeature(&server, &ret));
server.addFeature(new ServerIdFeature(&server));
server.addFeature(new ShutdownFeature(&server, {"UnitTests", "Script"}));
server.addFeature(new SslFeature(&server));
server.addFeature(new StatisticsFeature(&server));
server.addFeature(new TempFeature(&server, name));
server.addFeature(new TransactionManagerFeature(&server));
server.addFeature(new UnitTestsFeature(&server, &ret));
server.addFeature(new UpgradeFeature(&server, &ret, nonServerFeatures));
server.addFeature(new V8DealerFeature(&server));
server.addFeature(new V8PlatformFeature(&server));
server.addFeature(new VersionFeature(&server));
server.addFeature(new WorkMonitorFeature(&server));
#ifdef ARANGODB_HAVE_FORK
server.addFeature(new DaemonFeature(&server));
server.addFeature(new SupervisorFeature(&server));
server.addFeature(new DaemonFeature(&server));
server.addFeature(new SupervisorFeature(&server));
#endif
#ifdef _WIN32
server.addFeature(new WindowsServiceFeature(&server));
server.addFeature(new WindowsServiceFeature(&server));
#endif
#ifdef USE_ENTERPRISE
setupServerEE(&server);
setupServerEE(&server);
#else
server.addFeature(new SslServerFeature(&server));
server.addFeature(new SslServerFeature(&server));
#endif
// storage engines
server.addFeature(new MMFilesEngine(&server));
server.addFeature(new MMFilesWalRecoveryFeature(&server));
server.addFeature(new RocksDBEngine(&server));
// storage engines
server.addFeature(new MMFilesEngine(&server));
server.addFeature(new MMFilesWalRecoveryFeature(&server));
server.addFeature(new RocksDBEngine(&server));
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangod terminated because of an unhandled exception: "
<< ex.what();
ret = EXIT_FAILURE;
} catch (...) {
LOG(ERR) << "arangod terminated because of an unhandled exception of "
"unknown type";
ret = EXIT_FAILURE;
}
Logger::flush();
return context.exit(ret);
} catch (std::exception const& ex) {
LOG(ERR) << "arangod terminated because of an unhandled exception: "
<< ex.what();
ret = EXIT_FAILURE;
} catch (...) {
LOG(ERR) << "arangod terminated because of an unhandled exception of "
"unknown type";
ret = EXIT_FAILURE;
}
Logger::flush();
return context.exit(ret);
exit(EXIT_FAILURE);
}
#if _WIN32

View File

@ -26,9 +26,12 @@
#include "Basics/Common.h"
#include "Basics/Mutex.h"
#include "Statistics/StatisticsFeature.h"
#include "Statistics/figures.h"
#include <boost/lockfree/queue.hpp>
namespace arangodb {
class ConnectionStatistics {
public:

View File

@ -22,11 +22,11 @@
////////////////////////////////////////////////////////////////////////////////
#include "RequestStatistics.h"
#include "Basics/MutexLocker.h"
#include "Logger/Logger.h"
#include <iomanip>
#include "Basics/MutexLocker.h"
using namespace arangodb;
using namespace arangodb::basics;

View File

@ -26,10 +26,13 @@
#include "Basics/Common.h"
#include "Basics/Mutex.h"
#include "Rest/CommonDefines.h"
#include "Statistics/StatisticsFeature.h"
#include "Statistics/figures.h"
#include <boost/lockfree/queue.hpp>
namespace arangodb {
class RequestStatistics {
public:

View File

@ -22,6 +22,8 @@
#include "StatisticsFeature.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "Statistics/ConnectionStatistics.h"

View File

@ -22,6 +22,7 @@
#include "EngineSelectorFeature.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "MMFiles/MMFilesEngine.h"

View File

@ -31,6 +31,7 @@
#include "ApplicationFeatures/VersionFeature.h"
#include "Basics/ArangoGlobalContext.h"
#include "Benchmark/BenchFeature.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "Random/RandomFeature.h"

View File

@ -30,6 +30,7 @@
#include "ApplicationFeatures/VersionFeature.h"
#include "Basics/ArangoGlobalContext.h"
#include "Dump/DumpFeature.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "Random/RandomFeature.h"

View File

@ -31,6 +31,7 @@
#include "ApplicationFeatures/VersionFeature.h"
#include "Basics/ArangoGlobalContext.h"
#include "Import/ImportFeature.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "Random/RandomFeature.h"

View File

@ -32,6 +32,7 @@
#include "ApplicationFeatures/V8PlatformFeature.h"
#include "ApplicationFeatures/VersionFeature.h"
#include "Basics/ArangoGlobalContext.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "Random/RandomFeature.h"
@ -45,48 +46,57 @@ using namespace arangodb;
using namespace arangodb::application_features;
int main(int argc, char* argv[]) {
ArangoGlobalContext context(argc, argv, BIN_DIRECTORY);
context.installHup();
std::string name = context.binaryName();
std::shared_ptr<options::ProgramOptions> options(new options::ProgramOptions(
argv[0], "Usage: " + name + " [<options>]", "For more information use:", BIN_DIRECTORY));
ApplicationServer server(options, BIN_DIRECTORY);
int ret = EXIT_SUCCESS;
server.addFeature(new ClientFeature(&server));
server.addFeature(new ConfigFeature(&server, name));
server.addFeature(new ConsoleFeature(&server));
server.addFeature(new GreetingsFeature(&server, "arangosh"));
server.addFeature(new LanguageFeature(&server));
server.addFeature(new LoggerFeature(&server, false));
server.addFeature(new RandomFeature(&server));
server.addFeature(new ShellFeature(&server, &ret));
server.addFeature(new ShutdownFeature(&server, {"Shell"}));
server.addFeature(new SslFeature(&server));
server.addFeature(new TempFeature(&server, name));
server.addFeature(new V8PlatformFeature(&server));
server.addFeature(new V8ShellFeature(&server, name));
server.addFeature(new VersionFeature(&server));
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
ArangoGlobalContext context(argc, argv, BIN_DIRECTORY);
context.installHup();
std::string name = context.binaryName();
std::shared_ptr<options::ProgramOptions> options(new options::ProgramOptions(
argv[0], "Usage: " + name + " [<options>]", "For more information use:", BIN_DIRECTORY));
ApplicationServer server(options, BIN_DIRECTORY);
int ret = EXIT_SUCCESS;
try {
server.addFeature(new ClientFeature(&server));
server.addFeature(new ConfigFeature(&server, name));
server.addFeature(new ConsoleFeature(&server));
server.addFeature(new GreetingsFeature(&server, "arangosh"));
server.addFeature(new LanguageFeature(&server));
server.addFeature(new LoggerFeature(&server, false));
server.addFeature(new RandomFeature(&server));
server.addFeature(new ShellFeature(&server, &ret));
server.addFeature(new ShutdownFeature(&server, {"Shell"}));
server.addFeature(new SslFeature(&server));
server.addFeature(new TempFeature(&server, name));
server.addFeature(new V8PlatformFeature(&server));
server.addFeature(new V8ShellFeature(&server, name));
server.addFeature(new VersionFeature(&server));
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangosh terminated because of an unhandled exception: "
<< ex.what();
ret = EXIT_FAILURE;
} catch (...) {
LOG(ERR) << "arangosh terminated because of an unhandled exception of "
"unknown type";
ret = EXIT_FAILURE;
}
return context.exit(ret);
} catch (std::exception const& ex) {
LOG(ERR) << "arangosh terminated because of an unhandled exception: "
<< ex.what();
ret = EXIT_FAILURE;
} catch (...) {
LOG(ERR) << "arangosh terminated because of an unhandled exception of "
"unknown type";
ret = EXIT_FAILURE;
}
return context.exit(ret);
exit(EXIT_FAILURE);
}

View File

@ -27,7 +27,6 @@
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/Exceptions.h"
#include "Logger/Logger.h"
namespace arangodb {
namespace application_features {
@ -46,7 +45,7 @@ class ApplicationFeature {
public:
// return the feature's name
std::string name() const { return _name; }
std::string const& name() const { return _name; }
bool isOptional() const { return _optional; }
bool isRequired() const { return !_optional; }

View File

@ -495,7 +495,7 @@ void ApplicationServer::prepare() {
feature->prepare();
feature->state(FeatureState::PREPARED);
} catch (std::exception const& ex) {
LOG(ERR) << "caught exception during prepare of feature '"
LOG_TOPIC(ERR, Logger::STARTUP) << "caught exception during prepare of feature '"
<< feature->name() << "': " << ex.what();
// restore original privileges
if (!privilegesElevated) {
@ -503,7 +503,7 @@ void ApplicationServer::prepare() {
}
throw;
} catch (...) {
LOG(ERR) << "caught unknown exception during preparation of feature '"
LOG_TOPIC(ERR, Logger::STARTUP) << "caught unknown exception during preparation of feature '"
<< feature->name() << "'";
// restore original privileges
if (!privilegesElevated) {
@ -520,7 +520,7 @@ void ApplicationServer::prepare() {
void ApplicationServer::start() {
LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::start";
bool abortStartup = false;
int res = TRI_ERROR_NO_ERROR;
for (auto feature : _orderedFeatures) {
if (!feature->isEnabled()) {
@ -533,18 +533,26 @@ void ApplicationServer::start() {
feature->start();
feature->state(FeatureState::STARTED);
reportFeatureProgress(_state, feature->name());
} catch (std::exception const& ex) {
LOG(ERR) << "caught exception during start of feature '" << feature->name()
} catch (basics::Exception const& ex) {
LOG_TOPIC(ERR, Logger::STARTUP) << "caught exception during start of feature '" << feature->name()
<< "': " << ex.what() << ". shutting down";
abortStartup = true;
res = ex.code();
} catch (std::bad_alloc const& ex) {
LOG_TOPIC(ERR, Logger::STARTUP) << "caught exception during start of feature '" << feature->name()
<< "': " << ex.what() << ". shutting down";
res = TRI_ERROR_OUT_OF_MEMORY;
} catch (std::exception const& ex) {
LOG_TOPIC(ERR, Logger::STARTUP) << "caught exception during start of feature '" << feature->name()
<< "': " << ex.what() << ". shutting down";
res = TRI_ERROR_INTERNAL;
} catch (...) {
LOG(ERR) << "caught unknown exception during start of feature '"
LOG_TOPIC(ERR, Logger::STARTUP) << "caught unknown exception during start of feature '"
<< feature->name() << "'. shutting down";
abortStartup = true;
res = TRI_ERROR_INTERNAL;
}
if (abortStartup) {
if (res != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(TRACE, Logger::STARTUP) << "aborting startup, now stopping and unpreparing all features";
// try to stop all feature that we just started
for (auto it = _orderedFeatures.rbegin(); it != _orderedFeatures.rend();
++it) {
@ -553,31 +561,35 @@ void ApplicationServer::start() {
continue;
}
if (feature->state() == FeatureState::STARTED) {
LOG(TRACE) << "forcefully stopping feature '" << feature->name() << "'";
LOG_TOPIC(TRACE, Logger::STARTUP) << "forcefully stopping feature '" << feature->name() << "'";
try {
feature->stop();
feature->state(FeatureState::STOPPED);
} catch (...) {
// ignore errors on shutdown
LOG_TOPIC(TRACE, Logger::STARTUP) << "caught exception while stopping feature '" << feature->name() << "'";
}
}
}
// try to unprepare all feature that we just started
for (auto it = _orderedFeatures.rbegin(); it != _orderedFeatures.rend();
++it) {
auto feature = *it;
if (feature->state() == FeatureState::STOPPED) {
LOG(TRACE) << "forcefully unpreparing feature '" << feature->name() << "'";
LOG_TOPIC(TRACE, Logger::STARTUP) << "forcefully unpreparing feature '" << feature->name() << "'";
try {
feature->unprepare();
feature->state(FeatureState::UNPREPARED);
} catch (...) {
// ignore errors on shutdown
LOG_TOPIC(TRACE, Logger::STARTUP) << "caught exception while unpreparing feature '" << feature->name() << "'";
}
}
}
// throw exception so the startup aborts
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "startup aborted");
THROW_ARANGO_EXCEPTION_MESSAGE(res, std::string("startup aborted: ") + TRI_errno_string(res));
}
}
}

View File

@ -21,6 +21,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "GreetingsFeature.h"
#include "Logger/Logger.h"
#include "Rest/Version.h"
using namespace arangodb;

View File

@ -21,6 +21,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "PageSizeFeature.h"
#include "Logger/Logger.h"
using namespace arangodb;
using namespace arangodb::basics;

View File

@ -31,6 +31,7 @@
#endif
#include "Basics/conversions.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

View File

@ -24,6 +24,7 @@
#include "ApplicationFeatures/DaemonFeature.h"
#include "Basics/ArangoGlobalContext.h"
#include "Logger/Logger.h"
#include "Logger/LoggerFeature.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"

View File

@ -24,6 +24,7 @@
#define ARANGODB_APPLICATION_FEATURES_SUPERVISOR_FEATURE_H 1
#include "ApplicationFeatures/ApplicationFeature.h"
#include "Basics/threads.h"
namespace arangodb {
class SupervisorFeature final