From e4cc3ac776104b5c54b29ed9d0b38ed90ca60042 Mon Sep 17 00:00:00 2001 From: Dan Larkin-York Date: Wed, 12 Jun 2019 14:02:01 -0400 Subject: [PATCH] [3.4] Add drop-check for index creation in cluster (#9220) * Add drop-check for index creation in cluster. * Fix return. * Add changelog entry. * Address review comments. * Revert change of shared_ptr to plain atomic. --- CHANGELOG | 2 ++ arangod/Cluster/ClusterInfo.cpp | 37 +++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f9f70a51d8..c34d8da48a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ v3.4.7 (2019-XX-XX) ------------------- +* fix timeout-response in case of simultaneous index create/drop in cluster + * Fixed editing a user within the web UI if the user added a gravatar profile picture * eventually remove archived RocksDB WAL files from the "archive" directory on agency servers diff --git a/arangod/Cluster/ClusterInfo.cpp b/arangod/Cluster/ClusterInfo.cpp index d2e52130ae..90b61f4c9b 100644 --- a/arangod/Cluster/ClusterInfo.cpp +++ b/arangod/Cluster/ClusterInfo.cpp @@ -2650,7 +2650,8 @@ int ClusterInfo::ensureIndexCoordinatorInner(std::string const& databaseName, } // will contain the error number and message - auto dbServerResult = std::make_shared>(-1); + std::shared_ptr> dbServerResult = + std::make_shared>(-1); std::shared_ptr errMsg = std::make_shared(); std::function dbServerChanged = [=](VPackSlice const& result) { @@ -2726,7 +2727,6 @@ int ClusterInfo::ensureIndexCoordinatorInner(std::string const& databaseName, // by a mutex. We use the mutex of the condition variable in the // AgencyCallback for this. std::string where = "Current/Collections/" + databaseName + "/" + collectionID; - auto agencyCallback = std::make_shared(ac, where, dbServerChanged, true, false); _agencyCallbackRegistry->registerCallback(agencyCallback); @@ -2775,6 +2775,39 @@ int ClusterInfo::ensureIndexCoordinatorInner(std::string const& databaseName, { while (!application_features::ApplicationServer::isStopping()) { int tmpRes = dbServerResult->load(std::memory_order_acquire); + + if (tmpRes < 0) { + // index has not shown up in Current yet, follow up check to + // ensure it is still in plan (not dropped between iterations) + + AgencyCommResult result = _agency.sendTransactionWithFailover( + AgencyReadTransaction(AgencyCommManager::path(planIndexesKey))); + + if (result.successful()) { + auto indexes = result.slice()[0].get( + std::vector{AgencyCommManager::path(), "Plan", + "Collections", databaseName, + collectionID, "indexes"}); + + bool found = false; + if (indexes.isArray()) { + for (auto const& v : VPackArrayIterator(indexes)) { + VPackSlice const k = v.get(StaticStrings::IndexId); + if (k.isString() && k.isEqualString(idString)) { + // index is still here + found = true; + break; + } + } + } + + if (!found) { + errorMsg = "index was dropped during creation"; + return TRI_ERROR_ARANGO_INDEX_CREATION_FAILED; + } + } + } + if (tmpRes == 0) { // Finally, in case all is good, remove the `isBuilding` flag // check that the index has appeared. Note that we have to have