diff --git a/arangod/Cluster/ClusterInfo.cpp b/arangod/Cluster/ClusterInfo.cpp index 4e48165a3d..975db7f572 100644 --- a/arangod/Cluster/ClusterInfo.cpp +++ b/arangod/Cluster/ClusterInfo.cpp @@ -1224,68 +1224,6 @@ std::shared_ptr ClusterInfo::getView( return nullptr; } -std::shared_ptr ClusterInfo::getViewCurrent( - DatabaseID const& databaseID, - ViewID const& viewID -) { - if (viewID.empty()) { - return nullptr; - } - - static const auto lookupView = []( - AllViews const& dbs, - DatabaseID const& databaseID, - ViewID const& viewID - ) noexcept -> std::shared_ptr { - auto const db = dbs.find(databaseID); // look up database by id - - if (db != dbs.end()) { - auto& views = db->second; - auto const itr = views.find(viewID); // look up view by id (or by name) - - if (itr != views.end()) { - return itr->second; - } - } - - return nullptr; - }; - - if (std::this_thread::get_id() == _planLoader) { - return lookupView(_plannedViews, databaseID, viewID); - } - - size_t planReloads = 0; - - if (!_planProt.isValid) { - loadPlan(); // current Views are actually in Plan instead of Current - ++planReloads; - } - - for(;;) { - { - READ_LOCKER(readLocker, _planProt.lock); - auto const view = lookupView(_plannedViews, databaseID, viewID); - - if (view) { - return view; - } - } - - if (planReloads >= 2) { - break; - } - - loadPlan(); // current Views are actually in Plan instead of Current (must load plan outside the lock) - ++planReloads; - } - - LOG_TOPIC(INFO, Logger::CLUSTER) - << "View not found: '" << viewID << "' in database '" << databaseID << "'"; - - return nullptr; -} - ////////////////////////////////////////////////////////////////////////////// /// @brief ask about all views of a database ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Cluster/ClusterInfo.h b/arangod/Cluster/ClusterInfo.h index a0bc6aa909..c70001eca0 100644 --- a/arangod/Cluster/ClusterInfo.h +++ b/arangod/Cluster/ClusterInfo.h @@ -358,16 +358,6 @@ class ClusterInfo { ViewID const& viewID ); - ////////////////////////////////////////////////////////////////////////////// - /// @brief ask about a view in current. - /// If it is not found in the cache (and not currently loading plan), then the - /// cache is reloaded once. - ////////////////////////////////////////////////////////////////////////////// - std::shared_ptr getViewCurrent( - DatabaseID const& vocbase, - ViewID const& viewID - ); - ////////////////////////////////////////////////////////////////////////////// /// @brief ask about all views of a database ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/IResearch/IResearchViewDBServer.cpp b/arangod/IResearch/IResearchViewDBServer.cpp index 42b6fcb21b..09ed7a32ed 100644 --- a/arangod/IResearch/IResearchViewDBServer.cpp +++ b/arangod/IResearch/IResearchViewDBServer.cpp @@ -231,41 +231,21 @@ struct IResearchViewDBServer::ViewFactory: public arangodb::ViewFactory { ); } - auto wiew = std::shared_ptr( - new IResearchViewDBServer(vocbase, definition, *feature, planVersion) - ); - std::string error; - IResearchViewMeta meta; + auto meta = std::make_shared(); - if (!meta.init(definition, error)) { + if (!meta->init(definition, error)) { return arangodb::Result( TRI_ERROR_BAD_PARAMETER, error.empty() - ? (std::string("failed to initialize arangosearch View '") + wiew->name() + "' from definition: " + definition.toString()) - : (std::string("failed to initialize arangosearch View '") + wiew->name() + "' from definition, error in attribute '" + error + "': " + definition.toString()) + ? (std::string("failed to initialize arangosearch View '") + static_cast(name) + "' from definition: " + definition.toString()) + : (std::string("failed to initialize arangosearch View '") + static_cast(name) + "' from definition, error in attribute '" + error + "': " + definition.toString()) ); } - // search for the previous view instance and check if it's meta is the same - { - auto oldLogicalWiew = - ci->getViewCurrent(vocbase.name(), std::to_string(wiew->id())); - auto* oldWiew = arangodb::LogicalView::cast( - oldLogicalWiew.get() - ); - - if (oldWiew && *(oldWiew->_meta) == meta) { - wiew->_meta = oldWiew->_meta; - } - } - - if (!(wiew->_meta)) { - wiew->_meta = std::make_shared(); - static_cast(*(wiew->_meta)) = std::move(meta); - } - - view = wiew; + view = std::shared_ptr( + new IResearchViewDBServer(vocbase, definition, *feature, planVersion, std::move(meta)) + ); return arangodb::Result(); } @@ -281,36 +261,6 @@ struct IResearchViewDBServer::ViewFactory: public arangodb::ViewFactory { return arangodb::Result(); // resuse view from vocbase } - auto* ci = ClusterInfo::instance(); - std::shared_ptr meta; - - // reference meta from cluster-wide view if available to - // avoid memory and thread allocation - // if not availble then the meta will be reassigned when - // the per-cid instance is associated with the cluster-wide view - if (ci) { - auto planId = arangodb::basics::VelocyPackHelper::stringUInt64( - definition.get(arangodb::StaticStrings::DataSourcePlanId) - ); // planId set in ensure(...) - auto wiewId = std::to_string(planId); - auto logicalWiew = ci->getView(vocbase.name(), wiewId); // here if creating per-cid view during loadPlan() - auto* wiew = arangodb::LogicalView::cast( - logicalWiew.get() - ); - - // if not found in 'Plan' then search in 'Current' - if (!wiew) { - logicalWiew = ci->getViewCurrent(vocbase.name(), wiewId); // here if creating per-cid view outisde of loadPlan() - wiew = arangodb::LogicalView::cast( - logicalWiew.get() - ); - } - - if (wiew) { - meta = wiew->_meta; - } - } - // no view for shard arangodb::LogicalView::ptr impl; auto res = IResearchView::factory().instantiate( @@ -328,29 +278,39 @@ struct IResearchViewDBServer::ViewFactory: public arangodb::ViewFactory { ); } - if (meta) { - res = arangodb::LogicalView::cast(*impl).updateProperties(meta); - - if (!res.ok()) { - return res; - } - } - // a wrapper to remove the view from vocbase if it no longer has any links // hold a reference to the original view in the deleter so that the view is // still valid for the duration of the pointer wrapper view = std::shared_ptr( impl.get(), - [impl](arangodb::LogicalView*)->void { - static const auto visitor = [](TRI_voc_cid_t)->bool { return false; }; + [impl] (arangodb::LogicalView*) noexcept -> void { auto& vocbase = impl->vocbase(); - // same view in vocbase and with no collections - if (impl.get() == vocbase.lookupView(impl->id()).get() // avoid double dropView(...) - && impl->visitCollections(visitor) - && !impl->drop().ok()) { // per-cid collections always system - LOG_TOPIC(WARN, arangodb::iresearch::TOPIC) - << "failure to drop stale arangosearch View '" << impl->name() << "' while from database '" << vocbase.name() << "'"; + // suppress any errors in destructor + + try { + // same view in vocbase and with no collections + if (impl == vocbase.lookupView(impl->id()) // avoid double dropView(...) + && impl->visitCollections([](TRI_voc_cid_t){ return false; }) + && !impl->drop().ok()) { // per-cid collections always system + LOG_TOPIC(WARN, arangodb::iresearch::TOPIC) + << "failure to drop stale arangosearch View '" << impl->name() << "' while from database '" << vocbase.name() << "'"; + } + } catch (basics::Exception const& e) { + LOG_TOPIC(ERR, arangodb::iresearch::TOPIC) + << "caught exception while dropping stale arangosearch View '" << impl->name() + << "' while from database '" << vocbase.name() + << "', errorCode: '" << e.code() + << "', error: '" << e.message(); + } catch (std::exception const& e) { + LOG_TOPIC(ERR, arangodb::iresearch::TOPIC) + << "caught exception while dropping stale arangosearch View '" << impl->name() + << "' while from database '" << vocbase.name() + << "', error: '" << e.what() << "'"; + } catch (...) { + LOG_TOPIC(ERR, arangodb::iresearch::TOPIC) + << "caught an unspecified exception while dropping stale arangosearch View '" << impl->name() + << "' while from database '" << vocbase.name() << "'"; } } ); @@ -362,12 +322,14 @@ struct IResearchViewDBServer::ViewFactory: public arangodb::ViewFactory { IResearchViewDBServer::IResearchViewDBServer( TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& info, - arangodb::DatabasePathFeature const& dbPathFeature, - uint64_t planVersion -): LogicalViewClusterInfo(vocbase, info, planVersion) { + arangodb::DatabasePathFeature const& /*dbPathFeature*/, + uint64_t planVersion, + std::shared_ptr meta /*=nullptr*/ +) : LogicalViewClusterInfo(vocbase, info, planVersion), + _meta(std::move(meta)) { } -IResearchViewDBServer::~IResearchViewDBServer() { +IResearchViewDBServer::~IResearchViewDBServer() noexcept { _collections.clear(); // ensure view distructors called before mutex is deallocated } @@ -821,4 +783,4 @@ bool IResearchViewDBServer::visitCollections( // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE -// ----------------------------------------------------------------------------- \ No newline at end of file +// ----------------------------------------------------------------------------- diff --git a/arangod/IResearch/IResearchViewDBServer.h b/arangod/IResearch/IResearchViewDBServer.h index 228d7ee123..7546346b25 100644 --- a/arangod/IResearch/IResearchViewDBServer.h +++ b/arangod/IResearch/IResearchViewDBServer.h @@ -53,7 +53,7 @@ class AsyncMeta; class IResearchViewDBServer final: public arangodb::LogicalViewClusterInfo { public: - virtual ~IResearchViewDBServer(); + virtual ~IResearchViewDBServer() noexcept; using LogicalView::drop; @@ -122,7 +122,8 @@ class IResearchViewDBServer final: public arangodb::LogicalViewClusterInfo { TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& info, arangodb::DatabasePathFeature const& dbPathFeature, - uint64_t planVersion + uint64_t planVersion, + std::shared_ptr meta = nullptr ); };