diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 98aacbddb8..b3a2f879e4 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -32,59 +31,29 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include -#include -#include #include -#include #include #include -#include -#include #include #include -#include #include -#include -#include #include -#include -#include -#include #include -#include #include #include -#include -#include -#include #include -#include -#include -#include #include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include namespace ripple { @@ -325,7 +294,6 @@ public: NodeStoreScheduler m_nodeStoreScheduler; std::unique_ptr m_shaMapStore; - std::unique_ptr m_nodeStore; PendingSaves pendingSaves_; AccountIDCache accountIDCache_; boost::optional openLedger_; @@ -333,7 +301,6 @@ public: // These are not Stoppable-derived NodeCache m_tempNodeCache; std::unique_ptr m_collectorManager; - detail::AppFamily family_; CachedSLEs cachedSLEs_; std::pair nodeIdentity_; @@ -341,6 +308,8 @@ public: // These are Stoppable-related std::unique_ptr m_jobQueue; + std::unique_ptr m_nodeStore; + detail::AppFamily family_; // VFALCO TODO Make OrderBookDB abstract OrderBookDB m_orderBookDB; std::unique_ptr m_pathRequests; @@ -416,8 +385,6 @@ public: logs_->journal ("SHAMapStore"), logs_->journal ("NodeObject"), m_txMaster, *config_)) - , m_nodeStore (m_shaMapStore->makeDatabase ("NodeStore.main", 4)) - , accountIDCache_(128000) , m_tempNodeCache ("NodeCache", 16384, 90, stopwatch(), @@ -426,8 +393,6 @@ public: , m_collectorManager (CollectorManager::New ( config_->section (SECTION_INSIGHT), logs_->journal("Collector"))) - , family_ (*this, *m_nodeStore, *m_collectorManager) - , cachedSLEs_ (std::chrono::minutes(1), stopwatch()) , m_resourceManager (Resource::make_Manager ( @@ -443,6 +408,10 @@ public: // // Anything which calls addJob must be a descendant of the JobQueue // + , m_nodeStore ( + m_shaMapStore->makeDatabase ("NodeStore.main", 4, *m_jobQueue)) + + , family_ (*this, *m_nodeStore, *m_collectorManager) , m_orderBookDB (*this, *m_jobQueue) @@ -1964,9 +1933,9 @@ bool ApplicationImp::updateTables () auto j = logs_->journal("NodeObject"); NodeStore::DummyScheduler scheduler; std::unique_ptr source = - NodeStore::Manager::instance().make_Database ("NodeStore.import", scheduler, - j, 0, - config_->section(ConfigSection::importNodeDatabase ())); + NodeStore::Manager::instance().make_Database ("NodeStore.import", + scheduler, 0, *m_jobQueue, + config_->section(ConfigSection::importNodeDatabase ()), j); JLOG (j.warn()) << "Node import from '" << source->getName () << "' to '" diff --git a/src/ripple/app/misc/SHAMapStore.h b/src/ripple/app/misc/SHAMapStore.h index e2544fb741..6ac3229e79 100644 --- a/src/ripple/app/misc/SHAMapStore.h +++ b/src/ripple/app/misc/SHAMapStore.h @@ -21,9 +21,7 @@ #define RIPPLE_APP_MISC_SHAMAPSTORE_H_INCLUDED #include -#include #include -#include #include #include @@ -62,7 +60,8 @@ public: virtual std::uint32_t clampFetchDepth (std::uint32_t fetch_depth) const = 0; virtual std::unique_ptr makeDatabase ( - std::string const& name, std::int32_t readThreads) = 0; + std::string const& name, + std::int32_t readThreads, Stoppable& parent) = 0; /** Highest ledger that may be deleted. */ virtual LedgerIndex setCanDelete (LedgerIndex canDelete) = 0; diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index d715a8a463..77f385bb49 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -20,17 +20,10 @@ #include #include -#include #include -#include -#include +#include #include #include -#include -#include -#include -#include -#include namespace ripple { void SHAMapStoreImp::SavedStateDB::init (BasicConfig const& config, @@ -210,7 +203,7 @@ SHAMapStoreImp::SHAMapStoreImp ( std::unique_ptr SHAMapStoreImp::makeDatabase (std::string const& name, - std::int32_t readThreads) + std::int32_t readThreads, Stoppable& parent) { std::unique_ptr db; @@ -226,8 +219,8 @@ SHAMapStoreImp::makeDatabase (std::string const& name, fdlimit_ = writableBackend->fdlimit() + archiveBackend->fdlimit(); std::unique_ptr dbr = - makeDatabaseRotating (name, readThreads, writableBackend, - archiveBackend); + makeDatabaseRotating (name, readThreads, parent, + writableBackend, archiveBackend); if (!state.writableDb.size()) { @@ -242,7 +235,7 @@ SHAMapStoreImp::makeDatabase (std::string const& name, else { db = NodeStore::Manager::instance().make_Database (name, scheduler_, - nodeStoreJournal_, readThreads, setup_.nodeDatabase); + readThreads, parent, setup_.nodeDatabase, nodeStoreJournal_); fdlimit_ = db->fdlimit(); } @@ -530,12 +523,13 @@ SHAMapStoreImp::makeBackendRotating (std::string path) std::unique_ptr SHAMapStoreImp::makeDatabaseRotating (std::string const& name, - std::int32_t readThreads, + std::int32_t readThreads, Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend) const { - return NodeStore::Manager::instance().make_DatabaseRotating ("NodeStore.main", scheduler_, - readThreads, writableBackend, archiveBackend, nodeStoreJournal_); + return NodeStore::Manager::instance().make_DatabaseRotating ( + name, scheduler_, readThreads, parent, + writableBackend, archiveBackend, nodeStoreJournal_); } bool diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h index f4cb75a02a..6d047f5d05 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.h +++ b/src/ripple/app/misc/SHAMapStoreImp.h @@ -21,18 +21,17 @@ #define RIPPLE_APP_MISC_SHAMAPSTOREIMP_H_INCLUDED #include -#include +#include #include -#include -#include #include -#include #include #include namespace ripple { +class NetworkOPs; + class SHAMapStoreImp : public SHAMapStore { private: @@ -134,7 +133,8 @@ public: } std::unique_ptr makeDatabase ( - std::string const&name, std::int32_t readThreads) override; + std::string const&name, + std::int32_t readThreads, Stoppable& parent) override; LedgerIndex setCanDelete (LedgerIndex seq) override @@ -191,7 +191,7 @@ private: */ std::unique_ptr makeDatabaseRotating (std::string const&name, - std::int32_t readThreads, + std::int32_t readThreads, Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend) const; diff --git a/src/ripple/core/JobQueue.h b/src/ripple/core/JobQueue.h index e27a9a0bf2..81fbd3d050 100644 --- a/src/ripple/core/JobQueue.h +++ b/src/ripple/core/JobQueue.h @@ -22,19 +22,12 @@ #include #include -#include #include #include +#include #include #include -#include -#include #include -#include -#include -#include -#include -#include namespace ripple { diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index 9748f9ff3f..fde3eb5912 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -172,11 +172,11 @@ class RootStoppable; class Stoppable { protected: - Stoppable (char const* name, RootStoppable& root); + Stoppable (std::string name, RootStoppable& root); public: /** Create the Stoppable. */ - Stoppable (char const* name, Stoppable& parent); + Stoppable (std::string name, Stoppable& parent); /** Destroy the Stoppable. */ virtual ~Stoppable (); @@ -294,7 +294,7 @@ private: class RootStoppable : public Stoppable { public: - explicit RootStoppable (char const* name); + explicit RootStoppable (std::string name); ~RootStoppable () = default; @@ -339,7 +339,7 @@ private: /* Notify a root stoppable and children to stop, without waiting. Has no effect if the stoppable was already notified. - Returns true on the first call to stopAsync(), false otherwise. + Returns true on the first call to this method, false otherwise. Thread safety: Safe to call from any thread at any time. diff --git a/src/ripple/core/impl/JobQueue.cpp b/src/ripple/core/impl/JobQueue.cpp index 66f7dee3c7..1d3ba54fb3 100644 --- a/src/ripple/core/impl/JobQueue.cpp +++ b/src/ripple/core/impl/JobQueue.cpp @@ -19,15 +19,7 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace ripple { @@ -93,6 +85,8 @@ JobQueue::addJob (JobType type, std::string const& name, assert (type == jtCLIENT || m_workers.getNumberOfThreads () > 0); { + std::lock_guard lock (m_mutex); + // If this goes off it means that a child didn't follow // the Stoppable API rules. A job may only be added if: // @@ -104,15 +98,10 @@ JobQueue::addJob (JobType type, std::string const& name, // OR // * Not all children are stopped // - std::lock_guard lock (m_mutex); assert (! isStopped() && ( m_processCount>0 || ! m_jobSet.empty () || ! areChildrenStopped())); - } - - { - std::lock_guard lock (m_mutex); std::pair ::iterator, bool> result ( m_jobSet.insert (Job (type, name, ++m_lastJob, @@ -218,6 +207,9 @@ void JobQueue::addLoadEvents (JobType t, int count, std::chrono::milliseconds elapsed) { + if (isStopped()) + LogicError ("JobQueue::addLoadEvents() called after JobQueue stopped"); + JobDataMap::iterator iter (m_jobData.find (t)); assert (iter != m_jobData.end ()); iter->second.load().addSamples (count, elapsed); diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index 744417e279..862e592a01 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -22,8 +22,8 @@ namespace ripple { -Stoppable::Stoppable (char const* name, RootStoppable& root) - : m_name (name) +Stoppable::Stoppable (std::string name, RootStoppable& root) + : m_name (std::move (name)) , m_root (root) , m_child (this) , m_started (false) @@ -32,8 +32,8 @@ Stoppable::Stoppable (char const* name, RootStoppable& root) { } -Stoppable::Stoppable (char const* name, Stoppable& parent) - : m_name (name) +Stoppable::Stoppable (std::string name, Stoppable& parent) + : m_name (std::move (name)) , m_root (parent.m_root) , m_child (this) , m_started (false) @@ -157,8 +157,8 @@ void Stoppable::stopRecursive (beast::Journal j) //------------------------------------------------------------------------------ -RootStoppable::RootStoppable (char const* name) - : Stoppable (name, *this) +RootStoppable::RootStoppable (std::string name) + : Stoppable (std::move (name), *this) , m_prepared (false) , m_calledStop (false) { diff --git a/src/ripple/nodestore/Database.h b/src/ripple/nodestore/Database.h index 1134fd9622..611a0850a2 100644 --- a/src/ripple/nodestore/Database.h +++ b/src/ripple/nodestore/Database.h @@ -20,9 +20,10 @@ #ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED #define RIPPLE_NODESTORE_DATABASE_H_INCLUDED +#include +#include #include #include -#include namespace ripple { namespace NodeStore { @@ -40,9 +41,20 @@ namespace NodeStore { @see NodeObject */ -class Database +class Database : public Stoppable { public: + Database() = delete; + + /** Construct the node store. + + @param name The Stoppable name for this Database. + @param parent The parent Stoppable. + */ + Database (std::string name, Stoppable& parent) + : Stoppable (std::move (name), parent) + { } + /** Destroy the node store. All pending operations are completed, pending writes flushed, and files closed before this returns. @@ -55,11 +67,6 @@ public: */ virtual std::string getName () const = 0; - /** Close the database. - This allows the caller to catch exceptions. - */ - virtual void close() = 0; - /** Fetch an object. If the object is known to be not in the database, isn't found in the database during the fetch, or failed to load correctly during the fetch, diff --git a/src/ripple/nodestore/Manager.h b/src/ripple/nodestore/Manager.h index fa1bb139ff..514668b930 100644 --- a/src/ripple/nodestore/Manager.h +++ b/src/ripple/nodestore/Manager.h @@ -22,9 +22,6 @@ #include #include -#include -#include -#include namespace ripple { namespace NodeStore { @@ -87,16 +84,18 @@ public: virtual std::unique_ptr make_Database (std::string const& name, Scheduler& scheduler, - beast::Journal journal, int readThreads, - Section const& backendParameters) = 0; + int readThreads, Stoppable& parent, + Section const& backendParameters, + beast::Journal journal) = 0; virtual std::unique_ptr make_DatabaseRotating (std::string const& name, Scheduler& scheduler, std::int32_t readThreads, - std::shared_ptr writableBackend, - std::shared_ptr archiveBackend, - beast::Journal journal) = 0; + Stoppable& parent, + std::shared_ptr writableBackend, + std::shared_ptr archiveBackend, + beast::Journal journal) = 0; }; //------------------------------------------------------------------------------ diff --git a/src/ripple/nodestore/impl/DatabaseImp.h b/src/ripple/nodestore/impl/DatabaseImp.h index ac4052dd8c..717ed830a5 100644 --- a/src/ripple/nodestore/impl/DatabaseImp.h +++ b/src/ripple/nodestore/impl/DatabaseImp.h @@ -24,16 +24,8 @@ #include #include #include -#include #include -#include -#include -#include #include -#include -#include -#include -#include namespace ripple { namespace NodeStore { @@ -62,14 +54,21 @@ private: bool m_readShut; uint64_t m_readGen; // current read generation int fdlimit_; + std::atomic m_storeCount; + std::atomic m_fetchTotalCount; + std::atomic m_fetchHitCount; + std::atomic m_storeSize; + std::atomic m_fetchSize; public: DatabaseImp (std::string const& name, Scheduler& scheduler, int readThreads, + Stoppable& parent, std::unique_ptr backend, beast::Journal journal) - : m_journal (journal) + : Database (name, parent) + , m_journal (journal) , m_scheduler (scheduler) , m_backend (std::move (backend)) , m_cache ("NodeStore", cacheTargetSize, cacheTargetSeconds, @@ -109,16 +108,6 @@ public: return m_backend->getName (); } - void - close() override - { - if (m_backend) - { - m_backend->close(); - m_backend = nullptr; - } - } - //------------------------------------------------------------------------------ bool asyncFetch (uint256 const& hash, std::shared_ptr& object) override @@ -440,6 +429,18 @@ public: return fdlimit_; } + //-------------------------------------------------------------------------- + // + // Stoppable. + + void onStop () override + { + // After stop time we can no longer use the JobQueue for background + // reads. Join the background read threads. + DatabaseImp::stopThreads(); + stopped(); + } + protected: void stopThreads () { @@ -456,13 +457,6 @@ protected: for (auto& e : m_readThreads) e.join(); } - -private: - std::atomic m_storeCount; - std::atomic m_fetchTotalCount; - std::atomic m_fetchHitCount; - std::atomic m_storeSize; - std::atomic m_fetchSize; }; } diff --git a/src/ripple/nodestore/impl/DatabaseRotatingImp.h b/src/ripple/nodestore/impl/DatabaseRotatingImp.h index 44532a1c50..c0395d207f 100644 --- a/src/ripple/nodestore/impl/DatabaseRotatingImp.h +++ b/src/ripple/nodestore/impl/DatabaseRotatingImp.h @@ -50,6 +50,7 @@ public: DatabaseRotatingImp (std::string const& name, Scheduler& scheduler, int readThreads, + Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend, beast::Journal journal) @@ -57,6 +58,7 @@ public: name, scheduler, readThreads, + parent, std::unique_ptr (), journal) , writableBackend_ (writableBackend) @@ -93,13 +95,6 @@ public: return getWritableBackend()->getName(); } - void - close() override - { - // VFALCO TODO How do we close everything? - assert(false); - } - std::int32_t getWriteLoad() const override { return getWritableBackend()->getWriteLoad(); diff --git a/src/ripple/nodestore/impl/ManagerImp.cpp b/src/ripple/nodestore/impl/ManagerImp.cpp index 92fb649b48..a9826ba4c4 100644 --- a/src/ripple/nodestore/impl/ManagerImp.cpp +++ b/src/ripple/nodestore/impl/ManagerImp.cpp @@ -18,14 +18,8 @@ //============================================================================== #include -#include #include -#include #include -#include -#include -#include -#include namespace ripple { namespace NodeStore { @@ -90,14 +84,16 @@ std::unique_ptr ManagerImp::make_Database ( std::string const& name, Scheduler& scheduler, - beast::Journal journal, int readThreads, - Section const& backendParameters) + Stoppable& parent, + Section const& backendParameters, + beast::Journal journal) { return std::make_unique ( name, scheduler, readThreads, + parent, make_Backend ( backendParameters, scheduler, @@ -110,6 +106,7 @@ ManagerImp::make_DatabaseRotating ( std::string const& name, Scheduler& scheduler, std::int32_t readThreads, + Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend, beast::Journal journal) @@ -118,6 +115,7 @@ ManagerImp::make_DatabaseRotating ( name, scheduler, readThreads, + parent, writableBackend, archiveBackend, journal); diff --git a/src/ripple/nodestore/impl/ManagerImp.h b/src/ripple/nodestore/impl/ManagerImp.h index f4e87852ac..55a4d098e2 100644 --- a/src/ripple/nodestore/impl/ManagerImp.h +++ b/src/ripple/nodestore/impl/ManagerImp.h @@ -21,8 +21,6 @@ #define RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED #include -#include -#include namespace ripple { namespace NodeStore { @@ -65,15 +63,17 @@ public: make_Database ( std::string const& name, Scheduler& scheduler, - beast::Journal journal, int readThreads, - Section const& backendParameters) override; + Stoppable& parent, + Section const& backendParameters, + beast::Journal journal) override; std::unique_ptr make_DatabaseRotating ( std::string const& name, Scheduler& scheduler, std::int32_t readThreads, + Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend, beast::Journal journal) override; diff --git a/src/test/nodestore/Database_test.cpp b/src/test/nodestore/Database_test.cpp index 01fc86855e..c1abff846e 100644 --- a/src/test/nodestore/Database_test.cpp +++ b/src/test/nodestore/Database_test.cpp @@ -22,7 +22,6 @@ #include #include #include -#include namespace ripple { namespace NodeStore { @@ -34,6 +33,7 @@ public: std::string const& srcBackendType, std::int64_t seedValue) { DummyScheduler scheduler; + RootStoppable parent ("TestRootStoppable"); beast::temp_dir node_db; Section srcParams; @@ -49,7 +49,7 @@ public: // Write to source db { std::unique_ptr src = Manager::instance().make_Database ( - "test", scheduler, j, 2, srcParams); + "test", scheduler, 2, parent, srcParams, j); storeBatch (*src, batch); } @@ -58,7 +58,7 @@ public: { // Re-open the db std::unique_ptr src = Manager::instance().make_Database ( - "test", scheduler, j, 2, srcParams); + "test", scheduler, 2, parent, srcParams, j); // Set up the destination database beast::temp_dir dest_db; @@ -67,7 +67,7 @@ public: destParams.set ("path", dest_db.path()); std::unique_ptr dest = Manager::instance().make_Database ( - "test", scheduler, j, 2, destParams); + "test", scheduler, 2, parent, destParams, j); testcase ("import into '" + destBackendType + "' from '" + srcBackendType + "'"); @@ -93,6 +93,7 @@ public: int numObjectsToTest = 2000) { DummyScheduler scheduler; + RootStoppable parent ("TestRootStoppable"); std::string s = "NodeStore backend '" + type + "'"; @@ -114,7 +115,7 @@ public: { // Open the database std::unique_ptr db = Manager::instance().make_Database ( - "test", scheduler, j, 2, nodeParams); + "test", scheduler, 2, parent, nodeParams, j); // Write the batch storeBatch (*db, batch); @@ -143,7 +144,7 @@ public: { // Re-open the database without the ephemeral DB std::unique_ptr db = Manager::instance().make_Database ( - "test", scheduler, j, 2, nodeParams); + "test", scheduler, 2, parent, nodeParams, j); // Read it back in Batch copy; diff --git a/src/test/shamap/common.h b/src/test/shamap/common.h index 2a1e316e4f..98de9f9eb0 100644 --- a/src/test/shamap/common.h +++ b/src/test/shamap/common.h @@ -21,17 +21,10 @@ #define RIPPLE_SHAMAP_TESTS_COMMON_H_INCLUDED #include -#include #include -#include -#include -#include -#include -#include #include #include -#include -#include +#include namespace ripple { namespace tests { @@ -43,6 +36,7 @@ private: NodeStore::DummyScheduler scheduler_; TreeNodeCache treecache_; FullBelowCache fullbelow_; + RootStoppable parent_; std::unique_ptr db_; beast::Journal j_; @@ -50,13 +44,14 @@ public: TestFamily (beast::Journal j) : treecache_ ("TreeNodeCache", 65536, 60, clock_, j) , fullbelow_ ("full_below", clock_) + , parent_ ("TestRootStoppable") , j_ (j) { Section testSection; testSection.set("type", "memory"); testSection.set("Path", "SHAMap_test"); db_ = NodeStore::Manager::instance ().make_Database ( - "test", scheduler_, j, 1, testSection); + "test", scheduler_, 1, parent_, testSection, j); } beast::manual_clock