From 340e3c79b09f60a50b7fcb86f582e497f25dde1c Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 15 Apr 2019 12:40:09 +0200 Subject: [PATCH] try to force cleanup on shutdown (#8754) --- arangod/RestServer/DatabaseFeature.cpp | 2 ++ arangod/VocBase/vocbase.cpp | 35 ++++++++++++++++---------- arangod/VocBase/vocbase.h | 4 +++ js/server/arango-dfdb.js | 22 ++++++++-------- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/arangod/RestServer/DatabaseFeature.cpp b/arangod/RestServer/DatabaseFeature.cpp index 8a142dd8ea..f301ea9a9f 100644 --- a/arangod/RestServer/DatabaseFeature.cpp +++ b/arangod/RestServer/DatabaseFeature.cpp @@ -446,6 +446,8 @@ void DatabaseFeature::stop() { << ", keys: " << currentKeysCount << ", queries: " << currentQueriesCount; #endif + vocbase->stop(); + vocbase->processCollections( [](LogicalCollection* collection) { // no one else must modify the collection's status while we are in diff --git a/arangod/VocBase/vocbase.cpp b/arangod/VocBase/vocbase.cpp index 8d7f1fbcc2..bcc74ee0e7 100644 --- a/arangod/VocBase/vocbase.cpp +++ b/arangod/VocBase/vocbase.cpp @@ -698,7 +698,6 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection, unregisterCollection(collection); locker.unlock(); - writeLocker.unlock(); TRI_ASSERT(engine != nullptr); @@ -744,19 +743,29 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection, return TRI_ERROR_NO_ERROR; } +/// @brief stop operations in this vocbase. must be called prior to +/// shutdown to clean things up +void TRI_vocbase_t::stop() { + try { + // stop replication + if (_replicationApplier != nullptr) { + _replicationApplier->stopAndJoin(); + } + + // mark all cursors as deleted so underlying collections can be freed soon + _cursorRepository->garbageCollect(true); + + // mark all collection keys as deleted so underlying collections can be freed + // soon + _collectionKeys->garbageCollect(true); + } catch (...) { + // we are calling this on shutdown, and always want to go on from here + } +} + /// @brief closes a database and all collections void TRI_vocbase_t::shutdown() { - // stop replication - if (_replicationApplier != nullptr) { - _replicationApplier->stopAndJoin(); - } - - // mark all cursors as deleted so underlying collections can be freed soon - _cursorRepository->garbageCollect(true); - - // mark all collection keys as deleted so underlying collections can be freed - // soon - _collectionKeys->garbageCollect(true); + this->stop(); std::vector> collections; @@ -1528,7 +1537,7 @@ std::shared_ptr TRI_vocbase_t::createView(arangodb::veloc if (!res.ok()) { unregisterView(*view); - THROW_ARANGO_EXCEPTION_MESSAGE(res.errorNumber(), res.errorMessage()); + THROW_ARANGO_EXCEPTION(res); } } catch (...) { unregisterView(*view); diff --git a/arangod/VocBase/vocbase.h b/arangod/VocBase/vocbase.h index 15ca79315f..f9d4e5879c 100644 --- a/arangod/VocBase/vocbase.h +++ b/arangod/VocBase/vocbase.h @@ -241,6 +241,10 @@ struct TRI_vocbase_t { /// @brief returns whether the database is the system database bool isSystem() const { return name() == TRI_VOC_SYSTEM_DATABASE; } + /// @brief stop operations in this vocbase. must be called prior to + /// shutdown to clean things up + void stop(); + /// @brief closes a database and all collections void shutdown(); diff --git a/js/server/arango-dfdb.js b/js/server/arango-dfdb.js index 4e42e66801..76df098403 100644 --- a/js/server/arango-dfdb.js +++ b/js/server/arango-dfdb.js @@ -47,7 +47,7 @@ function UnloadCollection (collection) { if (++tries >= 20) { break; } - if (tries == 1) { + if (tries === 1) { printf("Trying to unload collection '%s', current status: %s\n", collection.name(), collection.status()); } @@ -465,7 +465,7 @@ function CheckCollection (collection, issues, details) { printf(" identifier: %s\n", collection._id); printf("\n"); - var datafiles = collection.datafiles(); + let datafiles = collection.datafiles(); printf("Datafiles\n"); printf(" # of journals: %d\n", datafiles.journals.length); @@ -473,15 +473,15 @@ function CheckCollection (collection, issues, details) { printf(" # of datafiles: %d\n", datafiles.datafiles.length); printf("\n"); - for (var i = 0; i < datafiles.journals.length; ++i) { + for (let i = 0; i < datafiles.journals.length; ++i) { CheckDatafile(collection, "journal", datafiles.journals[i], issues, details); } - for (var i = 0; i < datafiles.datafiles.length; ++i) { + for (let i = 0; i < datafiles.datafiles.length; ++i) { CheckDatafile(collection, "datafile", datafiles.datafiles[i], issues, details); } - for (var i = 0; i < datafiles.compactors.length; ++i) { + for (let i = 0; i < datafiles.compactors.length; ++i) { CheckDatafile(collection, "compactor", datafiles.compactors[i], issues, details); } } @@ -524,7 +524,7 @@ function main (argv) { return s; }; - if (databases.length == 0) { + if (databases.length === 0) { printf("No databases available. Exiting\n"); return; } @@ -542,12 +542,12 @@ function main (argv) { while (true) { line = console.getline(); - if (line == "") { + if (line === "") { printf("Exiting. Please wait.\n"); return; } else { - var l = parseInt(line); + let l = parseInt(line); if (l < 0 || l >= databases.length || l === null || l === undefined || isNaN(l)) { printf("Please select a number between 0 and %d: ", databases.length - 1); @@ -563,7 +563,7 @@ function main (argv) { var collections = internal.db._collections(); - if (collections.length == 0) { + if (collections.length === 0) { printf("No collections available. Exiting\n"); return; } @@ -587,7 +587,7 @@ function main (argv) { while (true) { line = console.getline(); - if (line == "") { + if (line === "") { printf("Exiting. Please wait.\n"); return; } @@ -600,7 +600,7 @@ function main (argv) { break; } else { - var l = parseInt(line); + let l = parseInt(line); if (l < 0 || l >= collections.length || l === null || l === undefined || isNaN(l)) { printf("Please select a number between 0 and %d: ", collections.length - 1);