database: Simplify database reset logic and locking (#3298)

This commit is contained in:
Teddy Reed 2017-05-20 00:00:27 -07:00 committed by GitHub
parent 017fc1d33c
commit 8f07e1df23

View File

@ -494,7 +494,17 @@ Status DatabasePlugin::call(const PluginRequest& request,
if (request.at("action") == "reset") {
WriteLock lock(kDatabaseReset);
return this->reset();
DatabasePlugin::kDBInitialized = false;
// Prevent RocksDB reentrancy by logger plugins during plugin setup.
VLOG(1) << "Resetting the database plugin: " << getName();
auto status = this->reset();
if (!status.ok()) {
// The active database could not be reset, fallback to an ephemeral.
Registry::get().setActive("database", "ephemeral");
LOG(WARNING) << "Unable to reset database plugin: " << getName();
}
DatabasePlugin::kDBInitialized = true;
return status;
}
// Switch over the possible database plugin actions.
@ -552,7 +562,6 @@ Status getDatabaseValue(const std::string& domain,
return Status(1, "Missing domain");
}
ReadLock lock(kDatabaseReset);
if (RegistryFactory::get().external()) {
// External registries (extensions) do not have databases active.
// It is not possible to use an extension-based database.
@ -568,8 +577,9 @@ Status getDatabaseValue(const std::string& domain,
}
return status;
} else if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot get database values");
throw std::runtime_error("Cannot get database value: " + key);
} else {
ReadLock lock(kDatabaseReset);
auto plugin = getDatabasePlugin();
return plugin->get(domain, key, value);
}
@ -582,7 +592,6 @@ Status setDatabaseValue(const std::string& domain,
return Status(1, "Missing domain");
}
ReadLock lock(kDatabaseReset);
if (RegistryFactory::get().external()) {
// External registries (extensions) do not have databases active.
// It is not possible to use an extension-based database.
@ -590,8 +599,9 @@ Status setDatabaseValue(const std::string& domain,
{"action", "put"}, {"domain", domain}, {"key", key}, {"value", value}};
return Registry::call("database", request);
} else if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot get database values");
throw std::runtime_error("Cannot set database value: " + key);
} else {
ReadLock lock(kDatabaseReset);
auto plugin = getDatabasePlugin();
return plugin->put(domain, key, value);
}
@ -602,7 +612,6 @@ Status deleteDatabaseValue(const std::string& domain, const std::string& key) {
return Status(1, "Missing domain");
}
ReadLock lock(kDatabaseReset);
if (RegistryFactory::get().external()) {
// External registries (extensions) do not have databases active.
// It is not possible to use an extension-based database.
@ -610,8 +619,9 @@ Status deleteDatabaseValue(const std::string& domain, const std::string& key) {
{"action", "remove"}, {"domain", domain}, {"key", key}};
return Registry::call("database", request);
} else if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot get database values");
throw std::runtime_error("Cannot delete database value: " + key);
} else {
ReadLock lock(kDatabaseReset);
auto plugin = getDatabasePlugin();
return plugin->remove(domain, key);
}
@ -624,7 +634,6 @@ Status deleteDatabaseRange(const std::string& domain,
return Status(1, "Missing domain");
}
ReadLock lock(kDatabaseReset);
if (RegistryFactory::get().external()) {
// External registries (extensions) do not have databases active.
// It is not possible to use an extension-based database.
@ -634,8 +643,10 @@ Status deleteDatabaseRange(const std::string& domain,
{"key_high", high}};
return Registry::call("database", request);
} else if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot get database values");
throw std::runtime_error("Cannot delete database values: " + low + " - " +
high);
} else {
ReadLock lock(kDatabaseReset);
auto plugin = getDatabasePlugin();
return plugin->removeRange(domain, low, high);
}
@ -656,7 +667,6 @@ Status scanDatabaseKeys(const std::string& domain,
return Status(1, "Missing domain");
}
ReadLock lock(kDatabaseReset);
if (RegistryFactory::get().external()) {
// External registries (extensions) do not have databases active.
// It is not possible to use an extension-based database.
@ -674,29 +684,17 @@ Status scanDatabaseKeys(const std::string& domain,
}
return status;
} else if (!DatabasePlugin::kDBInitialized) {
throw std::runtime_error("Cannot get database values");
throw std::runtime_error("Cannot scan database values: " + prefix);
} else {
ReadLock lock(kDatabaseReset);
auto plugin = getDatabasePlugin();
return plugin->scan(domain, keys, prefix, max);
}
}
void resetDatabase() {
auto active = Registry::get().getActive("database");
Status status;
DatabasePlugin::kDBInitialized = false;
// Prevent RocksDB reentrancy by logger plugins during plugin setup.
VLOG(1) << "Resetting the database plugin: " << active;
PluginRequest request = {{"action", "reset"}};
status = Registry::call("database", request);
if (!status.ok()) {
// The active database could not be reset, fallback to an ephemeral.
Registry::get().setActive("database", "ephemeral");
LOG(WARNING) << "Unable to reset database plugin: " << active;
}
DatabasePlugin::kDBInitialized = true;
Registry::call("database", request);
}
void dumpDatabase() {