1
0
Fork 0

try to fix some undefined behavior on cluster startup

This commit is contained in:
Jan Steemann 2016-04-25 15:31:23 +02:00
parent 5ea01c02b0
commit c8c8625727
14 changed files with 64 additions and 51 deletions

View File

@ -50,6 +50,7 @@ AgencyFeature::AgencyFeature(application_features::ApplicationServer* server)
startsAfter("Database");
startsAfter("Dispatcher");
startsAfter("Endpoint");
startsAfter("QueryRegistry");
startsAfter("Scheduler");
startsAfter("Server");
}

View File

@ -25,6 +25,7 @@
#include "Basics/ConditionLocker.h"
#include "RestServer/DatabaseFeature.h"
#include "RestServer/QueryRegistryFeature.h"
#include "VocBase/server.h"
#include "VocBase/vocbase.h"
@ -279,13 +280,12 @@ append_entries_t Agent::sendAppendEntriesRPC (id_t follower_id) {
0, true);
return append_entries_t(t, true);
}
// @brief load persistent state
bool Agent::load () {
DatabaseFeature* database = dynamic_cast<DatabaseFeature*>(
ApplicationServer::lookupFeature("Database"));
bool Agent::load() {
DatabaseFeature* database =
ApplicationServer::getFeature<DatabaseFeature>("Database");
auto vocbase = database->vocbase();
@ -310,7 +310,9 @@ bool Agent::load () {
_readDB.start(this);
LOG_TOPIC(INFO, Logger::AGENCY) << "Starting constituent personality.";
_constituent.start(vocbase);
auto queryRegistry = QueryRegistryFeature::QUERY_REGISTRY;
TRI_ASSERT(queryRegistry != nullptr);
_constituent.start(vocbase, queryRegistry);
if (_config.supervision) {
LOG_TOPIC(INFO, Logger::AGENCY) << "Starting cluster sanity facilities";

View File

@ -370,8 +370,10 @@ void Constituent::beginShutdown() {
Thread::beginShutdown();
}
bool Constituent::start (TRI_vocbase_t* vocbase) {
bool Constituent::start(TRI_vocbase_t* vocbase,
aql::QueryRegistry* queryRegistry) {
_vocbase = vocbase;
_queryRegistry = queryRegistry;
return Thread::start();
}

View File

@ -96,9 +96,9 @@ public:
size_t size() const;
/// @brief Orderly shutdown of thread
void beginShutdown () override;
void beginShutdown() override;
bool start (TRI_vocbase_t* vocbase);
bool start(TRI_vocbase_t* vocbase, aql::QueryRegistry*);
private:

View File

@ -821,6 +821,8 @@ ExecutionEngine* ExecutionEngine::instantiateFromPlan(
bool const isCoordinator =
arangodb::ServerState::instance()->isCoordinator(role);
bool const isDBServer = arangodb::ServerState::instance()->isDBServer(role);
TRI_ASSERT(queryRegistry != nullptr);
ExecutionEngine* engine = nullptr;
@ -836,7 +838,6 @@ ExecutionEngine* ExecutionEngine::instantiateFromPlan(
if (isCoordinator) {
// instantiate the engine on the coordinator
auto inst =
std::make_unique<CoordinatorInstanciator>(query, queryRegistry);
plan->root()->walk(inst.get());

View File

@ -391,6 +391,8 @@ void Query::registerWarning(int code, char const* details) {
/// to be able to only prepare a query from VelocyPack and then store it in the
/// QueryRegistry.
QueryResult Query::prepare(QueryRegistry* registry) {
TRI_ASSERT(registry != nullptr);
try {
init();
enterState(PARSING);
@ -513,6 +515,8 @@ QueryResult Query::prepare(QueryRegistry* registry) {
/// @brief execute an AQL query
QueryResult Query::execute(QueryRegistry* registry) {
TRI_ASSERT(registry != nullptr);
std::unique_ptr<AqlWorkStack> work;
try {

View File

@ -62,6 +62,7 @@ ClusterFeature::ClusterFeature(application_features::ApplicationServer* server)
startsAfter("Dispatcher");
startsAfter("Scheduler");
startsAfter("V8Dealer");
startsAfter("Database");
}
ClusterFeature::~ClusterFeature() {

View File

@ -68,18 +68,15 @@ void CheckVersionFeature::validateOptions(
ApplicationServer::forceDisableFeatures(_nonServerFeatures);
LoggerFeature* logger =
dynamic_cast<LoggerFeature*>(ApplicationServer::lookupFeature("Logger"));
LoggerFeature* logger = ApplicationServer::getFeature<LoggerFeature>("Logger");
logger->disableThreaded();
DatabaseFeature* database = dynamic_cast<DatabaseFeature*>(
ApplicationServer::lookupFeature("Database"));
DatabaseFeature* database = ApplicationServer::getFeature<DatabaseFeature>("Database");
database->disableReplicationApplier();
database->disableCompactor();
database->enableCheckVersion();
V8DealerFeature* v8dealer = dynamic_cast<V8DealerFeature*>(
ApplicationServer::lookupFeature("V8Dealer"));
V8DealerFeature* v8dealer = ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
v8dealer->setNumberContexts(1);
}

View File

@ -182,23 +182,25 @@ void DatabaseFeature::updateContexts() {
}
auto queryRegistry = QueryRegistryFeature::QUERY_REGISTRY;
TRI_ASSERT(queryRegistry != nullptr);
auto server = DatabaseServerFeature::SERVER;
TRI_ASSERT(server != nullptr);
auto vocbase = _vocbase;
V8DealerFeature* dealer = dynamic_cast<V8DealerFeature*>(
ApplicationServer::lookupFeature("V8Dealer"));
if (dealer != nullptr) {
dealer->defineContextUpdate(
[queryRegistry, server, vocbase](
v8::Isolate* isolate, v8::Handle<v8::Context> context, size_t i) {
TRI_InitV8VocBridge(isolate, context, queryRegistry, server, vocbase,
i);
TRI_InitV8Queries(isolate, context);
TRI_InitV8Cluster(isolate, context);
},
vocbase);
}
V8DealerFeature* dealer =
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
dealer->defineContextUpdate(
[queryRegistry, server, vocbase](
v8::Isolate* isolate, v8::Handle<v8::Context> context, size_t i) {
TRI_InitV8VocBridge(isolate, context, queryRegistry, server, vocbase,
i);
TRI_InitV8Queries(isolate, context);
TRI_InitV8Cluster(isolate, context);
},
vocbase);
}
void DatabaseFeature::shutdownCompactor() {

View File

@ -71,15 +71,18 @@ void QueryRegistryFeature::prepare() {
std::pair<std::string, size_t> cacheProperties{_queryCacheMode,
_queryCacheEntries};
arangodb::aql::QueryCache::instance()->setProperties(cacheProperties);
// create the query registery
_queryRegistry.reset(new aql::QueryRegistry());
QUERY_REGISTRY = _queryRegistry.get();
}
void QueryRegistryFeature::start() {
// create the query registery
_queryRegistry.reset(new aql::QueryRegistry());
DatabaseServerFeature::SERVER->_queryRegistry = _queryRegistry.get();
}
void QueryRegistryFeature::stop() {
// clear the query registery
DatabaseServerFeature::SERVER->_queryRegistry = nullptr;
// TODO: reset QUERY_REGISTRY as well?
}

View File

@ -130,17 +130,17 @@ void ServerFeature::validateOptions(std::shared_ptr<ProgramOptions>) {
"RestServer", "Scheduler", "Ssl",
"Supervisor"});
DatabaseFeature* database = dynamic_cast<DatabaseFeature*>(
ApplicationServer::lookupFeature("Database"));
DatabaseFeature* database =
ApplicationServer::getFeature<DatabaseFeature>("Database");
database->disableReplicationApplier();
StatisticsFeature* statistics = dynamic_cast<StatisticsFeature*>(
ApplicationServer::lookupFeature("Statistics"));
StatisticsFeature* statistics =
ApplicationServer::getFeature<StatisticsFeature>("Statistics");
statistics->disableStatistics();
}
V8DealerFeature* v8dealer = dynamic_cast<V8DealerFeature*>(
ApplicationServer::lookupFeature("V8Dealer"));
V8DealerFeature* v8dealer =
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
if (_operationMode == OperationMode::MODE_SCRIPT ||
_operationMode == OperationMode::MODE_UNITTESTS) {
@ -162,8 +162,8 @@ void ServerFeature::validateOptions(std::shared_ptr<ProgramOptions>) {
void ServerFeature::start() {
if (_operationMode != OperationMode::MODE_CONSOLE && _restServer) {
auto scheduler = dynamic_cast<SchedulerFeature*>(
ApplicationServer::lookupFeature("Scheduler"));
auto scheduler =
ApplicationServer::getFeature<SchedulerFeature>("Scheduler");
if (scheduler != nullptr) {
scheduler->buildControlCHandler();
@ -236,8 +236,8 @@ std::string ServerFeature::operationModeString(OperationMode mode) {
}
int ServerFeature::runUnitTests() {
DatabaseFeature* database = dynamic_cast<DatabaseFeature*>(
ApplicationServer::lookupFeature("Database"));
DatabaseFeature* database =
ApplicationServer::getFeature<DatabaseFeature>("Database");
V8Context* context =
V8DealerFeature::DEALER->enterContext(database->vocbase(), true);
@ -295,8 +295,8 @@ int ServerFeature::runUnitTests() {
int ServerFeature::runScript() {
bool ok = false;
DatabaseFeature* database = dynamic_cast<DatabaseFeature*>(
ApplicationServer::lookupFeature("Database"));
DatabaseFeature* database =
ApplicationServer::getFeature<DatabaseFeature>("Database");
V8Context* context =
V8DealerFeature::DEALER->enterContext(database->vocbase(), true);

View File

@ -101,6 +101,7 @@ V8DealerFeature::V8DealerFeature(
startsAfter("Action");
startsAfter("Database");
startsAfter("Dispatcher");
startsAfter("QueryRegistry");
startsAfter("Scheduler");
startsAfter("V8Platform");
startsAfter("WorkMonitor");
@ -178,8 +179,8 @@ void V8DealerFeature::start() {
// try to guess a suitable number of contexts
if (0 == _nrContexts && 0 == _forceNrContexts) {
DispatcherFeature* dispatcher = dynamic_cast<DispatcherFeature*>(
ApplicationServer::lookupFeature("Dispatcher"));
DispatcherFeature* dispatcher =
ApplicationServer::getFeature<DispatcherFeature>("Dispatcher");
if (dispatcher != nullptr) {
_nrContexts = dispatcher->concurrency();
@ -215,8 +216,8 @@ void V8DealerFeature::start() {
applyContextUpdates();
DatabaseFeature* database = dynamic_cast<DatabaseFeature*>(
ApplicationServer::lookupFeature("Database"));
DatabaseFeature* database =
ApplicationServer::getFeature<DatabaseFeature>("Database");
loadJavascript(database->vocbase(), "server/initialize.js");

View File

@ -3447,6 +3447,7 @@ void TRI_InitV8VocBridge(v8::Isolate* isolate, v8::Handle<v8::Context> context,
static_cast<V8TransactionContext*>(v8g->_transactionContext)->makeGlobal();
// register the query registry
TRI_ASSERT(queryRegistry != nullptr);
v8g->_queryRegistry = queryRegistry;
// register the server

View File

@ -1071,8 +1071,7 @@ static void DatabaseManager(void* data) {
usleep(DATABASE_MANAGER_INTERVAL);
// The following is only necessary after a wait:
auto queryRegistry =
static_cast<arangodb::aql::QueryRegistry*>(server->_queryRegistry);
auto queryRegistry = server->_queryRegistry.load();
if (queryRegistry != nullptr) {
queryRegistry->expireQueries();
@ -1092,8 +1091,7 @@ static void DatabaseManager(void* data) {
for (auto& p : theLists->_coordinatorDatabases) {
TRI_vocbase_t* vocbase = p.second;
TRI_ASSERT(vocbase != nullptr);
auto cursorRepository = static_cast<arangodb::CursorRepository*>(
vocbase->_cursorRepository);
auto cursorRepository = vocbase->_cursorRepository;
try {
cursorRepository->garbageCollect(false);