1
0
Fork 0

turn off all MMFiles features in case RocksDB engine is selected

This commit is contained in:
jsteemann 2017-03-27 14:22:00 +02:00
parent cdf1c1d894
commit 922a8af392
6 changed files with 63 additions and 48 deletions

View File

@ -109,15 +109,14 @@ MMFilesLogfileManager::MMFilesLogfileManager(ApplicationServer* server)
LOG_TOPIC(TRACE, arangodb::Logger::FIXME) << "creating WAL logfile manager";
TRI_ASSERT(!_allowWrites);
setOptional(false);
setOptional(true);
requiresElevatedPrivileges(false);
startsAfter("DatabasePath");
startsAfter("EngineSelector");
startsAfter("FeatureCache");
for (auto const& it : EngineSelectorFeature::availableEngines()) {
startsAfter(it.second);
}
startsAfter("MMFilesEngine");
onlyEnabledWith("MMFilesEngine");
}
// destroy the logfile manager

View File

@ -65,8 +65,9 @@ MMFilesPersistentIndexFeature::MMFilesPersistentIndexFeature(
_keepLogFileNum(1000), _logFileTimeToRoll(0), _compactionReadaheadSize(0) {
setOptional(true);
requiresElevatedPrivileges(false);
// startsAfter("MMFilesLogfileManager");
startsAfter("DatabasePath");
onlyEnabledWith("MMFilesEngine");
}
MMFilesPersistentIndexFeature::~MMFilesPersistentIndexFeature() {

View File

@ -37,11 +37,14 @@ using namespace arangodb::options;
MMFilesWalRecoveryFeature::MMFilesWalRecoveryFeature(ApplicationServer* server)
: ApplicationFeature(server, "MMFilesWalRecovery") {
setOptional(false);
setOptional(true);
requiresElevatedPrivileges(false);
startsAfter("Database");
startsAfter("MMFilesLogfileManager");
startsAfter("MMFilesPersistentIndex");
onlyEnabledWith("MMFilesEngine");
onlyEnabledWith("MMFilesLogfileManager");
}
/// @brief run the recovery procedure

View File

@ -68,7 +68,7 @@ class ApplicationFeature {
// enable or disable a feature
void setEnabled(bool value) {
if (!value && !isOptional() && _enableWith.empty()) {
if (!value && !isOptional()) {
THROW_ARANGO_EXCEPTION_MESSAGE(
TRI_ERROR_BAD_PARAMETER,
"cannot disable non-optional feature '" + name() + "'");
@ -76,9 +76,6 @@ class ApplicationFeature {
_enabled = value;
}
// return whether a feature is automatically enabled with another feature
std::string enableWith() const { return _enableWith; }
// names of features required to be enabled for this feature to be enabled
std::vector<std::string> const& requires() const { return _requires; }
@ -141,12 +138,6 @@ class ApplicationFeature {
// make the feature optional (or not)
void setOptional(bool value) { _optional = value; }
// enable this feature automatically when another is enabled
void enableWith(std::string const& other) {
_enableWith = other;
_requires.emplace_back(other);
}
// note that this feature requires another to be present
void requires(std::string const& other) { _requires.emplace_back(other); }
@ -161,6 +152,13 @@ class ApplicationFeature {
// determine all direct and indirect ancestors of a feature
std::unordered_set<std::string> ancestors() const;
void onlyEnabledWith(std::string const& other) { _onlyEnabledWith.emplace(other); }
// return the list of other features that this feature depends on
std::unordered_set<std::string> const& onlyEnabledWith() const {
return _onlyEnabledWith;
}
private:
// set a feature's state. this method should be called by the
// application server only
@ -182,14 +180,14 @@ class ApplicationFeature {
// is enabled
std::vector<std::string> _requires;
// name of other feature that will enable or disable this feature
std::string _enableWith;
// a list of start dependencies for the feature
std::unordered_set<std::string> _startsAfter;
// list of direct and indirect ancestors of the feature
std::unordered_set<std::string> _ancestors;
// enable this feature only if the following other features are enabled
std::unordered_set<std::string> _onlyEnabledWith;
// state of feature
ApplicationServer::FeatureState _state;

View File

@ -181,12 +181,13 @@ void ApplicationServer::run(int argc, char* argv[]) {
reportServerProgress(_state);
validateOptions();
// enable automatic features
enableAutomaticFeatures();
// setup and validate all feature dependencies
setupDependencies(true);
// turn off all features that depend on other features that have been
// turned off
disableDependentFeatures();
// allows process control
daemonize();
@ -198,6 +199,11 @@ void ApplicationServer::run(int argc, char* argv[]) {
_state = ServerState::IN_PREPARE;
reportServerProgress(_state);
prepare();
// turn off all features that depend on other features that have been
// turned off. we repeat this to allow features to turn other features
// off even in the prepare phase
disableDependentFeatures();
// permanently drop the privileges
dropPrivilegesPermanently();
@ -346,28 +352,6 @@ void ApplicationServer::validateOptions() {
}
}
void ApplicationServer::enableAutomaticFeatures() {
bool changed;
do {
changed = false;
for (auto& it : _features) {
auto other = it.second->enableWith();
if (other.empty()) {
continue;
}
if (!this->exists(other)) {
fail("feature '" + it.second->name() +
"' depends on unknown feature '" + other + "'");
}
bool otherIsEnabled = this->feature(other)->isEnabled();
if (otherIsEnabled != it.second->isEnabled()) {
it.second->setEnabled(otherIsEnabled);
changed = true;
}
}
} while (changed);
}
// setup and validate all feature dependencies, determine feature order
void ApplicationServer::setupDependencies(bool failOnMissing) {
LOG_TOPIC(TRACE, Logger::STARTUP)
@ -469,6 +453,35 @@ void ApplicationServer::daemonize() {
}
}
void ApplicationServer::disableDependentFeatures() {
LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::disableDependentFeatures";
for (auto feature : _orderedFeatures) {
auto const& onlyEnabledWith = feature->onlyEnabledWith();
if (!feature->isEnabled() || onlyEnabledWith.empty()) {
continue;
}
for (auto const& other : onlyEnabledWith) {
ApplicationFeature* f = lookupFeature(other);
if (f == nullptr) {
LOG_TOPIC(TRACE, Logger::STARTUP) << "turning off feature '" << feature->name()
<< "' because it is enabled only in conjunction with non-existing feature '"
<< f->name() << "'";
feature->disable();
break;
} else if (!f->isEnabled()) {
LOG_TOPIC(TRACE, Logger::STARTUP) << "turning off feature '" << feature->name()
<< "' because it is enabled only in conjunction with disabled feature '"
<< f->name() << "'";
feature->disable();
break;
}
}
}
}
void ApplicationServer::prepare() {
LOG_TOPIC(TRACE, Logger::STARTUP) << "ApplicationServer::prepare";

View File

@ -247,15 +247,16 @@ class ApplicationServer {
// allows features to cross-validate their program options
void validateOptions();
// enable automatic features
void enableAutomaticFeatures();
// setup and validate all feature dependencies, determine feature order
void setupDependencies(bool failOnMissing);
// allows process control
void daemonize();
// disables all features that depend on other features, which, themselves
// are disabled
void disableDependentFeatures();
// allows features to prepare themselves
void prepare();