From 33d0a4ff9bf7738c8134f65b1eb5c012cb0d7be0 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Tue, 4 Jun 2019 12:19:38 +0200 Subject: [PATCH] speedup collection creation --- CHANGELOG | 3 ++ arangod/Cluster/AgencyCallback.cpp | 4 +- arangod/Cluster/AgencyCallback.h | 5 ++- arangod/Cluster/ClusterInfo.cpp | 41 +++++++++---------- .../VocBase/Methods/CollectionCreationInfo.h | 4 +- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5827319d95..bc8acd8480 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ v3.4.6.1 (2019-06-03) --------------------- +* Speed up collection creation process in cluster, if not all agency callbacks are + delivered successfully. + * Fix agency's handling of object assignments with TTL v3.4.6 (2019-05-28) diff --git a/arangod/Cluster/AgencyCallback.cpp b/arangod/Cluster/AgencyCallback.cpp index b392299693..17ee157e00 100644 --- a/arangod/Cluster/AgencyCallback.cpp +++ b/arangod/Cluster/AgencyCallback.cpp @@ -127,7 +127,7 @@ bool AgencyCallback::execute(std::shared_ptr newData) { return result; } -void AgencyCallback::executeByCallbackOrTimeout(double maxTimeout) { +bool AgencyCallback::executeByCallbackOrTimeout(double maxTimeout) { // One needs to acquire the mutex of the condition variable // before entering this function! if (!_cv.wait(static_cast(maxTimeout * 1000000.0)) && @@ -136,5 +136,7 @@ void AgencyCallback::executeByCallbackOrTimeout(double maxTimeout) { << "Waiting done and nothing happended. Refetching to be sure"; // mop: watches have not triggered during our sleep...recheck to be sure refetchAndUpdate(false, true); // Force a check + return true; } + return false; } diff --git a/arangod/Cluster/AgencyCallback.h b/arangod/Cluster/AgencyCallback.h index 73b1dd57d1..f1cefcaa55 100644 --- a/arangod/Cluster/AgencyCallback.h +++ b/arangod/Cluster/AgencyCallback.h @@ -112,9 +112,12 @@ class AgencyCallback { ////////////////////////////////////////////////////////////////////////////// /// @brief wait until a callback is received or a timeout has happened + /// + /// @return true => if we got woken up after maxTimeout + /// false => if someone else ringed the condition variable ////////////////////////////////////////////////////////////////////////////// - void executeByCallbackOrTimeout(double); + bool executeByCallbackOrTimeout(double); ////////////////////////////////////////////////////////////////////////////// /// @brief private members diff --git a/arangod/Cluster/ClusterInfo.cpp b/arangod/Cluster/ClusterInfo.cpp index 408ccc4ede..506e205bf7 100644 --- a/arangod/Cluster/ClusterInfo.cpp +++ b/arangod/Cluster/ClusterInfo.cpp @@ -1919,15 +1919,9 @@ Result ClusterInfo::createCollectionsCoordinator(std::string const& databaseName } if (nrDone->load(std::memory_order_acquire) == infos.size()) { - { - // We need to lock all condition variables - std::vector<::arangodb::basics::ConditionLocker> lockers; - for (auto& cb : agencyCallbacks) { - CONDITION_LOCKER(locker, cb->_cv); - } - cbGuard.fire(); - // After the guard is done we can release the lockers - } + // unregister the callbacks + // We do not need any locks on condition variables as we are locked by the cacheMutex + cbGuard.fire(); // Now we need to remove TTL + the IsBuilding flag in Agency opers.clear(); opers.push_back(IncreaseVersion()); @@ -1958,15 +1952,9 @@ Result ClusterInfo::createCollectionsCoordinator(std::string const& databaseName return TRI_ERROR_NO_ERROR; } if (tmpRes > TRI_ERROR_NO_ERROR) { - { - // We need to lock all condition variables - std::vector<::arangodb::basics::ConditionLocker> lockers; - for (auto& cb : agencyCallbacks) { - CONDITION_LOCKER(locker, cb->_cv); - } - cbGuard.fire(); - // After the guard is done we can release the lockers - } + // unregister the callbacks + // We do not need any locks on condition variables as we are locked by the cacheMutex + cbGuard.fire(); // report error for (auto const& info : infos) { @@ -1997,9 +1985,20 @@ Result ClusterInfo::createCollectionsCoordinator(std::string const& databaseName TRI_ASSERT(agencyCallbacks.size() == infos.size()); for (size_t i = 0; i < infos.size(); ++i) { if (infos[i].state == ClusterCollectionCreationInfo::INIT) { - // This one has not responded, wait for it. - CONDITION_LOCKER(locker, agencyCallbacks[i]->_cv); - agencyCallbacks[i]->executeByCallbackOrTimeout(interval); + { + // This one has not responded, wait for it. + CONDITION_LOCKER(locker, agencyCallbacks[i]->_cv); + bool wokenUp = agencyCallbacks[i]->executeByCallbackOrTimeout(interval); + if (wokenUp) { + // We got woken up by waittime, not by callback. + // Let us check if we skipped other callbacks as well + for (; i < infos.size(); ++i) { + if (infos[i].state == ClusterCollectionCreationInfo::INIT) { + agencyCallbacks[i]->refetchAndUpdate(true, false); + } + } + } + } break; } } diff --git a/arangod/VocBase/Methods/CollectionCreationInfo.h b/arangod/VocBase/Methods/CollectionCreationInfo.h index 9a0ad4d9f0..d1ff12bd70 100644 --- a/arangod/VocBase/Methods/CollectionCreationInfo.h +++ b/arangod/VocBase/Methods/CollectionCreationInfo.h @@ -21,7 +21,7 @@ //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_VOCBASE__COLLECTION_CREATION_INFO_H -#define ARANGOD_VOCBASE__COLLECTION_CREATION__INFO_H 1 +#define ARANGOD_VOCBASE__COLLECTION_CREATION_INFO_H 1 #include @@ -37,4 +37,4 @@ struct CollectionCreationInfo { }; } // namespace arangodb -#endif \ No newline at end of file +#endif