From 0747c09bbb3b3e4a235322da3caade1493cf5dda Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 11:33:49 -0600 Subject: [PATCH 01/62] Remove Stoppable::onPrepare --- src/ripple/basics/impl/ResolverAsio.cpp | 1 - src/ripple/core/Stoppable.h | 47 ++---- src/ripple/core/impl/Stoppable.cpp | 16 -- src/ripple/overlay/impl/OverlayImpl.cpp | 8 +- src/ripple/overlay/impl/OverlayImpl.h | 3 - src/ripple/peerfinder/PeerfinderManager.h | 4 + .../peerfinder/impl/PeerfinderManager.cpp | 8 +- src/test/basics/PerfLog_test.cpp | 5 - src/test/core/Stoppable_test.cpp | 145 ++++-------------- 9 files changed, 50 insertions(+), 187 deletions(-) diff --git a/src/ripple/basics/impl/ResolverAsio.cpp b/src/ripple/basics/impl/ResolverAsio.cpp index d473953dd15..f75a390304b 100644 --- a/src/ripple/basics/impl/ResolverAsio.cpp +++ b/src/ripple/basics/impl/ResolverAsio.cpp @@ -218,7 +218,6 @@ class ResolverAsioImpl : public ResolverAsio, override { assert(m_stop_called == false); - assert(m_stopped == true); assert(!names.empty()); // TODO NIKB use rvalue references to construct and move diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index e192b83beaf..f5af4099664 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -56,23 +56,7 @@ class RootStoppable; hierarchy: Stoppable objects may themselves have Stoppable child objects. This captures the relationship of dependencies. - 2. prepare() - - Because some components may depend on others, preparatory steps require - that all objects be first constructed. The prepare step calls all - Stoppable objects in the tree starting from the leaves and working up - to the root. In this stage we are guaranteed that all objects have been - constructed and are in a well-defined state. - - 3. onPrepare() - - This override is called for all Stoppable objects in the hierarchy - during the prepare stage. It is guaranteed that all child Stoppable - objects have already been prepared when this is called. - - Objects are called children first. - - 4. start() + 2. start() At this point all sub-components have been constructed and prepared, so it should be safe for them to be started. While some Stoppable @@ -80,7 +64,7 @@ class RootStoppable; threads or call asynchronous i/o initiating functions like timers or sockets. - 5. onStart() + 3. onStart() This override is called for all Stoppable objects in the hierarchy during the start stage. It is guaranteed that no child Stoppable @@ -90,12 +74,12 @@ class RootStoppable; This is the sequence of events involved in stopping: - 6. stopAsync() [optional] + 4. stopAsync() [optional] This notifies the root Stoppable and all its children that a stop is requested. - 7. stop() + 5. stop() This first calls stopAsync(), and then blocks on each child Stoppable in the in the tree from the bottom up, until the Stoppable indicates it has @@ -103,7 +87,7 @@ class RootStoppable; when some external signal indicates that the process should stop. For example, an RPC 'stop' command, or a SIGINT POSIX signal. - 8. onStop() + 6. onStop() This override is called for the root Stoppable and all its children when stopAsync() is called. Derived classes should cancel pending I/O and @@ -112,7 +96,7 @@ class RootStoppable; Objects are called parent first. - 9. onChildrenStopped() + 7. onChildrenStopped() This override is called when all the children have stopped. This informs the Stoppable that there should not be any more dependents making calls @@ -121,7 +105,7 @@ class RootStoppable; Objects are called children first. - 10. stopped() + 8. stopped() The derived class calls this function to inform the Stoppable API that it has completed the stop. This unblocks the caller of stop(). @@ -254,16 +238,6 @@ class Stoppable stopped(); private: - /** Override called during preparation. - Since all other Stoppable objects in the tree have already been - constructed, this provides an opportunity to perform initialization - which depends on calling into other Stoppable objects. This call is made - on the same thread that called prepare(). The default implementation does - nothing. Guaranteed to only be called once. - */ - virtual void - onPrepare(); - /** Override called during start. */ virtual void onStart(); @@ -327,8 +301,6 @@ class Stoppable Stoppable* stoppable; }; - void - prepareRecursive(); void startRecursive(); void @@ -361,9 +333,8 @@ class RootStoppable : public Stoppable bool isStopping() const; - /** Prepare and start all contained Stoppable objects. - This calls onPrepare for all Stoppable objects in the tree, bottom-up, - then calls onStart for the same, top-down. + /** Start all contained Stoppable objects. + This calls onStart for all Stoppable objects in the tree, top-down. Calls made after the first have no effect. Thread safety: May be called from any thread. diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index 5d54c15660d..d0ac20372e4 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -76,11 +76,6 @@ Stoppable::stopped() m_cv.notify_all(); } -void -Stoppable::onPrepare() -{ -} - void Stoppable::onStart() { @@ -99,16 +94,6 @@ Stoppable::onChildrenStopped() //------------------------------------------------------------------------------ -void -Stoppable::prepareRecursive() -{ - for (Children::const_iterator iter(m_children.cbegin()); - iter != m_children.cend(); - ++iter) - iter->stoppable->prepareRecursive(); - onPrepare(); -} - void Stoppable::startRecursive() { @@ -182,7 +167,6 @@ RootStoppable::start() { if (startEntered_.exchange(true)) return; - prepareRecursive(); startRecursive(); startExited_ = true; } diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 409d687cd50..232273a68f2 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -494,7 +494,7 @@ OverlayImpl::checkStopped() } void -OverlayImpl::onPrepare() +OverlayImpl::onStart() { PeerFinder::Config config = PeerFinder::Config::makeConfig( app_.config(), @@ -503,6 +503,7 @@ OverlayImpl::onPrepare() setup_.ipLimit); m_peerFinder->setConfig(config); + m_peerFinder->start(); // Populate our boot cache: if there are no entries in [ips] then we use // the entries in [ips_fixed]. @@ -566,11 +567,6 @@ OverlayImpl::onPrepare() m_peerFinder->addFixedPeer(name, ips); }); } -} - -void -OverlayImpl::onStart() -{ auto const timer = std::make_shared(*this); std::lock_guard lock(mutex_); list_.emplace(timer.get(), timer); diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index ae04b388d59..783c0a9078b 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -507,9 +507,6 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler void checkStopped(); - void - onPrepare() override; - void onStart() override; diff --git a/src/ripple/peerfinder/PeerfinderManager.h b/src/ripple/peerfinder/PeerfinderManager.h index bcca3c919c9..f945fb8d76a 100644 --- a/src/ripple/peerfinder/PeerfinderManager.h +++ b/src/ripple/peerfinder/PeerfinderManager.h @@ -154,6 +154,10 @@ class Manager : public Stoppable, public beast::PropertyStream::Source virtual void setConfig(Config const& config) = 0; + /** Transition to the started state, synchronously. */ + virtual void + start() = 0; + /** Returns the configuration for the manager. */ virtual Config config() = 0; diff --git a/src/ripple/peerfinder/impl/PeerfinderManager.cpp b/src/ripple/peerfinder/impl/PeerfinderManager.cpp index 73383befd9e..0b947abfb21 100644 --- a/src/ripple/peerfinder/impl/PeerfinderManager.cpp +++ b/src/ripple/peerfinder/impl/PeerfinderManager.cpp @@ -214,14 +214,8 @@ class ManagerImp : public Manager return m_logic.buildEndpointsForPeers(); } - //-------------------------------------------------------------------------- - // - // Stoppable - // - //-------------------------------------------------------------------------- - void - onPrepare() override + start() override { m_store.open(m_sociConfig); m_logic.load(); diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index 452057ef159..a9d2af3c314 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -73,11 +73,6 @@ class PerfLog_test : public beast::unit_test::suite private: // Interfaces for RootStoppable. Made private to encourage the use // of doStart() and doStop(). - void - onPrepare() override - { - } - void onStart() override { diff --git a/src/test/core/Stoppable_test.cpp b/src/test/core/Stoppable_test.cpp index c538af2a9ce..79f8dfec331 100644 --- a/src/test/core/Stoppable_test.cpp +++ b/src/test/core/Stoppable_test.cpp @@ -49,23 +49,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 9, "D::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 0, "D::onStart called out of order"); + test_.expect(++test_.count == 11, "D::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 11, "D::onStop called out of order"); + test_.expect(--test_.count == 0, "D::onStop called out of order"); } void @@ -73,7 +66,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 2, "D::onChildrenStopped called out of order"); + ++test_.count == 9, "D::onChildrenStopped called out of order"); } }; @@ -87,23 +80,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 7, "J::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 1, "J::onStart called out of order"); + test_.expect(++test_.count == 10, "J::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 10, "J::onStop called out of order"); + test_.expect(--test_.count == 1, "J::onStop called out of order"); } void @@ -111,7 +97,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 4, "J::onChildrenStopped called out of order"); + ++test_.count == 7, "J::onChildrenStopped called out of order"); } }; @@ -126,23 +112,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 8, "E::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 2, "E::onStart called out of order"); + test_.expect(++test_.count == 9, "E::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 9, "E::onStop called out of order"); + test_.expect(--test_.count == 2, "E::onStop called out of order"); } void @@ -150,7 +129,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 3, "E::onChildrenStopped called out of order"); + ++test_.count == 8, "E::onChildrenStopped called out of order"); } }; @@ -164,23 +143,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 6, "F::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 3, "F::onStart called out of order"); + test_.expect(++test_.count == 8, "F::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 8, "F::onStop called out of order"); + test_.expect(--test_.count == 3, "F::onStop called out of order"); } void @@ -188,7 +160,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 5, "F::onChildrenStopped called out of order"); + ++test_.count == 6, "F::onChildrenStopped called out of order"); } }; @@ -225,23 +197,16 @@ class Stoppable_test : public beast::unit_test::suite stop_ = stopping; } - void - onPrepare() override - { - test_.expect( - ++test_.count == 10, "A::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 4, "A::onStart called out of order"); + test_.expect(++test_.count == 7, "A::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 7, "A::onStop called out of order"); + test_.expect(--test_.count == 4, "A::onStop called out of order"); } void @@ -252,7 +217,8 @@ class Stoppable_test : public beast::unit_test::suite ; Stoppable::stopped(); test_.expect( - --test_.count == 1, "A::onChildrenStopped called out of order"); + ++test_.count == 10, + "A::onChildrenStopped called out of order"); stop_ = stopped; } }; @@ -267,23 +233,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 4, "G::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 5, "G::onStart called out of order"); + test_.expect(++test_.count == 6, "G::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 6, "G::onStop called out of order"); + test_.expect(--test_.count == 5, "G::onStop called out of order"); } void @@ -291,7 +250,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 7, "G::onChildrenStopped called out of order"); + ++test_.count == 4, "G::onChildrenStopped called out of order"); } }; @@ -305,23 +264,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 3, "H::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 6, "H::onStart called out of order"); + test_.expect(++test_.count == 5, "H::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 5, "H::onStop called out of order"); + test_.expect(--test_.count == 6, "H::onStop called out of order"); } void @@ -329,7 +281,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 8, "H::onChildrenStopped called out of order"); + ++test_.count == 3, "H::onChildrenStopped called out of order"); } }; @@ -348,23 +300,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 5, "B::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 7, "B::onStart called out of order"); + test_.expect(++test_.count == 4, "B::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 4, "B::onStop called out of order"); + test_.expect(--test_.count == 7, "B::onStop called out of order"); } void @@ -372,7 +317,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 6, "B::onChildrenStopped called out of order"); + ++test_.count == 5, "B::onChildrenStopped called out of order"); } }; @@ -386,23 +331,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 1, "I::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 8, "I::onStart called out of order"); + test_.expect(++test_.count == 3, "I::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 3, "I::onStop called out of order"); + test_.expect(--test_.count == 8, "I::onStop called out of order"); } void @@ -410,8 +348,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 10, - "I::onChildrenStopped called out of order"); + ++test_.count == 1, "I::onChildrenStopped called out of order"); } }; @@ -426,23 +363,16 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onPrepare() override - { - test_.expect( - ++test_.count == 2, "C::onPrepare called out of order"); - } - void onStart() override { - test_.expect(--test_.count == 9, "C::onStart called out of order"); + test_.expect(++test_.count == 2, "C::onStart called out of order"); } void onStop() override { - test_.expect(++test_.count == 2, "C::onStop called out of order"); + test_.expect(--test_.count == 9, "C::onStop called out of order"); } void @@ -450,7 +380,7 @@ class Stoppable_test : public beast::unit_test::suite { Stoppable::stopped(); test_.expect( - --test_.count == 9, "C::onChildrenStopped called out of order"); + ++test_.count == 2, "C::onChildrenStopped called out of order"); } }; @@ -480,25 +410,18 @@ class Stoppable_test : public beast::unit_test::suite stop(journal_); } - void - onPrepare() override - { - test_.expect( - ++test_.count == 11, "Root::onPrepare called out of order"); - } - void onStart() override { test_.expect( - --test_.count == 10, "Root::onStart called out of order"); + ++test_.count == 1, "Root::onStart called out of order"); } void onStop() override { test_.expect( - ++test_.count == 1, "Root::onStop called out of order"); + --test_.count == 10, "Root::onStop called out of order"); } void @@ -507,7 +430,7 @@ class Stoppable_test : public beast::unit_test::suite a_.join(); Stoppable::stopped(); test_.expect( - --test_.count == 0, + ++test_.count == 11, "Root::onChildrenStopped called out of order"); } From 73e63475e450dd3e1c8894e4b26235837613c626 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 13:49:45 -0600 Subject: [PATCH 02/62] [fold] Move timer from RootStoppable to LoadManager --- src/ripple/app/main/LoadManager.cpp | 39 +++++++++++------------------ src/ripple/app/main/LoadManager.h | 9 +++++-- src/ripple/core/Stoppable.h | 35 -------------------------- src/ripple/core/impl/Stoppable.cpp | 3 ++- 4 files changed, 23 insertions(+), 63 deletions(-) diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index b63972f34e1..631ae76846a 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -39,7 +39,6 @@ LoadManager::LoadManager( , journal_(journal) , deadLock_() , armed_(false) - , stop_(false) { } @@ -89,13 +88,15 @@ LoadManager::onStart() void LoadManager::onStop() { + { + std::lock_guard sl(mutex_); + stop_ = true; + // There is at most one thread waiting on this condition. + cv_.notify_all(); + } if (thread_.joinable()) { JLOG(journal_.debug()) << "Stopping"; - { - std::lock_guard sl(mutex_); - stop_ = true; - } thread_.join(); } stopped(); @@ -109,19 +110,22 @@ LoadManager::run() beast::setCurrentThreadName("LoadManager"); using namespace std::chrono_literals; - using clock_type = std::chrono::system_clock; + using clock_type = std::chrono::steady_clock; auto t = clock_type::now(); - bool stop = false; - while (!(stop || isStopping())) + while (true) { { - // Copy out shared data under a lock. Use copies outside lock. + t += 1s; std::unique_lock sl(mutex_); + if (cv_.wait_until(sl, t, [this] { return stop_; })) + { + break; + } + // Copy out shared data under a lock. Use copies outside lock. auto const deadLock = deadLock_; auto const armed = armed_; - stop = stop_; sl.unlock(); // Measure the amount of time we have been deadlocked, in seconds. @@ -192,22 +196,7 @@ LoadManager::run() // subscribe in NetworkOPs or Application. app_.getOPs().reportFeeChange(); } - - t += 1s; - auto const duration = t - clock_type::now(); - - if ((duration < 0s) || (duration > 1s)) - { - JLOG(journal_.warn()) << "time jump"; - t = clock_type::now(); - } - else - { - alertable_sleep_until(t); - } } - - stopped(); } //------------------------------------------------------------------------------ diff --git a/src/ripple/app/main/LoadManager.h b/src/ripple/app/main/LoadManager.h index c5d344bdb4b..68abe475d4e 100644 --- a/src/ripple/app/main/LoadManager.h +++ b/src/ripple/app/main/LoadManager.h @@ -21,6 +21,7 @@ #define RIPPLE_APP_MAIN_LOADMANAGER_H_INCLUDED #include +#include #include #include #include @@ -97,12 +98,16 @@ class LoadManager : public Stoppable beast::Journal const journal_; std::thread thread_; - std::mutex mutex_; // Guards deadLock_, armed_, and stop_. + std::mutex mutex_; // Guards deadLock_, armed_, cv_ + std::condition_variable cv_; + // LoadManager must be stoppable separately from other Stoppables + // for the ripple.app.Subscribe test. It must stop on its own signal, + // instead of waiting for RootStoppable::isStopping(). + bool stop_ = false; std::chrono::steady_clock::time_point deadLock_; // Detect server deadlocks. bool armed_; - bool stop_; friend std::unique_ptr make_LoadManager( diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index f5af4099664..1d92b2099d1 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -225,13 +225,6 @@ class Stoppable inline JobCounter& jobCounter(); - /** Sleep or wake up on stop. - - @return `true` if we are stopping - */ - bool - alertable_sleep_until(std::chrono::system_clock::time_point const& t); - protected: /** Called by derived classes to indicate that the stoppable has stopped. */ void @@ -367,20 +360,12 @@ class RootStoppable : public Stoppable return jobCounter_; } - /** Sleep or wake up on stop. - - @return `true` if we are stopping - */ - bool - alertable_sleep_until(std::chrono::system_clock::time_point const& t); - private: // TODO [C++20]: Use std::atomic_flag instead. std::atomic startEntered_{false}; std::atomic startExited_{false}; std::atomic stopEntered_{false}; std::mutex m_; - std::condition_variable c_; JobCounter jobCounter_; }; /** @} */ @@ -393,26 +378,6 @@ Stoppable::jobCounter() return m_root.jobCounter(); } -//------------------------------------------------------------------------------ - -inline bool -RootStoppable::alertable_sleep_until( - std::chrono::system_clock::time_point const& t) -{ - std::unique_lock lock(m_); - if (stopEntered_) - return true; - // TODO [C++20]: When `stopEntered_` is changed to a `std::atomic_flag`, - // this call to `load` needs to change to a call to `test`. - return c_.wait_until(lock, t, [this] { return stopEntered_.load(); }); -} - -inline bool -Stoppable::alertable_sleep_until(std::chrono::system_clock::time_point const& t) -{ - return m_root.alertable_sleep_until(t); -} - } // namespace ripple #endif diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index d0ac20372e4..8bba6b1b2ee 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -159,6 +159,8 @@ RootStoppable::~RootStoppable() bool RootStoppable::isStopping() const { + // TODO [C++20]: When `stopEntered_` is changed to a `std::atomic_flag`, + // this implicit call to `load` needs to change to a call to `test`. return stopEntered_; } @@ -197,7 +199,6 @@ RootStoppable::stop(beast::Journal j) using namespace std::chrono_literals; jobCounter_.join(m_name.c_str(), 1s, j); - c_.notify_all(); stopAsyncRecursive(j); stopRecursive(j); } From 6b5684524ea17df50a007cab49500915db249d28 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 21:51:41 -0600 Subject: [PATCH 03/62] [fold] Call stopped() in LedgerCleanerImp::onStop --- src/ripple/app/ledger/impl/LedgerCleaner.cpp | 34 ++++++-------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index d80913ad7ef..cc3bdc5bde0 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -51,8 +51,8 @@ class LedgerCleanerImp : public LedgerCleaner std::thread thread_; - enum class State : char { readyToClean = 0, startCleaning, cleaning }; - State state_ = State::readyToClean; + enum class State : char { notCleaning = 0, cleaning }; + State state_ = State::notCleaning; bool shouldExit_ = false; // The lowest ledger in the range we're checking. @@ -108,6 +108,7 @@ class LedgerCleanerImp : public LedgerCleaner wakeup_.notify_one(); } thread_.join(); + stopped(); } //-------------------------------------------------------------------------- @@ -214,11 +215,8 @@ class LedgerCleanerImp : public LedgerCleaner if (params.isMember(jss::stop) && params[jss::stop].asBool()) minRange_ = maxRange_ = 0; - if (state_ == State::readyToClean) - { - state_ = State::startCleaning; - wakeup_.notify_one(); - } + state_ = State::cleaning; + wakeup_.notify_one(); } } @@ -228,36 +226,26 @@ class LedgerCleanerImp : public LedgerCleaner // //-------------------------------------------------------------------------- private: - void - init() - { - JLOG(j_.debug()) << "Initializing"; - } - void run() { beast::setCurrentThreadName("LedgerCleaner"); JLOG(j_.debug()) << "Started"; - init(); - while (true) { { std::unique_lock lock(mutex_); + state_ = State::notCleaning; wakeup_.wait(lock, [this]() { - return (shouldExit_ || state_ == State::startCleaning); + return (shouldExit_ || state_ == State::cleaning); }); if (shouldExit_) break; - - state_ = State::cleaning; + assert(state_ == State::cleaning); } doLedgerCleaner(); } - - stopped(); } // VFALCO TODO This should return boost::optional @@ -413,12 +401,11 @@ class LedgerCleanerImp : public LedgerCleaner bool doNodes; bool doTxns; - while (app_.getFeeTrack().isLoadedLocal()) + if (app_.getFeeTrack().isLoadedLocal()) { JLOG(j_.debug()) << "Waiting for load to subside"; std::this_thread::sleep_for(std::chrono::seconds(5)); - if (shouldExit()) - return; + continue; } { @@ -427,7 +414,6 @@ class LedgerCleanerImp : public LedgerCleaner (minRange_ == 0)) { minRange_ = maxRange_ = 0; - state_ = State::readyToClean; return; } ledgerIndex = maxRange_; From 2180d82a076dec02e93813596576bfcab012cd29 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 22:07:05 -0600 Subject: [PATCH 04/62] [fold] Remove Stoppable from base classes of OrderBookDB, LedgerMaster --- src/ripple/app/ledger/LedgerMaster.h | 3 +-- src/ripple/app/ledger/OrderBookDB.cpp | 9 +++------ src/ripple/app/ledger/OrderBookDB.h | 4 ++-- src/ripple/app/ledger/impl/LedgerMaster.cpp | 11 ++++++----- src/ripple/app/main/Application.cpp | 12 ++++++++++-- src/ripple/app/main/Application.h | 2 ++ 6 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index 564870d1edb..0b7bccd16d1 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -69,7 +68,7 @@ class ReportingShouldProxy : public std::runtime_error // Tracks the current ledger and any ledgers in the process of closing // Tracks ledger history // Tracks held transactions -class LedgerMaster : public Stoppable, public AbstractFetchPackContainer +class LedgerMaster : public AbstractFetchPackContainer { public: // Age for last validated ledger if the process has yet to validate. diff --git a/src/ripple/app/ledger/OrderBookDB.cpp b/src/ripple/app/ledger/OrderBookDB.cpp index 98cb306d5b6..a81331d04e8 100644 --- a/src/ripple/app/ledger/OrderBookDB.cpp +++ b/src/ripple/app/ledger/OrderBookDB.cpp @@ -27,11 +27,8 @@ namespace ripple { -OrderBookDB::OrderBookDB(Application& app, Stoppable& parent) - : Stoppable("OrderBookDB", parent) - , app_(app) - , mSeq(0) - , j_(app.journal("OrderBookDB")) +OrderBookDB::OrderBookDB(Application& app) + : app_(app), mSeq(0), j_(app.journal("OrderBookDB")) { } @@ -101,7 +98,7 @@ OrderBookDB::update(std::shared_ptr const& ledger) { for (auto& sle : ledger->sles) { - if (isStopping()) + if (app_.isStopping()) { JLOG(j_.info()) << "OrderBookDB::update exiting due to isStopping"; diff --git a/src/ripple/app/ledger/OrderBookDB.h b/src/ripple/app/ledger/OrderBookDB.h index 4a79bc1293b..a1983fdb40c 100644 --- a/src/ripple/app/ledger/OrderBookDB.h +++ b/src/ripple/app/ledger/OrderBookDB.h @@ -28,10 +28,10 @@ namespace ripple { -class OrderBookDB : public Stoppable +class OrderBookDB { public: - OrderBookDB(Application& app, Stoppable& parent); + OrderBookDB(Application& app); void setup(std::shared_ptr const& ledger); diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index 95f73ac06ee..c8a618d2dfe 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -184,12 +184,13 @@ LedgerMaster::LedgerMaster( Stoppable& parent, beast::insight::Collector::ptr const& collector, beast::Journal journal) - : Stoppable("LedgerMaster", parent) - , app_(app) + : app_(app) , m_journal(journal) , mLedgerHistory(collector, app) - , mLedgerCleaner( - detail::make_LedgerCleaner(app, *this, app_.journal("LedgerCleaner"))) + , mLedgerCleaner(detail::make_LedgerCleaner( + app, + parent, + app_.journal("LedgerCleaner"))) , standalone_(app_.config().standalone()) , fetch_depth_( app_.getSHAMapStore().clampFetchDepth(app_.config().FETCH_DEPTH)) @@ -1557,7 +1558,7 @@ LedgerMaster::newPFWork( } // If we're stopping don't give callers the expectation that their // request will be fulfilled, even if it may be serviced. - return mPathFindThread > 0 && !isStopping(); + return mPathFindThread > 0 && !app_.isStopping(); } std::recursive_mutex& diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index a5ac6e69fbd..0abf383fab6 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -336,7 +336,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp 4, logs_->journal("ShardStore"))) - , m_orderBookDB(*this, *m_jobQueue) + , m_orderBookDB(*this) , m_pathRequests(std::make_unique( *this, @@ -457,7 +457,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::chrono::milliseconds(100), get_io_service()) , grpcServer_(std::make_unique(*this, *m_jobQueue)) - , reportingETL_(std::make_unique(*this, *m_ledgerMaster)) + , reportingETL_(std::make_unique(*this, *this)) { add(m_resourceManager.get()); @@ -498,6 +498,8 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp checkSigs() const override; void checkSigs(bool) override; + bool + isStopping() const override; int fdRequired() const override; @@ -1768,6 +1770,12 @@ ApplicationImp::checkSigs(bool check) checkSigs_ = check; } +bool +ApplicationImp::isStopping() const +{ + return Stoppable::isStopping(); +} + int ApplicationImp::fdRequired() const { diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h index 59633a05bb2..af90570a797 100644 --- a/src/ripple/app/main/Application.h +++ b/src/ripple/app/main/Application.h @@ -135,6 +135,8 @@ class Application : public beast::PropertyStream::Source checkSigs() const = 0; virtual void checkSigs(bool) = 0; + virtual bool + isStopping() const = 0; // // --- From e8f8d04238232187860124744209ab6670a37bff Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 22:11:22 -0600 Subject: [PATCH 05/62] [fold] Call stopped() in SHAMapStoreImp::onStop --- src/ripple/app/misc/SHAMapStoreImp.cpp | 15 ++++----------- src/ripple/app/misc/SHAMapStoreImp.h | 11 ----------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index a85fd8046fd..39612aa051c 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -359,7 +359,6 @@ SHAMapStoreImp::run() rendezvous_.notify_all(); if (stop_) { - stopped(); return; } cond_.wait(lock); @@ -759,22 +758,16 @@ SHAMapStoreImp::health() void SHAMapStoreImp::onStop() { - // This is really a check for `if (thread_)`. - if (deleteInterval_) + if (thread_.joinable()) { { std::lock_guard lock(mutex_); stop_ = true; + cond_.notify_one(); } - cond_.notify_one(); - // stopped() will be called by the thread_ running run(), - // when it reaches the check for stop_. - } - else - { - // There is no thread running run(), so we must call stopped(). - stopped(); + thread_.join(); } + stopped(); } boost::optional diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h index 062b90dde6d..f325822e2a2 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.h +++ b/src/ripple/app/misc/SHAMapStoreImp.h @@ -135,12 +135,6 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore NodeStore::Scheduler& scheduler, beast::Journal journal); - ~SHAMapStoreImp() - { - if (thread_.joinable()) - thread_.join(); - } - std::uint32_t clampFetchDepth(std::uint32_t fetch_depth) const override { @@ -248,9 +242,6 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore Health health(); - // - // Stoppable - // void onStart() override { @@ -258,10 +249,8 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore thread_ = std::thread(&SHAMapStoreImp::run, this); } - // Called when the application begins shutdown void onStop() override; - // Called when all child Stoppable objects have stoped }; } // namespace ripple From 02828489fbb374b26070e9d36b2d9b95ba4b5592 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 22:33:48 -0600 Subject: [PATCH 06/62] [fold] Call stopped() in NodeStore::Database::onStop --- src/ripple/nodestore/Database.h | 3 --- src/ripple/nodestore/impl/Database.cpp | 5 ----- 2 files changed, 8 deletions(-) diff --git a/src/ripple/nodestore/Database.h b/src/ripple/nodestore/Database.h index da0677292ce..ec7effa9801 100644 --- a/src/ripple/nodestore/Database.h +++ b/src/ripple/nodestore/Database.h @@ -228,9 +228,6 @@ class Database : public Stoppable void onStop() override; - void - onChildrenStopped() override; - /** @return The earliest ledger sequence allowed */ std::uint32_t diff --git a/src/ripple/nodestore/impl/Database.cpp b/src/ripple/nodestore/impl/Database.cpp index 579443ace8f..b2e734d5c59 100644 --- a/src/ripple/nodestore/impl/Database.cpp +++ b/src/ripple/nodestore/impl/Database.cpp @@ -66,11 +66,6 @@ Database::onStop() // After stop time we can no longer use the JobQueue for background // reads. Join the background read threads. stopReadThreads(); -} - -void -Database::onChildrenStopped() -{ stopped(); } From 50a99674bd0d96aba6553832033c4feca5f29d29 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 29 Dec 2020 23:12:16 -0600 Subject: [PATCH 07/62] [fold] NodeStoreScheduler is not a Stoppable Make JobQueue a child Stoppable of ApplicationImp. --- src/ripple/app/main/Application.cpp | 38 +++++++++--------- src/ripple/app/main/NodeStoreScheduler.cpp | 45 +++------------------- src/ripple/app/main/NodeStoreScheduler.h | 24 ++---------- 3 files changed, 28 insertions(+), 79 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 0abf383fab6..21713cd5312 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -167,6 +167,9 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp #ifdef RIPPLED_REPORTING std::shared_ptr pgPool_; #endif + + std::unique_ptr m_collectorManager; + std::unique_ptr m_jobQueue; NodeStoreScheduler m_nodeStoreScheduler; std::unique_ptr m_shaMapStore; PendingSaves pendingSaves_; @@ -175,7 +178,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // These are not Stoppable-derived NodeCache m_tempNodeCache; - std::unique_ptr m_collectorManager; CachedSLEs cachedSLEs_; std::pair nodeIdentity_; ValidatorKeys const validatorKeys_; @@ -183,7 +185,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::unique_ptr m_resourceManager; // These are Stoppable-related - std::unique_ptr m_jobQueue; std::unique_ptr m_nodeStore; NodeFamily nodeFamily_; std::unique_ptr shardStore_; @@ -288,7 +289,22 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp : nullptr) #endif - , m_nodeStoreScheduler(*this) + , m_collectorManager(CollectorManager::New( + config_->section(SECTION_INSIGHT), + logs_->journal("Collector"))) + + // The JobQueue has to come pretty early since + // almost everything is a Stoppable child of the JobQueue. + // + , m_jobQueue(std::make_unique( + m_collectorManager->group("jobq"), + *this, + logs_->journal("JobQueue"), + *logs_, + *perfLog_)) + + , m_nodeStoreScheduler(*m_jobQueue) + , m_shaMapStore(make_SHAMapStore( *this, *this, @@ -304,9 +320,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp stopwatch(), logs_->journal("TaggedCache")) - , m_collectorManager(CollectorManager::New( - config_->section(SECTION_INSIGHT), - logs_->journal("Collector"))) , cachedSLEs_(std::chrono::minutes(1), stopwatch()) , validatorKeys_(*config_, m_journal) @@ -314,16 +327,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp m_collectorManager->collector(), logs_->journal("Resource"))) - // The JobQueue has to come pretty early since - // almost everything is a Stoppable child of the JobQueue. - // - , m_jobQueue(std::make_unique( - m_collectorManager->group("jobq"), - m_nodeStoreScheduler, - logs_->journal("JobQueue"), - *logs_, - *perfLog_)) - , m_nodeStore(m_shaMapStore->makeNodeStore("NodeStore.main", 4)) , nodeFamily_(*this, *m_collectorManager) @@ -476,9 +479,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // started in this constructor. // - // VFALCO HACK - m_nodeStoreScheduler.setJobQueue(*m_jobQueue); - add(m_ledgerMaster->getPropertySource()); } diff --git a/src/ripple/app/main/NodeStoreScheduler.cpp b/src/ripple/app/main/NodeStoreScheduler.cpp index 9d7fc225331..d1bab68b5a0 100644 --- a/src/ripple/app/main/NodeStoreScheduler.cpp +++ b/src/ripple/app/main/NodeStoreScheduler.cpp @@ -22,59 +22,24 @@ namespace ripple { -NodeStoreScheduler::NodeStoreScheduler(Stoppable& parent) - : Stoppable("NodeStoreScheduler", parent) +NodeStoreScheduler::NodeStoreScheduler(JobQueue& jobQueue) + : m_jobQueue(&jobQueue) { } -void -NodeStoreScheduler::setJobQueue(JobQueue& jobQueue) -{ - m_jobQueue = &jobQueue; -} - -void -NodeStoreScheduler::onStop() -{ -} - -void -NodeStoreScheduler::onChildrenStopped() -{ - assert(m_taskCount == 0); - stopped(); -} - void NodeStoreScheduler::scheduleTask(NodeStore::Task& task) { - ++m_taskCount; - if (!m_jobQueue->addJob(jtWRITE, "NodeObject::store", [this, &task](Job&) { - doTask(task); + if (!m_jobQueue->addJob(jtWRITE, "NodeObject::store", [&task](Job&) { + task.performScheduledTask(); })) { // Job not added, presumably because we're shutting down. // Recover by executing the task synchronously. - doTask(task); + task.performScheduledTask(); } } -void -NodeStoreScheduler::doTask(NodeStore::Task& task) -{ - task.performScheduledTask(); - - // NOTE: It feels a bit off that there are two different methods that - // call stopped(): onChildrenStopped() and doTask(). There's a - // suspicion that, as long as the Stoppable tree is configured - // correctly, this call to stopped() in doTask() can never occur. - // - // However, until we increase our confidence that the suspicion is - // correct, we will leave this code in place. - if ((--m_taskCount == 0) && isStopping() && areChildrenStopped()) - stopped(); -} - void NodeStoreScheduler::onFetch(NodeStore::FetchReport const& report) { diff --git a/src/ripple/app/main/NodeStoreScheduler.h b/src/ripple/app/main/NodeStoreScheduler.h index b37f3c3e78e..6073be760cf 100644 --- a/src/ripple/app/main/NodeStoreScheduler.h +++ b/src/ripple/app/main/NodeStoreScheduler.h @@ -21,29 +21,17 @@ #define RIPPLE_APP_MAIN_NODESTORESCHEDULER_H_INCLUDED #include -#include #include #include namespace ripple { -/** A NodeStore::Scheduler which uses the JobQueue and implements the Stoppable - * API. */ -class NodeStoreScheduler : public NodeStore::Scheduler, public Stoppable +/** A NodeStore::Scheduler which uses the JobQueue. */ +class NodeStoreScheduler : public NodeStore::Scheduler { public: - NodeStoreScheduler(Stoppable& parent); + NodeStoreScheduler(JobQueue& jobQueue); - // VFALCO NOTE This is a temporary hack to solve the problem - // of circular dependency. - // - void - setJobQueue(JobQueue& jobQueue); - - void - onStop() override; - void - onChildrenStopped() override; void scheduleTask(NodeStore::Task& task) override; void @@ -52,11 +40,7 @@ class NodeStoreScheduler : public NodeStore::Scheduler, public Stoppable onBatchWrite(NodeStore::BatchWriteReport const& report) override; private: - void - doTask(NodeStore::Task& task); - - JobQueue* m_jobQueue{nullptr}; - std::atomic m_taskCount{0}; + JobQueue* m_jobQueue; }; } // namespace ripple From 9af6acc7a208835b9199d9c2e0857056cb39a2c0 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 14:37:30 -0600 Subject: [PATCH 08/62] [fold] Call stopped() in ServerHandlerImp::onStop --- src/ripple/rpc/impl/ServerHandlerImp.cpp | 21 ++++++++++++++++----- src/ripple/rpc/impl/ServerHandlerImp.h | 5 ++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index fd709507ddd..6c8da851484 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include namespace ripple { @@ -141,6 +142,11 @@ void ServerHandlerImp::onStop() { m_server->close(); + { + std::unique_lock lock(mutex_); + condition_.wait(lock, [this]() { return stopped_; }); + } + stopped(); } //------------------------------------------------------------------------------ @@ -150,11 +156,14 @@ ServerHandlerImp::onAccept( Session& session, boost::asio::ip::tcp::endpoint endpoint) { - std::lock_guard lock(countlock_); + auto const& port = session.port(); - auto const c = ++count_[session.port()]; + auto const c = [this, &port]() { + std::lock_guard lock(mutex_); + return ++count_[port]; + }(); - if (session.port().limit && c >= session.port().limit) + if (port.limit && c >= port.limit) { JLOG(m_journal.trace()) << session.port().name << " is full; dropping " << endpoint; @@ -357,14 +366,16 @@ ServerHandlerImp::onWSMessage( void ServerHandlerImp::onClose(Session& session, boost::system::error_code const&) { - std::lock_guard lock(countlock_); + std::lock_guard lock(mutex_); --count_[session.port()]; } void ServerHandlerImp::onStopped(Server&) { - stopped(); + std::lock_guard lock(mutex_); + stopped_ = true; + condition_.notify_one(); } //------------------------------------------------------------------------------ diff --git a/src/ripple/rpc/impl/ServerHandlerImp.h b/src/ripple/rpc/impl/ServerHandlerImp.h index 49301cb07c5..7e8228c70c8 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.h +++ b/src/ripple/rpc/impl/ServerHandlerImp.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,9 @@ class ServerHandlerImp : public Stoppable beast::insight::Counter rpc_requests_; beast::insight::Event rpc_size_; beast::insight::Event rpc_time_; - std::mutex countlock_; + std::mutex mutex_; + std::condition_variable condition_; + bool stopped_{false}; std::map, int> count_; public: From 1bb43f72050f88de078a4b15db286b34141b7175 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 16:53:58 -0600 Subject: [PATCH 09/62] [fold] Stop NodeStore::TaskQueue from NodeStore::DatabaseShardImp::onStop --- .../nodestore/impl/DatabaseShardImp.cpp | 21 +++++++++---------- src/ripple/nodestore/impl/DatabaseShardImp.h | 2 +- src/ripple/nodestore/impl/TaskQueue.cpp | 14 ++++++------- src/ripple/nodestore/impl/TaskQueue.h | 6 +++--- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index 838e616653f..50f61e43ff3 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -55,7 +55,6 @@ DatabaseShardImp::DatabaseShardImp( j) , app_(app) , parent_(parent) - , taskQueue_(std::make_unique(*this)) , earliestShardIndex_(seqToShardIndex(earliestLedgerSeq())) , avgShardFileSz_(ledgersPerShard_ * kilobytes(192ull)) , openFinalLimit_( @@ -700,12 +699,12 @@ DatabaseShardImp::onStop() { // Stop read threads in base before data members are destroyed stopReadThreads(); - - std::lock_guard lock(mutex_); - - // Notify shards to stop - for (auto const& e : shards_) - e.second->stop(); + { + std::lock_guard lock(mutex_); + for (auto const& [_, shard] : shards_) + shard->stop(); + } + taskQueue_.stop(); } void @@ -1292,10 +1291,10 @@ DatabaseShardImp::finalizeShard( bool writeSQLite, boost::optional const& expectedHash) { - taskQueue_->addTask([this, - wptr = std::weak_ptr(shard), - writeSQLite, - expectedHash]() { + taskQueue_.addTask([this, + wptr = std::weak_ptr(shard), + writeSQLite, + expectedHash]() { if (isStopping()) return; diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.h b/src/ripple/nodestore/impl/DatabaseShardImp.h index 4bb0ae2021f..3db660d14f3 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.h +++ b/src/ripple/nodestore/impl/DatabaseShardImp.h @@ -179,7 +179,7 @@ class DatabaseShardImp : public DatabaseShard std::unique_ptr ctx_; // Queue of background tasks to be performed - std::unique_ptr taskQueue_; + TaskQueue taskQueue_; // Shards held by this server std::unordered_map> shards_; diff --git a/src/ripple/nodestore/impl/TaskQueue.cpp b/src/ripple/nodestore/impl/TaskQueue.cpp index 000b664b0b7..d069307dcd2 100644 --- a/src/ripple/nodestore/impl/TaskQueue.cpp +++ b/src/ripple/nodestore/impl/TaskQueue.cpp @@ -24,25 +24,23 @@ namespace ripple { namespace NodeStore { -TaskQueue::TaskQueue(Stoppable& parent) - : Stoppable("TaskQueue", parent) - , workers_(*this, nullptr, "Shard store taskQueue", 1) +TaskQueue::TaskQueue() : workers_(*this, nullptr, "Shard store taskQueue", 1) { } void -TaskQueue::onStop() +TaskQueue::stop() { workers_.pauseAllThreadsAndWait(); - stopped(); } void TaskQueue::addTask(std::function task) { - std::lock_guard lock{mutex_}; - - tasks_.emplace(std::move(task)); + { + std::lock_guard lock{mutex_}; + tasks_.emplace(std::move(task)); + } workers_.addTask(); } diff --git a/src/ripple/nodestore/impl/TaskQueue.h b/src/ripple/nodestore/impl/TaskQueue.h index 9f2121a4506..bb079ad2f16 100644 --- a/src/ripple/nodestore/impl/TaskQueue.h +++ b/src/ripple/nodestore/impl/TaskQueue.h @@ -29,13 +29,13 @@ namespace ripple { namespace NodeStore { -class TaskQueue : public Stoppable, private Workers::Callback +class TaskQueue : private Workers::Callback { public: - explicit TaskQueue(Stoppable& parent); + TaskQueue(); void - onStop() override; + stop(); /** Adds a task to the queue From 94c830c446e11d71702ec88dbfba655788a4212c Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 20:49:34 -0600 Subject: [PATCH 10/62] [fold] Move JobCounter from RootStoppable to JobQueue Call stopped() in JobQueue::onStop. --- src/ripple/app/ledger/LedgerMaster.h | 1 + src/ripple/core/Job.h | 3 ++ src/ripple/core/JobQueue.h | 21 ++++++-------- src/ripple/core/Stoppable.h | 27 +----------------- src/ripple/core/impl/JobQueue.cpp | 42 ++++++++++------------------ src/ripple/core/impl/Stoppable.cpp | 10 ------- src/ripple/rpc/ShardArchiveHandler.h | 1 + src/test/core/JobQueue_test.cpp | 12 +++----- 8 files changed, 33 insertions(+), 84 deletions(-) diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index 0b7bccd16d1..7f4e330eb3d 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ripple/core/Job.h b/src/ripple/core/Job.h index df53ae8bda0..49cdadfe0cd 100644 --- a/src/ripple/core/Job.h +++ b/src/ripple/core/Job.h @@ -20,6 +20,7 @@ #ifndef RIPPLE_CORE_JOB_H_INCLUDED #define RIPPLE_CORE_JOB_H_INCLUDED +#include #include #include @@ -155,6 +156,8 @@ class Job clock_type::time_point m_queue_time; }; +using JobCounter = ClosureCounter; + } // namespace ripple #endif diff --git a/src/ripple/core/JobQueue.h b/src/ripple/core/JobQueue.h index 6c14b117dbb..f382bc8463d 100644 --- a/src/ripple/core/JobQueue.h +++ b/src/ripple/core/JobQueue.h @@ -21,6 +21,7 @@ #define RIPPLE_CORE_JOBQUEUE_H_INCLUDED #include +#include #include #include #include @@ -165,8 +166,8 @@ class JobQueue : public Stoppable, private Workers::Callback bool addJob(JobType type, std::string const& name, JobHandler&& jobHandler) { - if (auto optionalCountedJob = Stoppable::jobCounter().wrap( - std::forward(jobHandler))) + if (auto optionalCountedJob = + jobCounter_.wrap(std::forward(jobHandler))) { return addRefCountedJob(type, name, std::move(*optionalCountedJob)); } @@ -224,10 +225,13 @@ class JobQueue : public Stoppable, private Workers::Callback Json::Value getJson(int c = 0); - /** Block until no tasks running. */ + /** Block until no jobs running. */ void rendezvous(); + void + onStop() override; + private: friend class Coro; @@ -237,6 +241,7 @@ class JobQueue : public Stoppable, private Workers::Callback mutable std::mutex m_mutex; std::uint64_t m_lastJob; std::set m_jobSet; + JobCounter jobCounter_; JobDataMap m_jobData; JobTypeData m_invalidJobData; @@ -262,13 +267,6 @@ class JobQueue : public Stoppable, private Workers::Callback JobTypeData& getJobTypeData(JobType type); - void - onStop() override; - - // Signals the service stopped if the stopped condition is met. - void - checkStopped(std::lock_guard const& lock); - // Adds a reference counted job to the JobQueue. // // param type The type of job. @@ -354,9 +352,6 @@ class JobQueue : public Stoppable, private Workers::Callback // will be enough. int getJobLimit(JobType type); - - void - onChildrenStopped() override; }; /* diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index 1d92b2099d1..265ab468342 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -22,8 +22,6 @@ #include #include -#include -#include #include #include #include @@ -31,9 +29,6 @@ namespace ripple { -// Give a reasonable name for the JobCounter -using JobCounter = ClosureCounter; - class RootStoppable; /** Provides an interface for starting and stopping. @@ -221,10 +216,6 @@ class Stoppable bool areChildrenStopped() const; - /* JobQueue uses this method for Job counting. */ - inline JobCounter& - jobCounter(); - protected: /** Called by derived classes to indicate that the stoppable has stopped. */ void @@ -321,7 +312,7 @@ class RootStoppable : public Stoppable public: explicit RootStoppable(std::string name); - virtual ~RootStoppable(); + virtual ~RootStoppable() = default; bool isStopping() const; @@ -353,31 +344,15 @@ class RootStoppable : public Stoppable return startExited_; } - /* JobQueue uses this method for Job counting. */ - JobCounter& - jobCounter() - { - return jobCounter_; - } - private: // TODO [C++20]: Use std::atomic_flag instead. std::atomic startEntered_{false}; std::atomic startExited_{false}; std::atomic stopEntered_{false}; std::mutex m_; - JobCounter jobCounter_; }; /** @} */ -//------------------------------------------------------------------------------ - -JobCounter& -Stoppable::jobCounter() -{ - return m_root.jobCounter(); -} - } // namespace ripple #endif diff --git a/src/ripple/core/impl/JobQueue.cpp b/src/ripple/core/impl/JobQueue.cpp index 8f1dbff31f5..0f41273c1f8 100644 --- a/src/ripple/core/impl/JobQueue.cpp +++ b/src/ripple/core/impl/JobQueue.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace ripple { @@ -298,26 +299,21 @@ JobQueue::getJobTypeData(JobType type) void JobQueue::onStop() { - // onStop must be defined and empty here, - // otherwise the base class will do the wrong thing. -} - -void -JobQueue::checkStopped(std::lock_guard const& lock) -{ - // We are stopped when all of the following are true: - // - // 1. A stop notification was received - // 2. All Stoppable children have stopped - // 3. There are no executing calls to processTask - // 4. There are no remaining Jobs in the job set - // 5. There are no suspended coroutines - // - if (isStopping() && areChildrenStopped() && (m_processCount == 0) && - m_jobSet.empty() && nSuspend_ == 0) + using namespace std::chrono_literals; + jobCounter_.join("JobQueue", 1s, m_journal); { - stopped(); + // After the JobCounter is joined, all jobs have finished executing + // (i.e. returned from `Job::doJob`) and no more are being accepted, + // but there may still be some threads between the return of + // `Job::doJob` and the return of `JobQueue::processTask`. That is why + // we must wait on the condition variable to make these assertions. + std::unique_lock lock(m_mutex); + cv_.wait(lock, [&] { return m_processCount == 0 && m_jobSet.empty(); }); + assert(m_processCount == 0); + assert(m_jobSet.empty()); + assert(nSuspend_ == 0); } + stopped(); } void @@ -437,13 +433,12 @@ JobQueue::processTask(int instance) { std::lock_guard lock(m_mutex); - // Job should be destroyed before calling checkStopped + // Job should be destroyed before calling stopped() // otherwise destructors with side effects can access // parent objects that are already destroyed. finishJob(type); if (--m_processCount == 0 && m_jobSet.empty()) cv_.notify_all(); - checkStopped(lock); } // Note that when Job::~Job is called, the last reference @@ -459,11 +454,4 @@ JobQueue::getJobLimit(JobType type) return j.limit(); } -void -JobQueue::onChildrenStopped() -{ - std::lock_guard lock(m_mutex); - checkStopped(lock); -} - } // namespace ripple diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index 8bba6b1b2ee..7d45b0e248a 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -150,12 +150,6 @@ RootStoppable::RootStoppable(std::string name) { } -RootStoppable::~RootStoppable() -{ - using namespace std::chrono_literals; - jobCounter_.join(m_name.c_str(), 1s, debugLog()); -} - bool RootStoppable::isStopping() const { @@ -195,10 +189,6 @@ RootStoppable::stop(beast::Journal j) return; } - // Wait until all in-flight JobQueue Jobs are completed. - using namespace std::chrono_literals; - jobCounter_.join(m_name.c_str(), 1s, j); - stopAsyncRecursive(j); stopRecursive(j); } diff --git a/src/ripple/rpc/ShardArchiveHandler.h b/src/ripple/rpc/ShardArchiveHandler.h index 2e2133bc242..c3566a2c71e 100644 --- a/src/ripple/rpc/ShardArchiveHandler.h +++ b/src/ripple/rpc/ShardArchiveHandler.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/src/test/core/JobQueue_test.cpp b/src/test/core/JobQueue_test.cpp index 2e85cebe24d..987f986ebe9 100644 --- a/src/test/core/JobQueue_test.cpp +++ b/src/test/core/JobQueue_test.cpp @@ -47,13 +47,11 @@ class JobQueue_test : public beast::unit_test::suite ; } { - // If the JobQueue's JobCounter is join()ed we should no + // If the JobQueue is stopped, we should no // longer be able to add Jobs (and calling addJob() should // return false). using namespace std::chrono_literals; - beast::Journal j{env.app().journal("JobQueue_test")}; - JobCounter& jCounter = jQueue.jobCounter(); - jCounter.join("JobQueue_test", 1s, j); + jQueue.onStop(); // The Job should never run, so having the Job access this // unprotected variable on the stack should be completely safe. @@ -132,13 +130,11 @@ class JobQueue_test : public beast::unit_test::suite BEAST_EXPECT(yieldCount == 4); } { - // If the JobQueue's JobCounter is join()ed we should no + // If the JobQueue is stopped, we should no // longer be able to add a Coro (and calling postCoro() should // return false). using namespace std::chrono_literals; - beast::Journal j{env.app().journal("JobQueue_test")}; - JobCounter& jCounter = jQueue.jobCounter(); - jCounter.join("JobQueue_test", 1s, j); + jQueue.onStop(); // The Coro should never run, so having the Coro access this // unprotected variable on the stack should be completely safe. From ef7d96858a315fb04b89c824a91360129069c2f2 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 21:28:52 -0600 Subject: [PATCH 11/62] [fold] Call stopped() in OverlayImpl::onStop --- src/ripple/overlay/impl/OverlayImpl.cpp | 35 +++++-------------------- src/ripple/overlay/impl/OverlayImpl.h | 5 ---- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 232273a68f2..709874289fc 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -158,19 +158,6 @@ OverlayImpl::OverlayImpl( beast::PropertyStream::Source::add(m_peerFinder.get()); } -OverlayImpl::~OverlayImpl() -{ - stop(); - - // Block until dependent objects have been destroyed. - // This is just to catch improper use of the Stoppable API. - // - std::unique_lock lock(mutex_); - cond_.wait(lock, [this] { return list_.empty(); }); -} - -//------------------------------------------------------------------------------ - Handoff OverlayImpl::onHandoff( std::unique_ptr&& stream_ptr, @@ -485,14 +472,6 @@ OverlayImpl::remove(std::shared_ptr const& slot) // //------------------------------------------------------------------------------ -// Caller must hold the mutex -void -OverlayImpl::checkStopped() -{ - if (isStopping() && areChildrenStopped() && list_.empty()) - stopped(); -} - void OverlayImpl::onStart() { @@ -578,13 +557,11 @@ void OverlayImpl::onStop() { strand_.dispatch(std::bind(&OverlayImpl::stop, this)); -} - -void -OverlayImpl::onChildrenStopped() -{ - std::lock_guard lock(mutex_); - checkStopped(); + { + std::unique_lock lock(mutex_); + cond_.wait(lock, [this] { return list_.empty(); }); + } + stopped(); } //------------------------------------------------------------------------------ @@ -1302,7 +1279,7 @@ OverlayImpl::remove(Child& child) std::lock_guard lock(mutex_); list_.erase(&child); if (list_.empty()) - checkStopped(); + cond_.notify_all(); } void diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index 783c0a9078b..4b0f18cef5b 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -149,8 +149,6 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler BasicConfig const& config, beast::insight::Collector::ptr const& collector); - ~OverlayImpl(); - OverlayImpl(OverlayImpl const&) = delete; OverlayImpl& operator=(OverlayImpl const&) = delete; @@ -513,9 +511,6 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler void onStop() override; - void - onChildrenStopped() override; - // // PropertyStream // From c27f4409bd8cffb9952ea0d7e538f95c208da849 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 21:45:10 -0600 Subject: [PATCH 12/62] [fold] Call stopped() in NodeStore::DatabaseShardImp::onStop --- src/ripple/nodestore/impl/DatabaseShardImp.cpp | 4 ---- src/ripple/nodestore/impl/DatabaseShardImp.h | 3 --- 2 files changed, 7 deletions(-) diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index 50f61e43ff3..c48c185ba06 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -705,11 +705,7 @@ DatabaseShardImp::onStop() shard->stop(); } taskQueue_.stop(); -} -void -DatabaseShardImp::onChildrenStopped() -{ std::vector> shards; { std::lock_guard lock(mutex_); diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.h b/src/ripple/nodestore/impl/DatabaseShardImp.h index 3db660d14f3..139db7ece4f 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.h +++ b/src/ripple/nodestore/impl/DatabaseShardImp.h @@ -126,9 +126,6 @@ class DatabaseShardImp : public DatabaseShard void onStop() override; - void - onChildrenStopped() override; - /** Import the application local node store @param source The application node store. From aad8a32a156a23248f23275b77eb2cf2e8b0a58e Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 21:52:24 -0600 Subject: [PATCH 13/62] [fold] Call stopped() in PerfLogImp::onStop --- src/ripple/basics/impl/PerfLogImp.cpp | 5 ----- src/ripple/basics/impl/PerfLogImp.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/ripple/basics/impl/PerfLogImp.cpp b/src/ripple/basics/impl/PerfLogImp.cpp index f3bb986d254..c24ac3e0fe8 100644 --- a/src/ripple/basics/impl/PerfLogImp.cpp +++ b/src/ripple/basics/impl/PerfLogImp.cpp @@ -477,11 +477,6 @@ PerfLogImp::onStop() } thread_.join(); } -} - -void -PerfLogImp::onChildrenStopped() -{ stopped(); } diff --git a/src/ripple/basics/impl/PerfLogImp.h b/src/ripple/basics/impl/PerfLogImp.h index 8fa430ec164..d648e460d3a 100644 --- a/src/ripple/basics/impl/PerfLogImp.h +++ b/src/ripple/basics/impl/PerfLogImp.h @@ -216,9 +216,6 @@ class PerfLogImp : public PerfLog, Stoppable // Called when the application begins shutdown. void onStop() override; - // Called when all child Stoppable objects have stopped. - void - onChildrenStopped() override; }; } // namespace perf From 59557fe1833a4f4d187c535a162f2c56453cd351 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 22:28:36 -0600 Subject: [PATCH 14/62] [fold] Remove Stoppable::{stopped,onChildrenStopped} --- src/ripple/app/ledger/impl/InboundLedgers.cpp | 2 - .../app/ledger/impl/InboundTransactions.cpp | 2 - src/ripple/app/ledger/impl/LedgerCleaner.cpp | 1 - src/ripple/app/ledger/impl/LedgerMaster.cpp | 2 +- src/ripple/app/main/Application.cpp | 16 +-- src/ripple/app/main/Application.h | 2 - src/ripple/app/main/GRPCServer.cpp | 2 - src/ripple/app/main/LoadManager.cpp | 1 - src/ripple/app/misc/NetworkOPs.cpp | 4 +- src/ripple/app/misc/SHAMapStoreImp.cpp | 5 - src/ripple/app/reporting/ReportingETL.h | 1 - src/ripple/basics/impl/PerfLogImp.cpp | 1 - src/ripple/core/JobQueue.h | 6 + src/ripple/core/Pg.cpp | 1 - src/ripple/core/Stoppable.h | 105 ++---------------- src/ripple/core/impl/JobQueue.cpp | 30 ++--- src/ripple/core/impl/Stoppable.cpp | 60 ---------- src/ripple/nodestore/impl/Database.cpp | 1 - .../nodestore/impl/DatabaseShardImp.cpp | 2 - src/ripple/overlay/impl/OverlayImpl.cpp | 1 - .../peerfinder/impl/PeerfinderManager.cpp | 1 - src/ripple/rpc/impl/ServerHandlerImp.cpp | 1 - src/ripple/rpc/impl/ShardArchiveHandler.cpp | 2 - src/test/basics/PerfLog_test.cpp | 8 -- src/test/core/Stoppable_test.cpp | 99 ++--------------- 25 files changed, 35 insertions(+), 321 deletions(-) diff --git a/src/ripple/app/ledger/impl/InboundLedgers.cpp b/src/ripple/app/ledger/impl/InboundLedgers.cpp index fa8cc9d17cf..1d7ff081bac 100644 --- a/src/ripple/app/ledger/impl/InboundLedgers.cpp +++ b/src/ripple/app/ledger/impl/InboundLedgers.cpp @@ -388,8 +388,6 @@ class InboundLedgersImp : public InboundLedgers, public Stoppable mLedgers.clear(); mRecentFailures.clear(); - - stopped(); } private: diff --git a/src/ripple/app/ledger/impl/InboundTransactions.cpp b/src/ripple/app/ledger/impl/InboundTransactions.cpp index db67f1738b6..f3819bb1d8d 100644 --- a/src/ripple/app/ledger/impl/InboundTransactions.cpp +++ b/src/ripple/app/ledger/impl/InboundTransactions.cpp @@ -244,8 +244,6 @@ class InboundTransactionsImp : public InboundTransactions, public Stoppable std::lock_guard lock(mLock); m_map.clear(); - - stopped(); } private: diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index cc3bdc5bde0..ddd6f5d4202 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -108,7 +108,6 @@ class LedgerCleanerImp : public LedgerCleaner wakeup_.notify_one(); } thread_.join(); - stopped(); } //-------------------------------------------------------------------------- diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index c8a618d2dfe..59517a81858 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -732,7 +732,7 @@ LedgerMaster::tryFill(Job& job, std::shared_ptr ledger) if (it == ledgerHashes.end()) { - if (app_.isShutdown()) + if (app_.isStopping()) return; { diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 21713cd5312..fa42b6525c5 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -490,8 +490,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp doStart(bool withTimers) override; void run() override; - bool - isShutdown() override; void signalStop() override; bool @@ -1111,8 +1109,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp [this](PublicKey const& pubKey) { return validators().trustedPublisher(pubKey); }); - - stopped(); } //-------------------------------------------------------------------------- @@ -1133,8 +1129,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // Only start the timer if waitHandlerCounter_ is not yet joined. if (auto optionalCountedHandler = waitHandlerCounter_.wrap( [this](boost::system::error_code const& e) { - if ((e.value() == boost::system::errc::success) && - (!m_jobQueue->isStopped())) + if (e.value() == boost::system::errc::success) { m_jobQueue->addJob( jtSWEEP, "sweep", [this](Job&) { doSweep(); }); @@ -1751,13 +1746,6 @@ ApplicationImp::signalStop() } } -bool -ApplicationImp::isShutdown() -{ - // from Stoppable mixin - return isStopped(); -} - bool ApplicationImp::checkSigs() const { @@ -2186,7 +2174,7 @@ ApplicationImp::serverOkay(std::string& reason) if (!config().ELB_SUPPORT) return true; - if (isShutdown()) + if (isStopping()) { reason = "Server is shutting down"; return false; diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h index af90570a797..42553677567 100644 --- a/src/ripple/app/main/Application.h +++ b/src/ripple/app/main/Application.h @@ -127,8 +127,6 @@ class Application : public beast::PropertyStream::Source doStart(bool withTimers) = 0; virtual void run() = 0; - virtual bool - isShutdown() = 0; virtual void signalStop() = 0; virtual bool diff --git a/src/ripple/app/main/GRPCServer.cpp b/src/ripple/app/main/GRPCServer.cpp index 6c2983ebea8..b0dddc92d01 100644 --- a/src/ripple/app/main/GRPCServer.cpp +++ b/src/ripple/app/main/GRPCServer.cpp @@ -797,8 +797,6 @@ GRPCServer::onStop() thread_.join(); running_ = false; } - - stopped(); } GRPCServer::~GRPCServer() diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index 631ae76846a..f9140eb010e 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -99,7 +99,6 @@ LoadManager::onStop() JLOG(journal_.debug()) << "Stopping"; thread_.join(); } - stopped(); } //------------------------------------------------------------------------------ diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp index bc8bfda8c51..9e5c36df3b7 100644 --- a/src/ripple/app/misc/NetworkOPs.cpp +++ b/src/ripple/app/misc/NetworkOPs.cpp @@ -637,11 +637,9 @@ class NetworkOPsImp final : public NetworkOPs << ec.message(); } } - // Make sure that any waitHandlers pending in our timers are done - // before we declare ourselves stopped. + // Make sure that any waitHandlers pending in our timers are done. using namespace std::chrono_literals; waitHandlerCounter_.join("NetworkOPs", 1s, m_journal); - stopped(); } private: diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index 39612aa051c..98bfd469389 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -392,7 +392,6 @@ SHAMapStoreImp::run() switch (health()) { case Health::stopping: - stopped(); return; case Health::unhealthy: continue; @@ -410,7 +409,6 @@ SHAMapStoreImp::run() switch (health()) { case Health::stopping: - stopped(); return; case Health::unhealthy: continue; @@ -426,7 +424,6 @@ SHAMapStoreImp::run() switch (health()) { case Health::stopping: - stopped(); return; case Health::unhealthy: continue; @@ -445,7 +442,6 @@ SHAMapStoreImp::run() switch (health()) { case Health::stopping: - stopped(); return; case Health::unhealthy: continue; @@ -767,7 +763,6 @@ SHAMapStoreImp::onStop() } thread_.join(); } - stopped(); } boost::optional diff --git a/src/ripple/app/reporting/ReportingETL.h b/src/ripple/app/reporting/ReportingETL.h index 0452b413ee7..ddd70cbea31 100644 --- a/src/ripple/app/reporting/ReportingETL.h +++ b/src/ripple/app/reporting/ReportingETL.h @@ -350,7 +350,6 @@ class ReportingETL : Stoppable worker_.join(); JLOG(journal_.debug()) << "Joined worker thread"; - stopped(); } ETLLoadBalancer& diff --git a/src/ripple/basics/impl/PerfLogImp.cpp b/src/ripple/basics/impl/PerfLogImp.cpp index c24ac3e0fe8..2206a7f1693 100644 --- a/src/ripple/basics/impl/PerfLogImp.cpp +++ b/src/ripple/basics/impl/PerfLogImp.cpp @@ -477,7 +477,6 @@ PerfLogImp::onStop() } thread_.join(); } - stopped(); } //----------------------------------------------------------------------------- diff --git a/src/ripple/core/JobQueue.h b/src/ripple/core/JobQueue.h index f382bc8463d..1176fdf033e 100644 --- a/src/ripple/core/JobQueue.h +++ b/src/ripple/core/JobQueue.h @@ -232,6 +232,11 @@ class JobQueue : public Stoppable, private Workers::Callback void onStop() override; + // We may be able to move away from this, but we can keep it during the + // transition. + bool + isStopped() const; + private: friend class Coro; @@ -242,6 +247,7 @@ class JobQueue : public Stoppable, private Workers::Callback std::uint64_t m_lastJob; std::set m_jobSet; JobCounter jobCounter_; + std::atomic_bool stopped_{false}; JobDataMap m_jobData; JobTypeData m_invalidJobData; diff --git a/src/ripple/core/Pg.cpp b/src/ripple/core/Pg.cpp index 977d8e18cd9..3033077ae7c 100644 --- a/src/ripple/core/Pg.cpp +++ b/src/ripple/core/Pg.cpp @@ -507,7 +507,6 @@ PgPool::onStop() stop_ = true; cond_.notify_all(); idle_.clear(); - stopped(); JLOG(j_.info()) << "stopped"; } diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index 265ab468342..7c764331d68 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -91,60 +91,6 @@ class RootStoppable; Objects are called parent first. - 7. onChildrenStopped() - - This override is called when all the children have stopped. This informs - the Stoppable that there should not be any more dependents making calls - into its member functions. A Stoppable that has no children will still - have this function called. - - Objects are called children first. - - 8. stopped() - - The derived class calls this function to inform the Stoppable API that - it has completed the stop. This unblocks the caller of stop(). - - For stoppables which are only considered stopped when all of their - children have stopped, and their own internal logic indicates a stop, it - will be necessary to perform special actions in onChildrenStopped(). The - function areChildrenStopped() can be used after children have stopped, - but before the Stoppable logic itself has stopped, to determine if the - stoppable's logic is a true stop. - - Pseudo code for this process is as follows: - - @code - - // Returns `true` if derived logic has stopped. - // - // When the logic stops, logicProcessingStop() is no longer called. - // If children are still active we need to wait until we get a - // notification that the children have stopped. - // - bool logicHasStopped (); - - // Called when children have stopped - void onChildrenStopped () - { - // We have stopped when the derived logic stops and children stop. - if (logicHasStopped) - stopped(); - } - - // derived-specific logic that executes periodically - void logicProcessingStep () - { - // process - // ... - - // now see if we've stopped - if (logicHasStopped() && areChildrenStopped()) - stopped(); - } - - @endcode - Derived class that manage one or more threads should typically notify those threads in onStop that they should exit. In the thread function, when the last thread is about to exit it would call stopped(). @@ -208,19 +154,6 @@ class Stoppable bool isStopping() const; - /** Returns `true` if the requested stop has completed. */ - bool - isStopped() const; - - /** Returns `true` if all children have stopped. */ - bool - areChildrenStopped() const; - -protected: - /** Called by derived classes to indicate that the stoppable has stopped. */ - void - stopped(); - private: /** Override called during start. */ virtual void @@ -229,7 +162,7 @@ class Stoppable /** Override called when the stop notification is issued. The call is made on an unspecified, implementation-specific thread. - onStop and onChildrenStopped will never be called concurrently, across + onStop will never be called concurrently, across all Stoppable objects descended from the same root, inclusive of the root. @@ -248,28 +181,7 @@ class Stoppable Must be safe to call from any thread at any time. */ virtual void - onStop(); - - /** Override called when all children have stopped. - - The call is made on an unspecified, implementation-specific thread. - onStop and onChildrenStopped will never be called concurrently, across - all Stoppable objects descended from the same root, inclusive of the - root. - - It is safe to call isStopping, isStopped, and areChildrenStopped from - within this function; The values returned will always be valid and never - change during the callback. - - The default implementation does nothing. - - Thread safety: - May not block for long periods. - Guaranteed only to be called once. - Must be safe to call from any thread at any time. - */ - virtual void - onChildrenStopped(); + onStop() = 0; friend class RootStoppable; @@ -289,19 +201,11 @@ class Stoppable startRecursive(); void stopAsyncRecursive(beast::Journal j); - void - stopRecursive(beast::Journal j); std::string m_name; RootStoppable& m_root; Child m_child; - // TODO [C++20]: Use std::atomic_flag instead. - std::atomic m_stopped{false}; - std::atomic m_childrenStopped{false}; Children m_children; - std::condition_variable m_cv; - std::mutex m_mut; - bool m_is_stopping = false; bool hasParent_{false}; }; @@ -337,6 +241,11 @@ class RootStoppable : public Stoppable void stop(beast::Journal j); + void + onStop() override + { + } + /** Return true if start() was ever called. */ bool started() const diff --git a/src/ripple/core/impl/JobQueue.cpp b/src/ripple/core/impl/JobQueue.cpp index 0f41273c1f8..8eb4b679ff8 100644 --- a/src/ripple/core/impl/JobQueue.cpp +++ b/src/ripple/core/impl/JobQueue.cpp @@ -97,24 +97,8 @@ JobQueue::addRefCountedJob( { 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: - // - // - The JobQueue has NOT stopped - // AND - // * We are currently processing jobs - // OR - // * We have have pending jobs - // OR - // * Not all children are stopped - // - assert( - !isStopped() && - (m_processCount > 0 || !m_jobSet.empty() || !areChildrenStopped())); - - std::pair::iterator, bool> result(m_jobSet.insert( - Job(type, name, ++m_lastJob, data.load(), func, m_cancelCallback))); + auto result = m_jobSet.emplace( + type, name, ++m_lastJob, data.load(), func, m_cancelCallback); queueJob(*result.first, lock); } return true; @@ -312,8 +296,14 @@ JobQueue::onStop() assert(m_processCount == 0); assert(m_jobSet.empty()); assert(nSuspend_ == 0); + stopped_ = true; } - stopped(); +} + +bool +JobQueue::isStopped() const +{ + return stopped_; } void @@ -433,7 +423,7 @@ JobQueue::processTask(int instance) { std::lock_guard lock(m_mutex); - // Job should be destroyed before calling stopped() + // Job should be destroyed before stopping // otherwise destructors with side effects can access // parent objects that are already destroyed. finishJob(type); diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index 7d45b0e248a..d7ddbf6b16c 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -56,42 +56,11 @@ Stoppable::isStopping() const return m_root.isStopping(); } -bool -Stoppable::isStopped() const -{ - return m_stopped; -} - -bool -Stoppable::areChildrenStopped() const -{ - return m_childrenStopped; -} - -void -Stoppable::stopped() -{ - std::lock_guard lk{m_mut}; - m_is_stopping = true; - m_cv.notify_all(); -} - void Stoppable::onStart() { } -void -Stoppable::onStop() -{ - stopped(); -} - -void -Stoppable::onChildrenStopped() -{ -} - //------------------------------------------------------------------------------ void @@ -115,34 +84,6 @@ Stoppable::stopAsyncRecursive(beast::Journal j) iter->stoppable->stopAsyncRecursive(j); } -void -Stoppable::stopRecursive(beast::Journal j) -{ - // Block on each child from the bottom of the tree up. - // - for (Children::const_iterator iter(m_children.cbegin()); - iter != m_children.cend(); - ++iter) - iter->stoppable->stopRecursive(j); - - // if we get here then all children have stopped - // - m_childrenStopped = true; - onChildrenStopped(); - - // Now block on this Stoppable until m_is_stopping is set by stopped(). - // - using namespace std::chrono_literals; - std::unique_lock lk{m_mut}; - if (!m_cv.wait_for(lk, 1s, [this] { return m_is_stopping; })) - { - if (auto stream = j.error()) - stream << "Waiting for '" << m_name << "' to stop"; - m_cv.wait(lk, [this] { return m_is_stopping; }); - } - m_stopped = true; -} - //------------------------------------------------------------------------------ RootStoppable::RootStoppable(std::string name) @@ -190,7 +131,6 @@ RootStoppable::stop(beast::Journal j) } stopAsyncRecursive(j); - stopRecursive(j); } } // namespace ripple diff --git a/src/ripple/nodestore/impl/Database.cpp b/src/ripple/nodestore/impl/Database.cpp index b2e734d5c59..05c85d7a3ac 100644 --- a/src/ripple/nodestore/impl/Database.cpp +++ b/src/ripple/nodestore/impl/Database.cpp @@ -66,7 +66,6 @@ Database::onStop() // After stop time we can no longer use the JobQueue for background // reads. Join the background read threads. stopReadThreads(); - stopped(); } void diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index c48c185ba06..58c9ac03f66 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -728,8 +728,6 @@ DatabaseShardImp::onStop() JLOG(j_.warn()) << " shard " << shardIndex << " unexpired"; } } - - stopped(); } void diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 709874289fc..f6293d73720 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -561,7 +561,6 @@ OverlayImpl::onStop() std::unique_lock lock(mutex_); cond_.wait(lock, [this] { return list_.empty(); }); } - stopped(); } //------------------------------------------------------------------------------ diff --git a/src/ripple/peerfinder/impl/PeerfinderManager.cpp b/src/ripple/peerfinder/impl/PeerfinderManager.cpp index 0b947abfb21..570e0496539 100644 --- a/src/ripple/peerfinder/impl/PeerfinderManager.cpp +++ b/src/ripple/peerfinder/impl/PeerfinderManager.cpp @@ -225,7 +225,6 @@ class ManagerImp : public Manager onStop() override { close(); - stopped(); } //-------------------------------------------------------------------------- diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index 6c8da851484..505645c58f7 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -146,7 +146,6 @@ ServerHandlerImp::onStop() std::unique_lock lock(mutex_); condition_.wait(lock, [this]() { return stopped_; }); } - stopped(); } //------------------------------------------------------------------------------ diff --git a/src/ripple/rpc/impl/ShardArchiveHandler.cpp b/src/ripple/rpc/impl/ShardArchiveHandler.cpp index 18e49c6a84a..a3f73c53bc2 100644 --- a/src/ripple/rpc/impl/ShardArchiveHandler.cpp +++ b/src/ripple/rpc/impl/ShardArchiveHandler.cpp @@ -209,8 +209,6 @@ ShardArchiveHandler::onStop() timerCounter_.join( "ShardArchiveHandler", std::chrono::milliseconds(2000), j_); - - stopped(); } bool diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index a9d2af3c314..e140ca87c79 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -81,14 +81,6 @@ class PerfLog_test : public beast::unit_test::suite void onStop() override { - if (areChildrenStopped()) - stopped(); - } - - void - onChildrenStopped() override - { - onStop(); } public: diff --git a/src/test/core/Stoppable_test.cpp b/src/test/core/Stoppable_test.cpp index 79f8dfec331..37f964ca58a 100644 --- a/src/test/core/Stoppable_test.cpp +++ b/src/test/core/Stoppable_test.cpp @@ -60,14 +60,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 0, "D::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 9, "D::onChildrenStopped called out of order"); - } }; class J : public Stoppable @@ -91,14 +83,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 1, "J::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 7, "J::onChildrenStopped called out of order"); - } }; class E : public Stoppable @@ -123,14 +107,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 2, "E::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 8, "E::onChildrenStopped called out of order"); - } }; class F : public Stoppable @@ -154,14 +130,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 3, "F::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 6, "F::onChildrenStopped called out of order"); - } }; class A : public Stoppable @@ -207,18 +175,12 @@ class Stoppable_test : public beast::unit_test::suite onStop() override { test_.expect(--test_.count == 4, "A::onStop called out of order"); - } - - void - onChildrenStopped() override - { + // Must be able to call onStop twice. + if (stop_ == stopped) + return; stop_ = please_stop; while (stop_ != stopping) ; - Stoppable::stopped(); - test_.expect( - ++test_.count == 10, - "A::onChildrenStopped called out of order"); stop_ = stopped; } }; @@ -244,14 +206,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 5, "G::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 4, "G::onChildrenStopped called out of order"); - } }; class H : public Stoppable @@ -275,14 +229,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 6, "H::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 3, "H::onChildrenStopped called out of order"); - } }; class B : public Stoppable @@ -311,14 +257,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 7, "B::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 5, "B::onChildrenStopped called out of order"); - } }; class I : public Stoppable @@ -342,14 +280,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 8, "I::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 1, "I::onChildrenStopped called out of order"); - } }; class C : public Stoppable @@ -374,14 +304,6 @@ class Stoppable_test : public beast::unit_test::suite { test_.expect(--test_.count == 9, "C::onStop called out of order"); } - - void - onChildrenStopped() override - { - Stoppable::stopped(); - test_.expect( - ++test_.count == 2, "C::onChildrenStopped called out of order"); - } }; class Root : public RootStoppable @@ -403,6 +325,11 @@ class Stoppable_test : public beast::unit_test::suite { } + ~Root() + { + a_.join(); + } + void run() { @@ -424,16 +351,6 @@ class Stoppable_test : public beast::unit_test::suite --test_.count == 10, "Root::onStop called out of order"); } - void - onChildrenStopped() override - { - a_.join(); - Stoppable::stopped(); - test_.expect( - ++test_.count == 11, - "Root::onChildrenStopped called out of order"); - } - void secondStop() { From 78050dbb808d51f36ac0c75b73c9e83949ab282c Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 30 Dec 2020 22:37:21 -0600 Subject: [PATCH 15/62] [fold] Remove Stoppable::{setParent,getRoot} --- src/ripple/core/Stoppable.h | 18 +----------------- src/ripple/core/impl/Stoppable.cpp | 14 -------------- src/ripple/nodestore/impl/Database.cpp | 2 +- src/ripple/nodestore/impl/DatabaseNodeImp.h | 1 - .../nodestore/impl/DatabaseRotatingImp.cpp | 1 - src/ripple/nodestore/impl/DatabaseShardImp.cpp | 2 -- src/ripple/nodestore/impl/DatabaseShardImp.h | 1 - 7 files changed, 2 insertions(+), 37 deletions(-) diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index 7c764331d68..0b517d1eb19 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -133,22 +133,7 @@ class Stoppable Stoppable(std::string name, Stoppable& parent); /** Destroy the Stoppable. */ - virtual ~Stoppable(); - - RootStoppable& - getRoot() - { - return m_root; - } - - /** Set the parent of this Stoppable. - - @note The Stoppable must not already have a parent. - The parent to be set cannot not be stopping. - Both roots must match. - */ - void - setParent(Stoppable& parent); + virtual ~Stoppable() = default; /** Returns `true` if the stoppable should stop. */ bool @@ -206,7 +191,6 @@ class Stoppable RootStoppable& m_root; Child m_child; Children m_children; - bool hasParent_{false}; }; //------------------------------------------------------------------------------ diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index d7ddbf6b16c..3859833da26 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -32,22 +32,8 @@ Stoppable::Stoppable(std::string name, RootStoppable& root) Stoppable::Stoppable(std::string name, Stoppable& parent) : m_name(std::move(name)), m_root(parent.m_root), m_child(this) { - setParent(parent); -} - -Stoppable::~Stoppable() -{ -} - -void -Stoppable::setParent(Stoppable& parent) -{ - assert(!hasParent_); assert(!parent.isStopping()); - assert(std::addressof(m_root) == std::addressof(parent.m_root)); - parent.m_children.push_front(&m_child); - hasParent_ = true; } bool diff --git a/src/ripple/nodestore/impl/Database.cpp b/src/ripple/nodestore/impl/Database.cpp index 05c85d7a3ac..5784e9c8576 100644 --- a/src/ripple/nodestore/impl/Database.cpp +++ b/src/ripple/nodestore/impl/Database.cpp @@ -36,7 +36,7 @@ Database::Database( int readThreads, Section const& config, beast::Journal journal) - : Stoppable(name, parent.getRoot()) + : Stoppable(name, parent) , j_(journal) , scheduler_(scheduler) , earliestLedgerSeq_( diff --git a/src/ripple/nodestore/impl/DatabaseNodeImp.h b/src/ripple/nodestore/impl/DatabaseNodeImp.h index 547e894886e..0e725a821ca 100644 --- a/src/ripple/nodestore/impl/DatabaseNodeImp.h +++ b/src/ripple/nodestore/impl/DatabaseNodeImp.h @@ -79,7 +79,6 @@ class DatabaseNodeImp : public Database j); } assert(backend_); - setParent(parent); } ~DatabaseNodeImp() override diff --git a/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp b/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp index 31df09f2bcf..2d8eadb3b51 100644 --- a/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp @@ -41,7 +41,6 @@ DatabaseRotatingImp::DatabaseRotatingImp( fdRequired_ += writableBackend_->fdRequired(); if (archiveBackend_) fdRequired_ += archiveBackend_->fdRequired(); - setParent(parent); } void diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index 58c9ac03f66..fc4731afa16 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -54,7 +54,6 @@ DatabaseShardImp::DatabaseShardImp( app.config().section(ConfigSection::shardDatabase()), j) , app_(app) - , parent_(parent) , earliestShardIndex_(seqToShardIndex(earliestLedgerSeq())) , avgShardFileSz_(ledgersPerShard_ * kilobytes(192ull)) , openFinalLimit_( @@ -221,7 +220,6 @@ DatabaseShardImp::init() } updateStatus(lock); - setParent(parent_); init_ = true; } diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.h b/src/ripple/nodestore/impl/DatabaseShardImp.h index 139db7ece4f..05b8ddf6c7e 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.h +++ b/src/ripple/nodestore/impl/DatabaseShardImp.h @@ -168,7 +168,6 @@ class DatabaseShardImp : public DatabaseShard }; Application& app_; - Stoppable& parent_; mutable std::mutex mutex_; bool init_{false}; From 251bf3e55fa7af8a43f931df9ed1daf45e92e7c7 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 4 Jan 2021 21:56:59 -0600 Subject: [PATCH 16/62] [fold] Remove RootStoppable::start and Stoppable::startRecursive --- src/ripple/app/ledger/LedgerCleaner.h | 3 + src/ripple/app/ledger/LedgerMaster.h | 4 ++ src/ripple/app/ledger/impl/LedgerCleaner.cpp | 8 +-- src/ripple/app/ledger/impl/LedgerMaster.cpp | 6 ++ src/ripple/app/main/Application.cpp | 17 +++-- src/ripple/app/main/GRPCServer.cpp | 2 +- src/ripple/app/main/GRPCServer.h | 2 +- src/ripple/app/main/LoadManager.cpp | 2 +- src/ripple/app/main/LoadManager.h | 3 +- src/ripple/app/misc/SHAMapStore.h | 3 + src/ripple/app/misc/SHAMapStoreImp.h | 3 +- src/ripple/basics/PerfLog.h | 3 + src/ripple/basics/impl/PerfLogImp.cpp | 2 +- src/ripple/basics/impl/PerfLogImp.h | 4 +- src/ripple/core/Stoppable.h | 52 ++------------- src/ripple/core/impl/Stoppable.cpp | 27 -------- src/ripple/overlay/Overlay.h | 3 + src/ripple/overlay/impl/OverlayImpl.cpp | 8 +-- src/ripple/overlay/impl/OverlayImpl.h | 2 +- src/test/basics/PerfLog_test.cpp | 30 +++------ src/test/core/Stoppable_test.cpp | 70 +------------------- src/test/core/Workers_test.cpp | 5 ++ 22 files changed, 62 insertions(+), 197 deletions(-) diff --git a/src/ripple/app/ledger/LedgerCleaner.h b/src/ripple/app/ledger/LedgerCleaner.h index d3ee4add066..1ad96fe4d13 100644 --- a/src/ripple/app/ledger/LedgerCleaner.h +++ b/src/ripple/app/ledger/LedgerCleaner.h @@ -40,6 +40,9 @@ class LedgerCleaner : public Stoppable, public beast::PropertyStream::Source /** Destroy the object. */ virtual ~LedgerCleaner() = 0; + virtual void + start() = 0; + /** Start a long running task to clean the ledger. The ledger is cleaned asynchronously, on an implementation defined thread. This function call does not block. The long running task diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index 7f4e330eb3d..f91f709374d 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -259,6 +259,10 @@ class LedgerMaster : public AbstractFetchPackContainer bool fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash); + + void + start(); + void doLedgerCleaner(Json::Value const& parameters); diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index ddd6f5d4202..add4157608f 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -86,14 +86,8 @@ class LedgerCleanerImp : public LedgerCleaner LogicError("LedgerCleanerImp::onStop not called."); } - //-------------------------------------------------------------------------- - // - // Stoppable - // - //-------------------------------------------------------------------------- - void - onStart() override + start() override { thread_ = std::thread{&LedgerCleanerImp::run, this}; } diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index 59517a81858..876e79d8248 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -1786,6 +1786,12 @@ LedgerMaster::getLedgerByHash(uint256 const& hash) return {}; } +void +LedgerMaster::start() +{ + mLedgerCleaner->start(); +} + void LedgerMaster::doLedgerCleaner(Json::Value const& parameters) { diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index fa42b6525c5..74ffb53bbee 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -468,8 +468,8 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // VFALCO - READ THIS! // // Do not start threads, open sockets, or do any sort of "real work" - // inside the constructor. Put it in onStart instead. Or if you must, - // put it in setup (but everything in setup should be moved to onStart + // inside the constructor. Put it in start instead. Or if you must, + // put it in setup (but everything in setup should be moved to start // anyway. // // The reason is that the unit tests require an Application object to @@ -1023,12 +1023,9 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp } //-------------------------------------------------------------------------- - // - // Stoppable - // void - onStart() override + start() { JLOG(m_journal.info()) << "Application starting. Version is " << BuildInfo::getVersionString(); @@ -1705,7 +1702,13 @@ void ApplicationImp::doStart(bool withTimers) { startTimers_ = withTimers; - start(); + ApplicationImp::start(); + m_loadManager->start(); + m_shaMapStore->start(); + overlay_->start(); + grpcServer_->start(); + m_ledgerMaster->start(); + perfLog_->start(); } void diff --git a/src/ripple/app/main/GRPCServer.cpp b/src/ripple/app/main/GRPCServer.cpp index b0dddc92d01..e7742b7a871 100644 --- a/src/ripple/app/main/GRPCServer.cpp +++ b/src/ripple/app/main/GRPCServer.cpp @@ -774,7 +774,7 @@ GRPCServerImpl::start() } void -GRPCServer::onStart() +GRPCServer::start() { // Start the server and setup listeners if (running_ = impl_.start(); running_) diff --git a/src/ripple/app/main/GRPCServer.h b/src/ripple/app/main/GRPCServer.h index 65468de7335..81f1dd4e63d 100644 --- a/src/ripple/app/main/GRPCServer.h +++ b/src/ripple/app/main/GRPCServer.h @@ -308,7 +308,7 @@ class GRPCServer : public Stoppable operator=(const GRPCServer&) = delete; void - onStart() override; + start(); void onStop() override; diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index f9140eb010e..b5a79b64cee 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -77,7 +77,7 @@ LoadManager::resetDeadlockDetector() //------------------------------------------------------------------------------ void -LoadManager::onStart() +LoadManager::start() { JLOG(journal_.debug()) << "Starting"; assert(!thread_.joinable()); diff --git a/src/ripple/app/main/LoadManager.h b/src/ripple/app/main/LoadManager.h index 68abe475d4e..e14ec3653a1 100644 --- a/src/ripple/app/main/LoadManager.h +++ b/src/ripple/app/main/LoadManager.h @@ -82,9 +82,8 @@ class LoadManager : public Stoppable //-------------------------------------------------------------------------- - // Stoppable members void - onStart() override; + start(); void onStop() override; diff --git a/src/ripple/app/misc/SHAMapStore.h b/src/ripple/app/misc/SHAMapStore.h index e45cb30b207..dd48ca069db 100644 --- a/src/ripple/app/misc/SHAMapStore.h +++ b/src/ripple/app/misc/SHAMapStore.h @@ -43,6 +43,9 @@ class SHAMapStore virtual void onLedgerClosed(std::shared_ptr const& ledger) = 0; + virtual void + start() = 0; + virtual void rendezvous() const = 0; diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h index f325822e2a2..e50fe1148b6 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.h +++ b/src/ripple/app/misc/SHAMapStoreImp.h @@ -242,8 +242,9 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore Health health(); +public: void - onStart() override + start() override { if (deleteInterval_) thread_ = std::thread(&SHAMapStoreImp::run, this); diff --git a/src/ripple/basics/PerfLog.h b/src/ripple/basics/PerfLog.h index 44d5c940e62..46673828761 100644 --- a/src/ripple/basics/PerfLog.h +++ b/src/ripple/basics/PerfLog.h @@ -66,6 +66,9 @@ class PerfLog virtual ~PerfLog() = default; + virtual void + start() = 0; + /** * Log start of RPC call. * diff --git a/src/ripple/basics/impl/PerfLogImp.cpp b/src/ripple/basics/impl/PerfLogImp.cpp index 2206a7f1693..29d726ec813 100644 --- a/src/ripple/basics/impl/PerfLogImp.cpp +++ b/src/ripple/basics/impl/PerfLogImp.cpp @@ -459,7 +459,7 @@ PerfLogImp::rotate() } void -PerfLogImp::onStart() +PerfLogImp::start() { if (setup_.perfLog.size()) thread_ = std::thread(&PerfLogImp::run, this); diff --git a/src/ripple/basics/impl/PerfLogImp.h b/src/ripple/basics/impl/PerfLogImp.h index d648e460d3a..02e4401edf7 100644 --- a/src/ripple/basics/impl/PerfLogImp.h +++ b/src/ripple/basics/impl/PerfLogImp.h @@ -210,9 +210,9 @@ class PerfLogImp : public PerfLog, Stoppable void rotate() override; - // Called when application is ready to start threads. void - onStart() override; + start() override; + // Called when the application begins shutdown. void onStop() override; diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h index 0b517d1eb19..8250f10e321 100644 --- a/src/ripple/core/Stoppable.h +++ b/src/ripple/core/Stoppable.h @@ -31,7 +31,7 @@ namespace ripple { class RootStoppable; -/** Provides an interface for starting and stopping. +/** Provides an interface for stopping. A common method of structuring server or peer to peer code is to isolate conceptual portions of functionality into individual classes, aggregated @@ -39,8 +39,8 @@ class RootStoppable; Frequently, these components are dependent on each other in unavoidably complex ways. They also often use threads and perform asynchronous i/o operations involving sockets or other operating system objects. The process - of starting and stopping such a system can be complex. This interface - provides a set of behaviors for ensuring that the start and stop of a + of stopping such a system can be complex. This interface + provides a set of behaviors for ensuring that the stop of a composite application-style object is well defined. Upon the initialization of the composite object these steps are performed: @@ -51,22 +51,6 @@ class RootStoppable; hierarchy: Stoppable objects may themselves have Stoppable child objects. This captures the relationship of dependencies. - 2. start() - - At this point all sub-components have been constructed and prepared, - so it should be safe for them to be started. While some Stoppable - objects may do nothing in their start function, others will start - threads or call asynchronous i/o initiating functions like timers or - sockets. - - 3. onStart() - - This override is called for all Stoppable objects in the hierarchy - during the start stage. It is guaranteed that no child Stoppable - objects have been started when this is called. - - Objects are called parent first. - This is the sequence of events involved in stopping: 4. stopAsync() [optional] @@ -95,8 +79,6 @@ class RootStoppable; those threads in onStop that they should exit. In the thread function, when the last thread is about to exit it would call stopped(). - @note A Stoppable may not be restarted. - The form of the Stoppable tree in the rippled application evolves as the source code changes and reacts to new demands. As of July in 2020 the Stoppable tree had this form: @@ -139,11 +121,6 @@ class Stoppable bool isStopping() const; -private: - /** Override called during start. */ - virtual void - onStart(); - /** Override called when the stop notification is issued. The call is made on an unspecified, implementation-specific thread. @@ -168,6 +145,7 @@ class Stoppable virtual void onStop() = 0; +private: friend class RootStoppable; struct Child; @@ -182,8 +160,6 @@ class Stoppable Stoppable* stoppable; }; - void - startRecursive(); void stopAsyncRecursive(beast::Journal j); @@ -205,20 +181,9 @@ class RootStoppable : public Stoppable bool isStopping() const; - /** Start all contained Stoppable objects. - This calls onStart for all Stoppable objects in the tree, top-down. - Calls made after the first have no effect. - Thread safety: - May be called from any thread. - */ - void - start(); - /** Notify a root stoppable and children to stop, and block until stopped. Has no effect if the stoppable was already notified. This blocks until the stoppable and all of its children have stopped. - Undefined behavior results if stop() is called without finishing - a previous call to start(). Thread safety: Safe to call from any thread not associated with a Stoppable. */ @@ -230,17 +195,8 @@ class RootStoppable : public Stoppable { } - /** Return true if start() was ever called. */ - bool - started() const - { - return startExited_; - } - private: // TODO [C++20]: Use std::atomic_flag instead. - std::atomic startEntered_{false}; - std::atomic startExited_{false}; std::atomic stopEntered_{false}; std::mutex m_; }; diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp index 3859833da26..49c630280fe 100644 --- a/src/ripple/core/impl/Stoppable.cpp +++ b/src/ripple/core/impl/Stoppable.cpp @@ -42,23 +42,8 @@ Stoppable::isStopping() const return m_root.isStopping(); } -void -Stoppable::onStart() -{ -} - //------------------------------------------------------------------------------ -void -Stoppable::startRecursive() -{ - onStart(); - for (Children::const_iterator iter(m_children.cbegin()); - iter != m_children.cend(); - ++iter) - iter->stoppable->startRecursive(); -} - void Stoppable::stopAsyncRecursive(beast::Journal j) { @@ -85,21 +70,9 @@ RootStoppable::isStopping() const return stopEntered_; } -void -RootStoppable::start() -{ - if (startEntered_.exchange(true)) - return; - startRecursive(); - startExited_ = true; -} - void RootStoppable::stop(beast::Journal j) { - // Must have a prior call to start() - assert(startExited_); - bool alreadyCalled; { // Even though stopEntered_ is atomic, we change its value under a diff --git a/src/ripple/overlay/Overlay.h b/src/ripple/overlay/Overlay.h index a9c52dd7748..8b77c987b1e 100644 --- a/src/ripple/overlay/Overlay.h +++ b/src/ripple/overlay/Overlay.h @@ -83,6 +83,9 @@ class Overlay : public Stoppable, public beast::PropertyStream::Source virtual ~Overlay() = default; + virtual void + start() = 0; + /** Conditionally accept an incoming HTTP request. */ virtual Handoff onHandoff( diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index f6293d73720..28a6679f89d 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -466,14 +466,8 @@ OverlayImpl::remove(std::shared_ptr const& slot) m_peers.erase(iter); } -//------------------------------------------------------------------------------ -// -// Stoppable -// -//------------------------------------------------------------------------------ - void -OverlayImpl::onStart() +OverlayImpl::start() { PeerFinder::Config config = PeerFinder::Config::makeConfig( app_.config(), diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index 4b0f18cef5b..8384b5d918e 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -506,7 +506,7 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler checkStopped(); void - onStart() override; + start() override; void onStop() override; diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index e140ca87c79..ba48ab6696e 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -59,7 +59,6 @@ class PerfLog_test : public beast::unit_test::suite ~PerfLogParent() override { - doStop(); cleanupPerfLogDir(); } @@ -72,30 +71,17 @@ class PerfLog_test : public beast::unit_test::suite private: // Interfaces for RootStoppable. Made private to encourage the use - // of doStart() and doStop(). - void - onStart() override - { - } - + // of doStop(). void onStop() override { } public: - // Test interfaces to start and stop the PerfLog - void - doStart() - { - start(); - } - void doStop() { - if (started()) - stop(j_); + stop(j_); } // Interfaces for PerfLog file management @@ -291,7 +277,7 @@ class PerfLog_test : public beast::unit_test::suite // Start PerfLog and wait long enough for PerfLog::report() // to not be able to write to its file. That should cause no // problems. - parent.doStart(); + perfLog->start(); std::this_thread::sleep_for(parent.getLogInterval() * 10); parent.doStop(); @@ -344,7 +330,7 @@ class PerfLog_test : public beast::unit_test::suite // Start PerfLog and wait long enough for PerfLog::report() // to not be able to write to its file. That should cause no // problems. - parent.doStart(); + perfLog->start(); std::this_thread::sleep_for(parent.getLogInterval() * 10); parent.doStop(); @@ -363,7 +349,7 @@ class PerfLog_test : public beast::unit_test::suite // Start up the PerfLog that we'll use for testing. PerfLogParent parent{j_}; auto perfLog{getPerfLog(parent, withFile)}; - parent.doStart(); + perfLog->start(); // Get the all the labels we can use for RPC interfaces without // causing an assert. @@ -569,7 +555,7 @@ class PerfLog_test : public beast::unit_test::suite // Start up the PerfLog that we'll use for testing. PerfLogParent parent{j_}; auto perfLog{getPerfLog(parent, withFile)}; - parent.doStart(); + perfLog->start(); // Get the all the JobTypes we can use to call the jobs interfaces // without causing an assert. @@ -917,7 +903,7 @@ class PerfLog_test : public beast::unit_test::suite // Start up the PerfLog that we'll use for testing. PerfLogParent parent{j_}; auto perfLog{getPerfLog(parent, withFile)}; - parent.doStart(); + perfLog->start(); // Randomly select a job type and its name. JobType jobType; @@ -1077,7 +1063,7 @@ class PerfLog_test : public beast::unit_test::suite // Start PerfLog and wait long enough for PerfLog::report() // to write to its file. - parent.doStart(); + perfLog->start(); waitForFileUpdate(parent); decltype(file_size(fullPath)) firstFileSize{0}; diff --git a/src/test/core/Stoppable_test.cpp b/src/test/core/Stoppable_test.cpp index 37f964ca58a..47539a07f61 100644 --- a/src/test/core/Stoppable_test.cpp +++ b/src/test/core/Stoppable_test.cpp @@ -37,7 +37,7 @@ class Stoppable_test : public beast::unit_test::suite | J */ - unsigned count = 0; + unsigned count = 11; class D : public Stoppable { @@ -49,12 +49,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 11, "D::onStart called out of order"); - } - void onStop() override { @@ -72,12 +66,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 10, "J::onStart called out of order"); - } - void onStop() override { @@ -96,12 +84,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 9, "E::onStart called out of order"); - } - void onStop() override { @@ -119,12 +101,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 8, "F::onStart called out of order"); - } - void onStop() override { @@ -165,12 +141,6 @@ class Stoppable_test : public beast::unit_test::suite stop_ = stopping; } - void - onStart() override - { - test_.expect(++test_.count == 7, "A::onStart called out of order"); - } - void onStop() override { @@ -195,12 +165,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 6, "G::onStart called out of order"); - } - void onStop() override { @@ -218,12 +182,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 5, "H::onStart called out of order"); - } - void onStop() override { @@ -246,12 +204,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 4, "B::onStart called out of order"); - } - void onStop() override { @@ -269,12 +221,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 3, "I::onStart called out of order"); - } - void onStop() override { @@ -293,12 +239,6 @@ class Stoppable_test : public beast::unit_test::suite { } - void - onStart() override - { - test_.expect(++test_.count == 2, "C::onStart called out of order"); - } - void onStop() override { @@ -333,17 +273,9 @@ class Stoppable_test : public beast::unit_test::suite void run() { - start(); stop(journal_); } - void - onStart() override - { - test_.expect( - ++test_.count == 1, "Root::onStart called out of order"); - } - void onStop() override { diff --git a/src/test/core/Workers_test.cpp b/src/test/core/Workers_test.cpp index 7243732af10..d0c3ef9dec0 100644 --- a/src/test/core/Workers_test.cpp +++ b/src/test/core/Workers_test.cpp @@ -95,6 +95,11 @@ class PerfLogTest : public PerfLog rotate() override { } + + void + start() override + { + } }; } // namespace perf From 299e059f8a38710058f50f090be0cf6c7c3bacf5 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 5 Jan 2021 18:36:02 -0600 Subject: [PATCH 17/62] [fold] Inline Application::start --- src/ripple/app/main/Application.cpp | 39 +++++++++++------------------ src/ripple/app/main/Application.h | 2 +- src/ripple/app/main/Main.cpp | 2 +- src/test/jtx/impl/Env.cpp | 2 +- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 74ffb53bbee..80b12c9437b 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -214,7 +214,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp ClosureCounter waitHandlerCounter_; boost::asio::steady_timer sweepTimer_; boost::asio::steady_timer entropyTimer_; - bool startTimers_; std::unique_ptr mTxnDB; std::unique_ptr mLedgerDB; @@ -445,8 +444,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , entropyTimer_(get_io_service()) - , startTimers_(false) - , m_signals(get_io_service()) , checkSigs_(true) @@ -487,7 +484,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp bool setup() override; void - doStart(bool withTimers) override; + start(bool withTimers) override; void run() override; void @@ -1024,24 +1021,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp //-------------------------------------------------------------------------- - void - start() - { - JLOG(m_journal.info()) << "Application starting. Version is " - << BuildInfo::getVersionString(); - - using namespace std::chrono_literals; - if (startTimers_) - { - setSweepTimer(); - setEntropyTimer(); - } - - m_io_latency_sampler.start(); - - m_resolver->start(); - } - // Called to indicate shutdown. void onStop() override @@ -1699,10 +1678,20 @@ ApplicationImp::setup() } void -ApplicationImp::doStart(bool withTimers) +ApplicationImp::start(bool withTimers) { - startTimers_ = withTimers; - ApplicationImp::start(); + JLOG(m_journal.info()) << "Application starting. Version is " + << BuildInfo::getVersionString(); + + using namespace std::chrono_literals; + if (withTimers) + { + setSweepTimer(); + setEntropyTimer(); + } + + m_io_latency_sampler.start(); + m_resolver->start(); m_loadManager->start(); m_shaMapStore->start(); overlay_->start(); diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h index 42553677567..44bef2ff49c 100644 --- a/src/ripple/app/main/Application.h +++ b/src/ripple/app/main/Application.h @@ -124,7 +124,7 @@ class Application : public beast::PropertyStream::Source virtual bool setup() = 0; virtual void - doStart(bool withTimers) = 0; + start(bool withTimers) = 0; virtual void run() = 0; virtual void diff --git a/src/ripple/app/main/Main.cpp b/src/ripple/app/main/Main.cpp index 377d6c25671..d32d9b83497 100644 --- a/src/ripple/app/main/Main.cpp +++ b/src/ripple/app/main/Main.cpp @@ -766,7 +766,7 @@ run(int argc, char** argv) return -1; // Start the server - app->doStart(true /*start timers*/); + app->start(true /*start timers*/); // Block until we get a stop RPC. app->run(); diff --git a/src/test/jtx/impl/Env.cpp b/src/test/jtx/impl/Env.cpp index a8c5aca49b3..081d826bcc8 100644 --- a/src/test/jtx/impl/Env.cpp +++ b/src/test/jtx/impl/Env.cpp @@ -86,7 +86,7 @@ Env::AppBundle::AppBundle( if (!app->setup()) Throw("Env::AppBundle: setup failed"); timeKeeper->set(app->getLedgerMaster().getClosedLedger()->info().closeTime); - app->doStart(false /*don't start timers*/); + app->start(false /*don't start timers*/); thread = std::thread([&]() { app->run(); }); client = makeJSONRPCClient(app->config()); From ad12f0e9fc6d6eecaa80dc9a1336a99ff8106353 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 5 Jan 2021 22:41:02 -0600 Subject: [PATCH 18/62] [fold] LoadManager is not a Stoppable --- src/ripple/app/main/Application.cpp | 4 ++-- src/ripple/app/main/LoadManager.cpp | 19 ++++++------------- src/ripple/app/main/LoadManager.h | 19 +++++++------------ src/test/rpc/Subscribe_test.cpp | 2 +- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 80b12c9437b..c6abef84792 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -434,8 +434,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp *this, logs_->journal("Validations")) - , m_loadManager( - make_LoadManager(*this, *this, logs_->journal("LoadManager"))) + , m_loadManager(make_LoadManager(*this, logs_->journal("LoadManager"))) , txQ_( std::make_unique(setup_TxQ(*config_), logs_->journal("TxQ"))) @@ -1721,6 +1720,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + m_loadManager->stop(); JLOG(m_journal.info()) << "Done."; } diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index b5a79b64cee..e19685ce42c 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -30,15 +30,8 @@ namespace ripple { -LoadManager::LoadManager( - Application& app, - Stoppable& parent, - beast::Journal journal) - : Stoppable("LoadManager", parent) - , app_(app) - , journal_(journal) - , deadLock_() - , armed_(false) +LoadManager::LoadManager(Application& app, beast::Journal journal) + : app_(app), journal_(journal), deadLock_(), armed_(false) { } @@ -46,7 +39,7 @@ LoadManager::~LoadManager() { try { - onStop(); + stop(); } catch (std::exception const& ex) { @@ -86,7 +79,7 @@ LoadManager::start() } void -LoadManager::onStop() +LoadManager::stop() { { std::lock_guard sl(mutex_); @@ -201,9 +194,9 @@ LoadManager::run() //------------------------------------------------------------------------------ std::unique_ptr -make_LoadManager(Application& app, Stoppable& parent, beast::Journal journal) +make_LoadManager(Application& app, beast::Journal journal) { - return std::unique_ptr{new LoadManager{app, parent, journal}}; + return std::unique_ptr{new LoadManager{app, journal}}; } } // namespace ripple diff --git a/src/ripple/app/main/LoadManager.h b/src/ripple/app/main/LoadManager.h index e14ec3653a1..905006f5e41 100644 --- a/src/ripple/app/main/LoadManager.h +++ b/src/ripple/app/main/LoadManager.h @@ -20,8 +20,9 @@ #ifndef RIPPLE_APP_MAIN_LOADMANAGER_H_INCLUDED #define RIPPLE_APP_MAIN_LOADMANAGER_H_INCLUDED -#include +#include #include +#include #include #include #include @@ -41,9 +42,9 @@ class Application; The warning system is used instead of merely dropping, because hostile peers can just reconnect anyway. */ -class LoadManager : public Stoppable +class LoadManager { - LoadManager(Application& app, Stoppable& parent, beast::Journal journal); + LoadManager(Application& app, beast::Journal journal); public: LoadManager() = delete; @@ -86,7 +87,7 @@ class LoadManager : public Stoppable start(); void - onStop() override; + stop(); private: void @@ -99,9 +100,6 @@ class LoadManager : public Stoppable std::thread thread_; std::mutex mutex_; // Guards deadLock_, armed_, cv_ std::condition_variable cv_; - // LoadManager must be stoppable separately from other Stoppables - // for the ripple.app.Subscribe test. It must stop on its own signal, - // instead of waiting for RootStoppable::isStopping(). bool stop_ = false; std::chrono::steady_clock::time_point @@ -109,14 +107,11 @@ class LoadManager : public Stoppable bool armed_; friend std::unique_ptr - make_LoadManager( - Application& app, - Stoppable& parent, - beast::Journal journal); + make_LoadManager(Application& app, beast::Journal journal); }; std::unique_ptr -make_LoadManager(Application& app, Stoppable& parent, beast::Journal journal); +make_LoadManager(Application& app, beast::Journal journal); } // namespace ripple diff --git a/src/test/rpc/Subscribe_test.cpp b/src/test/rpc/Subscribe_test.cpp index 22a4afb29df..d4dc83909af 100644 --- a/src/test/rpc/Subscribe_test.cpp +++ b/src/test/rpc/Subscribe_test.cpp @@ -61,7 +61,7 @@ class Subscribe_test : public beast::unit_test::suite // first findMsg but BEFORE we unsubscribe, thus causing the final // findMsg check to fail since there is one unprocessed ws msg created // by the loadmanager - env.app().getLoadManager().onStop(); + env.app().getLoadManager().stop(); { // Raise fee to cause an update auto& feeTrack = env.app().getFeeTrack(); From ffa6c2cba83aaac5010788787bd38845e1bb6fc9 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 5 Jan 2021 23:17:31 -0600 Subject: [PATCH 19/62] [fold] PeerFinder::Manager is not a Stoppable --- src/ripple/overlay/impl/OverlayImpl.cpp | 2 +- src/ripple/peerfinder/PeerfinderManager.h | 9 ++++++--- .../peerfinder/impl/PeerfinderManager.cpp | 20 +++++-------------- src/ripple/peerfinder/make_Manager.h | 1 - 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 28a6679f89d..76cbf2f1a3e 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -130,7 +130,6 @@ OverlayImpl::OverlayImpl( , serverHandler_(serverHandler) , m_resourceManager(resourceManager) , m_peerFinder(PeerFinder::make_Manager( - *this, io_service, stopwatch(), app_.journal("PeerFinder"), @@ -555,6 +554,7 @@ OverlayImpl::onStop() std::unique_lock lock(mutex_); cond_.wait(lock, [this] { return list_.empty(); }); } + m_peerFinder->stop(); } //------------------------------------------------------------------------------ diff --git a/src/ripple/peerfinder/PeerfinderManager.h b/src/ripple/peerfinder/PeerfinderManager.h index f945fb8d76a..61ce3df1434 100644 --- a/src/ripple/peerfinder/PeerfinderManager.h +++ b/src/ripple/peerfinder/PeerfinderManager.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -133,10 +132,10 @@ using Endpoints = std::vector; enum class Result { duplicate, full, success }; /** Maintains a set of IP addresses used for getting into the network. */ -class Manager : public Stoppable, public beast::PropertyStream::Source +class Manager : public beast::PropertyStream::Source { protected: - explicit Manager(Stoppable& parent); + Manager() noexcept; public: /** Destroy the object. @@ -158,6 +157,10 @@ class Manager : public Stoppable, public beast::PropertyStream::Source virtual void start() = 0; + /** Transition to the stopped state, synchronously. */ + virtual void + stop() = 0; + /** Returns the configuration for the manager. */ virtual Config config() = 0; diff --git a/src/ripple/peerfinder/impl/PeerfinderManager.cpp b/src/ripple/peerfinder/impl/PeerfinderManager.cpp index 570e0496539..0922d7fc539 100644 --- a/src/ripple/peerfinder/impl/PeerfinderManager.cpp +++ b/src/ripple/peerfinder/impl/PeerfinderManager.cpp @@ -47,13 +47,12 @@ class ManagerImp : public Manager //-------------------------------------------------------------------------- ManagerImp( - Stoppable& stoppable, boost::asio::io_service& io_service, clock_type& clock, beast::Journal journal, BasicConfig const& config, beast::insight::Collector::ptr const& collector) - : Manager(stoppable) + : Manager() , io_service_(io_service) , work_(boost::in_place(std::ref(io_service_))) , m_clock(clock) @@ -68,11 +67,11 @@ class ManagerImp : public Manager ~ManagerImp() override { - close(); + stop(); } void - close() + stop() override { if (work_) { @@ -221,12 +220,6 @@ class ManagerImp : public Manager m_logic.load(); } - void - onStop() override - { - close(); - } - //-------------------------------------------------------------------------- // // PropertyStream @@ -273,15 +266,12 @@ class ManagerImp : public Manager //------------------------------------------------------------------------------ -Manager::Manager(Stoppable& parent) - : Stoppable("PeerFinder", parent) - , beast::PropertyStream::Source("peerfinder") +Manager::Manager() noexcept : beast::PropertyStream::Source("peerfinder") { } std::unique_ptr make_Manager( - Stoppable& parent, boost::asio::io_service& io_service, clock_type& clock, beast::Journal journal, @@ -289,7 +279,7 @@ make_Manager( beast::insight::Collector::ptr const& collector) { return std::make_unique( - parent, io_service, clock, journal, config, collector); + io_service, clock, journal, config, collector); } } // namespace PeerFinder diff --git a/src/ripple/peerfinder/make_Manager.h b/src/ripple/peerfinder/make_Manager.h index 2520fa360de..932fccb9abd 100644 --- a/src/ripple/peerfinder/make_Manager.h +++ b/src/ripple/peerfinder/make_Manager.h @@ -30,7 +30,6 @@ namespace PeerFinder { /** Create a new Manager. */ std::unique_ptr make_Manager( - Stoppable& parent, boost::asio::io_service& io_service, clock_type& clock, beast::Journal journal, From 4d32cf6ad8d8430714d71f4964e8c5e20804036e Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 5 Jan 2021 23:19:11 -0600 Subject: [PATCH 20/62] [fold] Remove unused include --- src/ripple/nodestore/impl/TaskQueue.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ripple/nodestore/impl/TaskQueue.h b/src/ripple/nodestore/impl/TaskQueue.h index bb079ad2f16..77c5ff95b8e 100644 --- a/src/ripple/nodestore/impl/TaskQueue.h +++ b/src/ripple/nodestore/impl/TaskQueue.h @@ -20,7 +20,6 @@ #ifndef RIPPLE_NODESTORE_TASKQUEUE_H_INCLUDED #define RIPPLE_NODESTORE_TASKQUEUE_H_INCLUDED -#include #include #include From f331b3fb998ba41711577b520c7b4e869ae277b1 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 5 Jan 2021 23:28:15 -0600 Subject: [PATCH 21/62] [fold] ServerHandlerImp is not a Stoppable --- src/ripple/app/main/Application.cpp | 1 - src/ripple/rpc/ServerHandler.h | 2 -- src/ripple/rpc/impl/ServerHandlerImp.cpp | 11 ++++------- src/ripple/rpc/impl/ServerHandlerImp.h | 9 ++------- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index c6abef84792..d0378f62578 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -413,7 +413,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , serverHandler_(make_ServerHandler( *this, - *m_networkOPs, get_io_service(), *m_jobQueue, *m_networkOPs, diff --git a/src/ripple/rpc/ServerHandler.h b/src/ripple/rpc/ServerHandler.h index 1a9d34b650f..54cccdff64e 100644 --- a/src/ripple/rpc/ServerHandler.h +++ b/src/ripple/rpc/ServerHandler.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ setup_ServerHandler(Config const& c, std::ostream&& log); std::unique_ptr make_ServerHandler( Application& app, - Stoppable& parent, boost::asio::io_service&, JobQueue&, NetworkOPs&, diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index 505645c58f7..eebcbdd7489 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -104,14 +104,12 @@ authorized(Port const& port, std::map const& h) ServerHandlerImp::ServerHandlerImp( Application& app, - Stoppable& parent, boost::asio::io_service& io_service, JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager, CollectorManager& cm) - : Stoppable("ServerHandler", parent) - , app_(app) + : app_(app) , m_resourceManager(resourceManager) , m_journal(app_.journal("Server")) , m_networkOPs(networkOPs) @@ -139,12 +137,12 @@ ServerHandlerImp::setup(Setup const& setup, beast::Journal journal) //------------------------------------------------------------------------------ void -ServerHandlerImp::onStop() +ServerHandlerImp::stop() { m_server->close(); { std::unique_lock lock(mutex_); - condition_.wait(lock, [this]() { return stopped_; }); + condition_.wait(lock, [&] { return stopped_; }); } } @@ -1167,7 +1165,6 @@ setup_ServerHandler(Config const& config, std::ostream&& log) std::unique_ptr make_ServerHandler( Application& app, - Stoppable& parent, boost::asio::io_service& io_service, JobQueue& jobQueue, NetworkOPs& networkOPs, @@ -1175,7 +1172,7 @@ make_ServerHandler( CollectorManager& cm) { return std::make_unique( - app, parent, io_service, jobQueue, networkOPs, resourceManager, cm); + app, io_service, jobQueue, networkOPs, resourceManager, cm); } } // namespace ripple diff --git a/src/ripple/rpc/impl/ServerHandlerImp.h b/src/ripple/rpc/impl/ServerHandlerImp.h index 7e8228c70c8..7c0bf9c9ae5 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.h +++ b/src/ripple/rpc/impl/ServerHandlerImp.h @@ -44,7 +44,7 @@ operator<(Port const& lhs, Port const& rhs) return lhs.name < rhs.name; } -class ServerHandlerImp : public Stoppable +class ServerHandlerImp { public: struct Setup @@ -107,7 +107,6 @@ class ServerHandlerImp : public Stoppable public: ServerHandlerImp( Application& app, - Stoppable& parent, boost::asio::io_service& io_service, JobQueue& jobQueue, NetworkOPs& networkOPs, @@ -127,12 +126,8 @@ class ServerHandlerImp : public Stoppable return setup_; } - // - // Stoppable - // - void - onStop() override; + stop(); // // Handler From f8bd287aac3344897208f8fe6128520561cbc4ca Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 6 Jan 2021 10:21:54 -0600 Subject: [PATCH 22/62] [fold] LedgerCleaner is not a Stoppable --- src/ripple/app/ledger/LedgerCleaner.h | 12 ++++++----- src/ripple/app/ledger/LedgerMaster.h | 4 +++- src/ripple/app/ledger/impl/LedgerCleaner.cpp | 21 ++++++++------------ src/ripple/app/ledger/impl/LedgerMaster.cpp | 13 +++++++----- src/ripple/app/main/Application.cpp | 2 +- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/ripple/app/ledger/LedgerCleaner.h b/src/ripple/app/ledger/LedgerCleaner.h index 1ad96fe4d13..dadb4ad2624 100644 --- a/src/ripple/app/ledger/LedgerCleaner.h +++ b/src/ripple/app/ledger/LedgerCleaner.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -31,10 +30,10 @@ namespace ripple { namespace detail { /** Check the ledger/transaction databases to make sure they have continuity */ -class LedgerCleaner : public Stoppable, public beast::PropertyStream::Source +class LedgerCleaner : public beast::PropertyStream::Source { protected: - explicit LedgerCleaner(Stoppable& parent); + LedgerCleaner(); public: /** Destroy the object. */ @@ -43,10 +42,13 @@ class LedgerCleaner : public Stoppable, public beast::PropertyStream::Source virtual void start() = 0; + virtual void + stop() = 0; + /** Start a long running task to clean the ledger. The ledger is cleaned asynchronously, on an implementation defined thread. This function call does not block. The long running task - will be stopped if the Stoppable stops. + will be stopped by a call to stop(). Thread safety: Safe to call from any thread at any time. @@ -58,7 +60,7 @@ class LedgerCleaner : public Stoppable, public beast::PropertyStream::Source }; std::unique_ptr -make_LedgerCleaner(Application& app, Stoppable& parent, beast::Journal journal); +make_LedgerCleaner(Application& app, beast::Journal journal); } // namespace detail } // namespace ripple diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index f91f709374d..c89872fd6ee 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -79,12 +79,14 @@ class LedgerMaster : public AbstractFetchPackContainer explicit LedgerMaster( Application& app, Stopwatch& stopwatch, - Stoppable& parent, beast::insight::Collector::ptr const& collector, beast::Journal journal); virtual ~LedgerMaster() = default; + void + stop(); + LedgerIndex getCurrentLedgerIndex(); LedgerIndex diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index add4157608f..299c957e5e6 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -72,18 +72,15 @@ class LedgerCleanerImp : public LedgerCleaner //-------------------------------------------------------------------------- public: - LedgerCleanerImp( - Application& app, - Stoppable& stoppable, - beast::Journal journal) - : LedgerCleaner(stoppable), app_(app), j_(journal) + LedgerCleanerImp(Application& app, beast::Journal journal) + : app_(app), j_(journal) { } ~LedgerCleanerImp() override { if (thread_.joinable()) - LogicError("LedgerCleanerImp::onStop not called."); + LogicError("LedgerCleanerImp::stop not called."); } void @@ -93,7 +90,7 @@ class LedgerCleanerImp : public LedgerCleaner } void - onStop() override + stop() override { JLOG(j_.info()) << "Stopping"; { @@ -380,7 +377,7 @@ class LedgerCleanerImp : public LedgerCleaner void doLedgerCleaner() { - auto shouldExit = [this]() { + auto shouldExit = [&] { std::lock_guard lock(mutex_); return shouldExit_; }; @@ -457,18 +454,16 @@ class LedgerCleanerImp : public LedgerCleaner //------------------------------------------------------------------------------ -LedgerCleaner::LedgerCleaner(Stoppable& parent) - : Stoppable("LedgerCleaner", parent) - , beast::PropertyStream::Source("ledgercleaner") +LedgerCleaner::LedgerCleaner() : beast::PropertyStream::Source("ledgercleaner") { } LedgerCleaner::~LedgerCleaner() = default; std::unique_ptr -make_LedgerCleaner(Application& app, Stoppable& parent, beast::Journal journal) +make_LedgerCleaner(Application& app, beast::Journal journal) { - return std::make_unique(app, parent, journal); + return std::make_unique(app, journal); } } // namespace detail diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index 876e79d8248..a4cb3f49d09 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -181,16 +181,13 @@ shouldAcquire( LedgerMaster::LedgerMaster( Application& app, Stopwatch& stopwatch, - Stoppable& parent, beast::insight::Collector::ptr const& collector, beast::Journal journal) : app_(app) , m_journal(journal) , mLedgerHistory(collector, app) - , mLedgerCleaner(detail::make_LedgerCleaner( - app, - parent, - app_.journal("LedgerCleaner"))) + , mLedgerCleaner( + detail::make_LedgerCleaner(app, app_.journal("LedgerCleaner"))) , standalone_(app_.config().standalone()) , fetch_depth_( app_.getSHAMapStore().clampFetchDepth(app_.config().FETCH_DEPTH)) @@ -206,6 +203,12 @@ LedgerMaster::LedgerMaster( { } +void +LedgerMaster::stop() +{ + mLedgerCleaner->stop(); +} + LedgerIndex LedgerMaster::getCurrentLedgerIndex() { diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index d0378f62578..598abad50d0 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -348,7 +348,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , m_ledgerMaster(std::make_unique( *this, stopwatch(), - *m_jobQueue, m_collectorManager->collector(), logs_->journal("LedgerMaster"))) @@ -1719,6 +1718,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + m_ledgerMaster->stop(); m_loadManager->stop(); JLOG(m_journal.info()) << "Done."; } From 15a9472c7afad59acf82100cee3c2dc548604f3b Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 6 Jan 2021 15:28:31 -0600 Subject: [PATCH 23/62] [fold] NetworkOPsImp is not a Stoppable --- src/ripple/app/main/Application.cpp | 2 +- src/ripple/app/misc/NetworkOPs.cpp | 21 ++------------------- src/ripple/app/misc/NetworkOPs.h | 8 +++----- src/ripple/net/InfoSub.h | 8 +++----- src/ripple/net/impl/InfoSub.cpp | 9 --------- 5 files changed, 9 insertions(+), 39 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 598abad50d0..02632abe369 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -383,7 +383,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp config_->START_VALID, *m_jobQueue, *m_ledgerMaster, - *m_jobQueue, validatorKeys_, get_io_service(), logs_->journal("NetworkOPs"), @@ -1718,6 +1717,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + m_networkOPs->stop(); m_ledgerMaster->stop(); m_loadManager->stop(); JLOG(m_journal.info()) << "Done."; diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp index 9e5c36df3b7..7fde2999d67 100644 --- a/src/ripple/app/misc/NetworkOPs.cpp +++ b/src/ripple/app/misc/NetworkOPs.cpp @@ -223,13 +223,11 @@ class NetworkOPsImp final : public NetworkOPs bool start_valid, JobQueue& job_queue, LedgerMaster& ledgerMaster, - Stoppable& parent, ValidatorKeys const& validatorKeys, boost::asio::io_service& io_svc, beast::Journal journal, beast::insight::Collector::ptr const& collector) - : NetworkOPs(parent) - , app_(app) + : app_(app) , m_clock(clock) , m_journal(journal) , m_localTX(make_LocalTxs()) @@ -611,12 +609,8 @@ class NetworkOPsImp final : public NetworkOPs bool tryRemoveRpcSub(std::string const& strUrl) override; - //-------------------------------------------------------------------------- - // - // Stoppable. - void - onStop() override + stop() override { { boost::system::error_code ec; @@ -4091,15 +4085,6 @@ NetworkOPsImp::collect_metrics() counters[static_cast(OperatingMode::FULL)].transitions); } -//------------------------------------------------------------------------------ - -NetworkOPs::NetworkOPs(Stoppable& parent) - : InfoSub::Source("NetworkOPs", parent) -{ -} - -//------------------------------------------------------------------------------ - void NetworkOPsImp::StateAccounting::mode(OperatingMode om) { @@ -4148,7 +4133,6 @@ make_NetworkOPs( bool startvalid, JobQueue& job_queue, LedgerMaster& ledgerMaster, - Stoppable& parent, ValidatorKeys const& validatorKeys, boost::asio::io_service& io_svc, beast::Journal journal, @@ -4162,7 +4146,6 @@ make_NetworkOPs( startvalid, job_queue, ledgerMaster, - parent, validatorKeys, io_svc, journal, diff --git a/src/ripple/app/misc/NetworkOPs.h b/src/ripple/app/misc/NetworkOPs.h index 04ebe08afb3..051ce220c0f 100644 --- a/src/ripple/app/misc/NetworkOPs.h +++ b/src/ripple/app/misc/NetworkOPs.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -87,9 +86,6 @@ enum class OperatingMode { */ class NetworkOPs : public InfoSub::Source { -protected: - explicit NetworkOPs(Stoppable& parent); - public: using clock_type = beast::abstract_clock; @@ -103,6 +99,9 @@ class NetworkOPs : public InfoSub::Source public: ~NetworkOPs() override = default; + virtual void + stop() = 0; + //-------------------------------------------------------------------------- // // Network information @@ -337,7 +336,6 @@ make_NetworkOPs( bool start_valid, JobQueue& job_queue, LedgerMaster& ledgerMaster, - Stoppable& parent, ValidatorKeys const& validatorKeys, boost::asio::io_service& io_svc, beast::Journal journal, diff --git a/src/ripple/net/InfoSub.h b/src/ripple/net/InfoSub.h index b1ef6e25be1..c776e6f99bd 100644 --- a/src/ripple/net/InfoSub.h +++ b/src/ripple/net/InfoSub.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -53,12 +52,11 @@ class InfoSub : public CountedObject public: /** Abstracts the source of subscription data. */ - class Source : public Stoppable + class Source { - protected: - Source(char const* name, Stoppable& parent); - public: + virtual ~Source() = default; + // For some reason, these were originally called "rt" // for "real time". They actually refer to whether // you get transactions as they occur or once their diff --git a/src/ripple/net/impl/InfoSub.cpp b/src/ripple/net/impl/InfoSub.cpp index a13b7f736b3..19cdb5364de 100644 --- a/src/ripple/net/impl/InfoSub.cpp +++ b/src/ripple/net/impl/InfoSub.cpp @@ -33,15 +33,6 @@ namespace ripple { // code assumes this node is synched (and will continue to do so until // there's a functional network. -//------------------------------------------------------------------------------ - -InfoSub::Source::Source(char const* name, Stoppable& parent) - : Stoppable(name, parent) -{ -} - -//------------------------------------------------------------------------------ - InfoSub::InfoSub(Source& source) : m_source(source), mSeq(assign_id()) { } From eb686565f6174280bc141d428a5f7ee441bac90e Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 6 Jan 2021 15:35:06 -0600 Subject: [PATCH 24/62] [fold] Remove unused include --- src/ripple/net/RPCSub.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ripple/net/RPCSub.h b/src/ripple/net/RPCSub.h index e62aeeb4ca7..e2193b1ce1a 100644 --- a/src/ripple/net/RPCSub.h +++ b/src/ripple/net/RPCSub.h @@ -21,7 +21,6 @@ #define RIPPLE_NET_RPCSUB_H_INCLUDED #include -#include #include #include From 2d261552c978728caaf70822bf34d2a6965ad87b Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 6 Jan 2021 15:41:46 -0600 Subject: [PATCH 25/62] [fold] GRPCServer is not a Stoppable --- src/ripple/app/main/Application.cpp | 3 ++- src/ripple/app/main/GRPCServer.cpp | 2 +- src/ripple/app/main/GRPCServer.h | 10 ++++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 02632abe369..0cb8dc2a968 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -452,7 +452,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp logs_->journal("Application"), std::chrono::milliseconds(100), get_io_service()) - , grpcServer_(std::make_unique(*this, *m_jobQueue)) + , grpcServer_(std::make_unique(*this)) , reportingETL_(std::make_unique(*this, *this)) { add(m_resourceManager.get()); @@ -1717,6 +1717,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + grpcServer_->stop(); m_networkOPs->stop(); m_ledgerMaster->stop(); m_loadManager->stop(); diff --git a/src/ripple/app/main/GRPCServer.cpp b/src/ripple/app/main/GRPCServer.cpp index e7742b7a871..892cc883b40 100644 --- a/src/ripple/app/main/GRPCServer.cpp +++ b/src/ripple/app/main/GRPCServer.cpp @@ -789,7 +789,7 @@ GRPCServer::start() } void -GRPCServer::onStop() +GRPCServer::stop() { if (running_) { diff --git a/src/ripple/app/main/GRPCServer.h b/src/ripple/app/main/GRPCServer.h index 81f1dd4e63d..79780e10137 100644 --- a/src/ripple/app/main/GRPCServer.h +++ b/src/ripple/app/main/GRPCServer.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -294,11 +293,10 @@ class GRPCServerImpl final }; // GRPCServerImpl -class GRPCServer : public Stoppable +class GRPCServer { public: - explicit GRPCServer(Application& app, Stoppable& parent) - : Stoppable("GRPCServer", parent), impl_(app) + explicit GRPCServer(Application& app) : impl_(app) { } @@ -311,9 +309,9 @@ class GRPCServer : public Stoppable start(); void - onStop() override; + stop(); - ~GRPCServer() override; + ~GRPCServer(); private: GRPCServerImpl impl_; From 727b34985bab623ab18d2daae2aad3fc48c8cccd Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 6 Jan 2021 18:19:45 -0600 Subject: [PATCH 26/62] [fold] PerfLogImp is not a Stoppable --- src/ripple/app/main/Application.cpp | 10 ++--- src/ripple/basics/PerfLog.h | 20 --------- src/ripple/basics/impl/PerfLogImp.cpp | 18 +++----- src/ripple/basics/impl/PerfLogImp.h | 18 +++++--- src/test/basics/PerfLog_test.cpp | 60 +++++++++------------------ src/test/core/Workers_test.cpp | 5 --- 6 files changed, 42 insertions(+), 89 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 0cb8dc2a968..7348689834c 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -46,8 +46,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -158,7 +158,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::unique_ptr timeKeeper_; beast::Journal m_journal; - std::unique_ptr perfLog_; + std::unique_ptr perfLog_; Application::MutexType m_masterMutex; // Required by the SHAMapStore @@ -270,13 +270,12 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , m_journal(logs_->journal("Application")) // PerfLog must be started before any other threads are launched. - , perfLog_(perf::make_PerfLog( + , perfLog_(perf::make_PerfLogImp( perf::setup_PerfLog( config_->section("perf"), config_->CONFIG_DIR), - *this, logs_->journal("PerfLog"), - [this]() { signalStop(); })) + [&] { signalStop(); })) , m_txMaster(*this) #ifdef RIPPLED_REPORTING @@ -1717,6 +1716,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + perfLog_->stop(); grpcServer_->stop(); m_networkOPs->stop(); m_ledgerMaster->stop(); diff --git a/src/ripple/basics/PerfLog.h b/src/ripple/basics/PerfLog.h index 46673828761..b1ec2603252 100644 --- a/src/ripple/basics/PerfLog.h +++ b/src/ripple/basics/PerfLog.h @@ -66,9 +66,6 @@ class PerfLog virtual ~PerfLog() = default; - virtual void - start() = 0; - /** * Log start of RPC call. * @@ -160,23 +157,6 @@ class PerfLog rotate() = 0; }; -} // namespace perf - -class Section; -class Stoppable; - -namespace perf { - -PerfLog::Setup -setup_PerfLog(Section const& section, boost::filesystem::path const& configDir); - -std::unique_ptr -make_PerfLog( - PerfLog::Setup const& setup, - Stoppable& parent, - beast::Journal journal, - std::function&& signalStop); - } // namespace perf } // namespace ripple diff --git a/src/ripple/basics/impl/PerfLogImp.cpp b/src/ripple/basics/impl/PerfLogImp.cpp index 29d726ec813..860368d6b01 100644 --- a/src/ripple/basics/impl/PerfLogImp.cpp +++ b/src/ripple/basics/impl/PerfLogImp.cpp @@ -313,20 +313,16 @@ PerfLogImp::report() PerfLogImp::PerfLogImp( Setup const& setup, - Stoppable& parent, beast::Journal journal, std::function&& signalStop) - : Stoppable("PerfLogImp", parent) - , setup_(setup) - , j_(journal) - , signalStop_(std::move(signalStop)) + : setup_(setup), j_(journal), signalStop_(std::move(signalStop)) { openLog(); } PerfLogImp::~PerfLogImp() { - onStop(); + stop(); } void @@ -466,7 +462,7 @@ PerfLogImp::start() } void -PerfLogImp::onStop() +PerfLogImp::stop() { if (thread_.joinable()) { @@ -503,15 +499,13 @@ setup_PerfLog(Section const& section, boost::filesystem::path const& configDir) return setup; } -std::unique_ptr -make_PerfLog( +std::unique_ptr +make_PerfLogImp( PerfLog::Setup const& setup, - Stoppable& parent, beast::Journal journal, std::function&& signalStop) { - return std::make_unique( - setup, parent, journal, std::move(signalStop)); + return std::make_unique(setup, journal, std::move(signalStop)); } } // namespace perf diff --git a/src/ripple/basics/impl/PerfLogImp.h b/src/ripple/basics/impl/PerfLogImp.h index 02e4401edf7..c556d463788 100644 --- a/src/ripple/basics/impl/PerfLogImp.h +++ b/src/ripple/basics/impl/PerfLogImp.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,7 @@ namespace perf { /** * Implementation class for PerfLog. */ -class PerfLogImp : public PerfLog, Stoppable +class PerfLogImp : public PerfLog { /** * Track performance counters and currently executing tasks. @@ -161,7 +160,6 @@ class PerfLogImp : public PerfLog, Stoppable public: PerfLogImp( Setup const& setup, - Stoppable& parent, beast::Journal journal, std::function&& signalStop); @@ -211,13 +209,21 @@ class PerfLogImp : public PerfLog, Stoppable rotate() override; void - start() override; + start(); - // Called when the application begins shutdown. void - onStop() override; + stop(); }; +PerfLog::Setup +setup_PerfLog(Section const& section, boost::filesystem::path const& configDir); + +std::unique_ptr +make_PerfLogImp( + PerfLog::Setup const& setup, + beast::Journal journal, + std::function&& signalStop); + } // namespace perf } // namespace ripple diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index ba48ab6696e..9fe15478e50 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include #include #include #include @@ -45,19 +45,11 @@ class PerfLog_test : public beast::unit_test::suite test::jtx::Env env_{*this}; beast::Journal j_{env_.app().journal("PerfLog_test")}; - // A PerfLog needs a Parent that is a Stoppable and a function to - // call if it wants to shutdown the system. This class provides both. - struct PerfLogParent : public RootStoppable + struct PerfLogParent { bool stopSignaled{false}; - beast::Journal j_; - explicit PerfLogParent(beast::Journal const& j) - : RootStoppable("testRootStoppable"), j_(j) - { - } - - ~PerfLogParent() override + ~PerfLogParent() { cleanupPerfLogDir(); } @@ -69,21 +61,7 @@ class PerfLog_test : public beast::unit_test::suite stopSignaled = true; } - private: - // Interfaces for RootStoppable. Made private to encourage the use - // of doStop(). - void - onStop() override - { - } - public: - void - doStop() - { - stop(j_); - } - // Interfaces for PerfLog file management static path getPerfLogPath() @@ -136,11 +114,11 @@ class PerfLog_test : public beast::unit_test::suite //------------------------------------------------------------------------------ // Convenience function to return a PerfLog - std::unique_ptr + std::unique_ptr getPerfLog(PerfLogParent& parent, WithFile withFile) { - return perf::make_PerfLog( - parent.getSetup(withFile), parent, j_, [&parent]() { + return perf::make_PerfLogImp( + parent.getSetup(withFile), j_, [&parent]() { return parent.signalStop(); }); } @@ -242,7 +220,7 @@ class PerfLog_test : public beast::unit_test::suite auto const fullPath = perfLogPath / PerfLogParent::getPerfLogFileName(); { // Verify a PerfLog creates its file when constructed. - PerfLogParent parent{j_}; + PerfLogParent parent; BEAST_EXPECT(!exists(perfLogPath)); auto perfLog{getPerfLog(parent, WithFile::yes)}; @@ -254,7 +232,7 @@ class PerfLog_test : public beast::unit_test::suite // Create a file where PerfLog wants to put its directory. // Make sure that PerfLog tries to shutdown the server since it // can't open its file. - PerfLogParent parent{j_}; + PerfLogParent parent; if (!BEAST_EXPECT(!exists(perfLogPath))) return; @@ -279,7 +257,7 @@ class PerfLog_test : public beast::unit_test::suite // problems. perfLog->start(); std::this_thread::sleep_for(parent.getLogInterval() * 10); - parent.doStop(); + perfLog->stop(); // Remove the file. remove(perfLogPath); @@ -288,7 +266,7 @@ class PerfLog_test : public beast::unit_test::suite // Put a write protected file where PerfLog wants to write its // file. Make sure that PerfLog tries to shutdown the server // since it can't open its file. - PerfLogParent parent{j_}; + PerfLogParent parent; if (!BEAST_EXPECT(!exists(perfLogPath))) return; @@ -332,7 +310,7 @@ class PerfLog_test : public beast::unit_test::suite // problems. perfLog->start(); std::this_thread::sleep_for(parent.getLogInterval() * 10); - parent.doStop(); + perfLog->stop(); // Fix file permissions so the file can be cleaned up. boost::filesystem::permissions( @@ -347,7 +325,7 @@ class PerfLog_test : public beast::unit_test::suite { // Exercise the rpc interfaces of PerfLog. // Start up the PerfLog that we'll use for testing. - PerfLogParent parent{j_}; + PerfLogParent parent; auto perfLog{getPerfLog(parent, withFile)}; perfLog->start(); @@ -510,7 +488,7 @@ class PerfLog_test : public beast::unit_test::suite waitForFileUpdate(parent); // Politely stop the PerfLog. - parent.doStop(); + perfLog->stop(); auto const fullPath = parent.getPerfLogPath() / parent.getPerfLogFileName(); @@ -553,7 +531,7 @@ class PerfLog_test : public beast::unit_test::suite // Exercise the jobs interfaces of PerfLog. // Start up the PerfLog that we'll use for testing. - PerfLogParent parent{j_}; + PerfLogParent parent; auto perfLog{getPerfLog(parent, withFile)}; perfLog->start(); @@ -855,7 +833,7 @@ class PerfLog_test : public beast::unit_test::suite waitForFileUpdate(parent); // Politely stop the PerfLog. - parent.doStop(); + perfLog->stop(); // Check file contents if that is appropriate. auto const fullPath = @@ -901,7 +879,7 @@ class PerfLog_test : public beast::unit_test::suite // the PerLog behaves as well as possible if an invalid ID is passed. // Start up the PerfLog that we'll use for testing. - PerfLogParent parent{j_}; + PerfLogParent parent; auto perfLog{getPerfLog(parent, withFile)}; perfLog->start(); @@ -997,7 +975,7 @@ class PerfLog_test : public beast::unit_test::suite waitForFileUpdate(parent); // Politely stop the PerfLog. - parent.doStop(); + perfLog->stop(); // Check file contents if that is appropriate. auto const fullPath = @@ -1045,7 +1023,7 @@ class PerfLog_test : public beast::unit_test::suite auto const perfLogPath{PerfLogParent::getPerfLogPath()}; auto const fullPath = perfLogPath / PerfLogParent::getPerfLogFileName(); - PerfLogParent parent{j_}; + PerfLogParent parent; BEAST_EXPECT(!exists(perfLogPath)); auto perfLog{getPerfLog(parent, withFile)}; @@ -1081,7 +1059,7 @@ class PerfLog_test : public beast::unit_test::suite perfLog->rotate(); waitForFileUpdate(parent); - parent.doStop(); + perfLog->stop(); if (withFile == WithFile::no) { diff --git a/src/test/core/Workers_test.cpp b/src/test/core/Workers_test.cpp index d0c3ef9dec0..7243732af10 100644 --- a/src/test/core/Workers_test.cpp +++ b/src/test/core/Workers_test.cpp @@ -95,11 +95,6 @@ class PerfLogTest : public PerfLog rotate() override { } - - void - start() override - { - } }; } // namespace perf From 3e08270f22a06e6ee345691f710d2e209b7fc2c0 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Thu, 7 Jan 2021 08:47:10 -0600 Subject: [PATCH 27/62] [fold] Use a fixture for PerfLog tests --- src/test/basics/PerfLog_test.cpp | 246 +++++++++++++------------------ 1 file changed, 106 insertions(+), 140 deletions(-) diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index 9fe15478e50..bffd2d2e6a4 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -20,11 +20,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -45,96 +47,101 @@ class PerfLog_test : public beast::unit_test::suite test::jtx::Env env_{*this}; beast::Journal j_{env_.app().journal("PerfLog_test")}; - struct PerfLogParent + struct Fixture { + beast::Journal j_; bool stopSignaled{false}; - ~PerfLogParent() + Fixture(beast::Journal const& j) : j_(j) { - cleanupPerfLogDir(); } - // Benign replacement for Application::signalStop(). + ~Fixture() + { + using namespace boost::filesystem; + + auto const dir{logDir()}; + auto const file{logFile()}; + if (exists(file)) + remove(file); + + if (!exists(dir) || !is_directory(dir) || !is_empty(dir)) + { + return; + } + remove(dir); + } + void signalStop() { stopSignaled = true; } - public: - // Interfaces for PerfLog file management - static path - getPerfLogPath() + path + logDir() const { using namespace boost::filesystem; return temp_directory_path() / "perf_log_test_dir"; } - static path - getPerfLogFileName() + path + logFile() const { - return {"perf_log.txt"}; + return logDir() / "perf_log.txt"; } - static std::chrono::milliseconds - getLogInterval() + std::chrono::milliseconds + logInterval() const { return std::chrono::milliseconds{10}; } - static perf::PerfLog::Setup - getSetup(WithFile withFile) + std::unique_ptr + perfLog(WithFile withFile) { - return perf::PerfLog::Setup{ - withFile == WithFile::no - ? "" - : getPerfLogPath() / getPerfLogFileName(), - getLogInterval()}; + perf::PerfLog::Setup const setup{ + withFile == WithFile::no ? "" : logFile(), logInterval()}; + return perf::make_PerfLogImp( + setup, j_, [this]() { return signalStop(); }); } - static void - cleanupPerfLogDir() + // Block until the log file has grown in size, indicating that the + // PerfLog has written new values to the file and _should_ have the + // latest update. + void + wait() const { using namespace boost::filesystem; - auto const perfLogPath{getPerfLogPath()}; - auto const fullPath = perfLogPath / getPerfLogFileName(); - if (exists(fullPath)) - remove(fullPath); + auto const path = logFile(); + if (!exists(path)) + return; - if (!exists(perfLogPath) || !is_directory(perfLogPath) || - !is_empty(perfLogPath)) + // We wait for the file to change size twice. The first file size + // change may have been in process while we arrived. + std::uintmax_t const firstSize{file_size(path)}; + std::uintmax_t secondSize{firstSize}; + do { - return; - } - remove(perfLogPath); + std::this_thread::sleep_for(logInterval()); + secondSize = file_size(path); + } while (firstSize >= secondSize); + + do + { + std::this_thread::sleep_for(logInterval()); + } while (secondSize >= file_size(path)); } }; - //------------------------------------------------------------------------------ - - // Convenience function to return a PerfLog - std::unique_ptr - getPerfLog(PerfLogParent& parent, WithFile withFile) - { - return perf::make_PerfLogImp( - parent.getSetup(withFile), j_, [&parent]() { - return parent.signalStop(); - }); - } - - //------------------------------------------------------------------------------ - - // Convenience function to return a uint64 given a Json::Value containing - // a string. + // Return a uint64 from a JSON string. static std::uint64_t jsonToUint64(Json::Value const& jsonUintAsString) { return std::stoull(jsonUintAsString.asString()); } - //------------------------------------------------------------------------------ - // The PerfLog's current state is easier to sort by duration if the // duration is converted from string to integer. The following struct // is a way to think about the converted entry. @@ -177,70 +184,35 @@ class PerfLog_test : public beast::unit_test::suite return currents; } - //------------------------------------------------------------------------------ - - // Helper function that checks the size of the PerfLog file and then - // returns when the file gets bigger. This indicates that the PerfLog - // has written new values to the file and _should_ have the latest - // update. - static void - waitForFileUpdate(PerfLogParent const& parent) - { - using namespace boost::filesystem; - - auto const path = parent.getPerfLogPath() / parent.getPerfLogFileName(); - if (!exists(path)) - return; - - // We wait for the file to change size twice. The first file size - // change may have been in process while we arrived. - std::uintmax_t const firstSize{file_size(path)}; - std::uintmax_t secondSize{firstSize}; - do - { - std::this_thread::sleep_for(parent.getLogInterval()); - secondSize = file_size(path); - } while (firstSize >= secondSize); - - do - { - std::this_thread::sleep_for(parent.getLogInterval()); - } while (secondSize >= file_size(path)); - } - - //------------------------------------------------------------------------------ - public: void testFileCreation() { using namespace boost::filesystem; - auto const perfLogPath{PerfLogParent::getPerfLogPath()}; - auto const fullPath = perfLogPath / PerfLogParent::getPerfLogFileName(); { // Verify a PerfLog creates its file when constructed. - PerfLogParent parent; - BEAST_EXPECT(!exists(perfLogPath)); + Fixture fixture{j_}; + BEAST_EXPECT(!exists(fixture.logDir())); - auto perfLog{getPerfLog(parent, WithFile::yes)}; + auto perfLog{fixture.perfLog(WithFile::yes)}; - BEAST_EXPECT(parent.stopSignaled == false); - BEAST_EXPECT(exists(perfLogPath)); + BEAST_EXPECT(fixture.stopSignaled == false); + BEAST_EXPECT(exists(fixture.logDir())); } { // Create a file where PerfLog wants to put its directory. // Make sure that PerfLog tries to shutdown the server since it // can't open its file. - PerfLogParent parent; - if (!BEAST_EXPECT(!exists(perfLogPath))) + Fixture fixture{j_}; + if (!BEAST_EXPECT(!exists(fixture.logDir()))) return; { // Make a file that prevents PerfLog from creating its file. std::ofstream nastyFile; nastyFile.open( - perfLogPath.c_str(), std::ios::out | std::ios::app); + fixture.logDir().c_str(), std::ios::out | std::ios::app); if (!BEAST_EXPECT(nastyFile)) return; nastyFile.close(); @@ -248,32 +220,32 @@ class PerfLog_test : public beast::unit_test::suite // Now construct a PerfLog. The PerfLog should attempt to shut // down the server because it can't open its file. - BEAST_EXPECT(parent.stopSignaled == false); - auto perfLog{getPerfLog(parent, WithFile::yes)}; - BEAST_EXPECT(parent.stopSignaled == true); + BEAST_EXPECT(fixture.stopSignaled == false); + auto perfLog{fixture.perfLog(WithFile::yes)}; + BEAST_EXPECT(fixture.stopSignaled == true); // Start PerfLog and wait long enough for PerfLog::report() // to not be able to write to its file. That should cause no // problems. perfLog->start(); - std::this_thread::sleep_for(parent.getLogInterval() * 10); + std::this_thread::sleep_for(fixture.logInterval() * 10); perfLog->stop(); // Remove the file. - remove(perfLogPath); + remove(fixture.logDir()); } { // Put a write protected file where PerfLog wants to write its // file. Make sure that PerfLog tries to shutdown the server // since it can't open its file. - PerfLogParent parent; - if (!BEAST_EXPECT(!exists(perfLogPath))) + Fixture fixture{j_}; + if (!BEAST_EXPECT(!exists(fixture.logDir()))) return; // Construct and write protect a file to prevent PerfLog // from creating its file. boost::system::error_code ec; - boost::filesystem::create_directories(perfLogPath, ec); + boost::filesystem::create_directories(fixture.logDir(), ec); if (!BEAST_EXPECT(!ec)) return; @@ -282,17 +254,17 @@ class PerfLog_test : public beast::unit_test::suite .is_open(); }; - if (!BEAST_EXPECT(fileWriteable(fullPath))) + if (!BEAST_EXPECT(fileWriteable(fixture.logFile()))) return; boost::filesystem::permissions( - fullPath, + fixture.logFile(), perms::remove_perms | perms::owner_write | perms::others_write | perms::group_write); // If the test is running as root, then the write protect may have // no effect. Make sure write protect worked before proceeding. - if (fileWriteable(fullPath)) + if (fileWriteable(fixture.logFile())) { log << "Unable to write protect file. Test skipped." << std::endl; @@ -301,20 +273,20 @@ class PerfLog_test : public beast::unit_test::suite // Now construct a PerfLog. The PerfLog should attempt to shut // down the server because it can't open its file. - BEAST_EXPECT(parent.stopSignaled == false); - auto perfLog{getPerfLog(parent, WithFile::yes)}; - BEAST_EXPECT(parent.stopSignaled == true); + BEAST_EXPECT(fixture.stopSignaled == false); + auto perfLog{fixture.perfLog(WithFile::yes)}; + BEAST_EXPECT(fixture.stopSignaled == true); // Start PerfLog and wait long enough for PerfLog::report() // to not be able to write to its file. That should cause no // problems. perfLog->start(); - std::this_thread::sleep_for(parent.getLogInterval() * 10); + std::this_thread::sleep_for(fixture.logInterval() * 10); perfLog->stop(); // Fix file permissions so the file can be cleaned up. boost::filesystem::permissions( - fullPath, + fixture.logFile(), perms::add_perms | perms::owner_write | perms::others_write | perms::group_write); } @@ -325,8 +297,8 @@ class PerfLog_test : public beast::unit_test::suite { // Exercise the rpc interfaces of PerfLog. // Start up the PerfLog that we'll use for testing. - PerfLogParent parent; - auto perfLog{getPerfLog(parent, withFile)}; + Fixture fixture{j_}; + auto perfLog{fixture.perfLog(withFile)}; perfLog->start(); // Get the all the labels we can use for RPC interfaces without @@ -485,13 +457,12 @@ class PerfLog_test : public beast::unit_test::suite validateFinalCurrent(perfLog->currentJson()); // Give the PerfLog enough time to flush it's state to the file. - waitForFileUpdate(parent); + fixture.wait(); // Politely stop the PerfLog. perfLog->stop(); - auto const fullPath = - parent.getPerfLogPath() / parent.getPerfLogFileName(); + auto const fullPath = fixture.logFile(); if (withFile == WithFile::no) { @@ -531,8 +502,8 @@ class PerfLog_test : public beast::unit_test::suite // Exercise the jobs interfaces of PerfLog. // Start up the PerfLog that we'll use for testing. - PerfLogParent parent; - auto perfLog{getPerfLog(parent, withFile)}; + Fixture fixture{j_}; + auto perfLog{fixture.perfLog(withFile)}; perfLog->start(); // Get the all the JobTypes we can use to call the jobs interfaces @@ -830,14 +801,13 @@ class PerfLog_test : public beast::unit_test::suite validateFinalCurrent(perfLog->currentJson()); // Give the PerfLog enough time to flush it's state to the file. - waitForFileUpdate(parent); + fixture.wait(); // Politely stop the PerfLog. perfLog->stop(); // Check file contents if that is appropriate. - auto const fullPath = - parent.getPerfLogPath() / parent.getPerfLogFileName(); + auto const fullPath = fixture.logFile(); if (withFile == WithFile::no) { @@ -879,8 +849,8 @@ class PerfLog_test : public beast::unit_test::suite // the PerLog behaves as well as possible if an invalid ID is passed. // Start up the PerfLog that we'll use for testing. - PerfLogParent parent; - auto perfLog{getPerfLog(parent, withFile)}; + Fixture fixture{j_}; + auto perfLog{fixture.perfLog(withFile)}; perfLog->start(); // Randomly select a job type and its name. @@ -972,14 +942,13 @@ class PerfLog_test : public beast::unit_test::suite verifyEmptyCurrent(perfLog->currentJson()); // Give the PerfLog enough time to flush it's state to the file. - waitForFileUpdate(parent); + fixture.wait(); // Politely stop the PerfLog. perfLog->stop(); // Check file contents if that is appropriate. - auto const fullPath = - parent.getPerfLogPath() / parent.getPerfLogFileName(); + auto const fullPath = fixture.logFile(); if (withFile == WithFile::no) { @@ -1020,54 +989,51 @@ class PerfLog_test : public beast::unit_test::suite // the interface and see that it doesn't crash. using namespace boost::filesystem; - auto const perfLogPath{PerfLogParent::getPerfLogPath()}; - auto const fullPath = perfLogPath / PerfLogParent::getPerfLogFileName(); - - PerfLogParent parent; - BEAST_EXPECT(!exists(perfLogPath)); + Fixture fixture{j_}; + BEAST_EXPECT(!exists(fixture.logDir())); - auto perfLog{getPerfLog(parent, withFile)}; + auto perfLog{fixture.perfLog(withFile)}; - BEAST_EXPECT(parent.stopSignaled == false); + BEAST_EXPECT(fixture.stopSignaled == false); if (withFile == WithFile::no) { - BEAST_EXPECT(!exists(perfLogPath)); + BEAST_EXPECT(!exists(fixture.logDir())); } else { - BEAST_EXPECT(exists(fullPath)); - BEAST_EXPECT(file_size(fullPath) == 0); + BEAST_EXPECT(exists(fixture.logFile())); + BEAST_EXPECT(file_size(fixture.logFile()) == 0); } // Start PerfLog and wait long enough for PerfLog::report() // to write to its file. perfLog->start(); - waitForFileUpdate(parent); + fixture.wait(); - decltype(file_size(fullPath)) firstFileSize{0}; + decltype(file_size(fixture.logFile())) firstFileSize{0}; if (withFile == WithFile::no) { - BEAST_EXPECT(!exists(perfLogPath)); + BEAST_EXPECT(!exists(fixture.logDir())); } else { - firstFileSize = file_size(fullPath); + firstFileSize = file_size(fixture.logFile()); BEAST_EXPECT(firstFileSize > 0); } // Rotate and then wait to make sure more stuff is written to the file. perfLog->rotate(); - waitForFileUpdate(parent); + fixture.wait(); perfLog->stop(); if (withFile == WithFile::no) { - BEAST_EXPECT(!exists(perfLogPath)); + BEAST_EXPECT(!exists(fixture.logDir())); } else { - BEAST_EXPECT(file_size(fullPath) > firstFileSize); + BEAST_EXPECT(file_size(fixture.logFile()) > firstFileSize); } } From 15b7da18f71e290d82f667c15992cd1abea09455 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 8 Jan 2021 10:45:32 -0600 Subject: [PATCH 28/62] [fold] OverlayImpl is not a Stoppable --- src/ripple/app/main/Application.cpp | 6 ++--- src/ripple/overlay/Overlay.h | 12 +++------ src/ripple/overlay/impl/OverlayImpl.cpp | 34 +++++++++++-------------- src/ripple/overlay/impl/OverlayImpl.h | 25 +++++++----------- src/ripple/overlay/make_Overlay.h | 8 +++--- 5 files changed, 33 insertions(+), 52 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 7348689834c..e4d370da0d0 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -218,7 +218,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::unique_ptr mTxnDB; std::unique_ptr mLedgerDB; std::unique_ptr mWalletDB; - std::unique_ptr overlay_; + std::unique_ptr overlay_; std::vector> websocketServers_; boost::asio::signal_set m_signals; @@ -1496,10 +1496,9 @@ ApplicationImp::setup() // if (!config_.standalone()) if (!config_->reporting()) { - overlay_ = make_Overlay( + overlay_ = make_OverlayImpl( *this, setup_Overlay(*config_), - *m_jobQueue, *serverHandler_, *m_resourceManager, *m_resolver, @@ -1716,6 +1715,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + overlay_->stop(); perfLog_->stop(); grpcServer_->stop(); m_networkOPs->stop(); diff --git a/src/ripple/overlay/Overlay.h b/src/ripple/overlay/Overlay.h index 8b77c987b1e..d0c7b09ad26 100644 --- a/src/ripple/overlay/Overlay.h +++ b/src/ripple/overlay/Overlay.h @@ -21,7 +21,6 @@ #define RIPPLE_OVERLAY_OVERLAY_H_INCLUDED #include -#include #include #include #include @@ -49,7 +48,7 @@ class context; namespace ripple { /** Manages the set of connected peers. */ -class Overlay : public Stoppable, public beast::PropertyStream::Source +class Overlay : public beast::PropertyStream::Source { protected: using socket_type = boost::beast::tcp_stream; @@ -57,10 +56,8 @@ class Overlay : public Stoppable, public beast::PropertyStream::Source // VFALCO NOTE The requirement of this constructor is an // unfortunate problem with the API for - // Stoppable and PropertyStream - // - Overlay(Stoppable& parent) - : Stoppable("Overlay", parent), beast::PropertyStream::Source("peers") + // PropertyStream + Overlay() : beast::PropertyStream::Source("peers") { } @@ -83,9 +80,6 @@ class Overlay : public Stoppable, public beast::PropertyStream::Source virtual ~Overlay() = default; - virtual void - start() = 0; - /** Conditionally accept an incoming HTTP request. */ virtual Handoff onHandoff( diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 76cbf2f1a3e..503d5b55f46 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -72,14 +72,16 @@ OverlayImpl::Timer::Timer(OverlayImpl& overlay) void OverlayImpl::Timer::stop() { - error_code ec; - timer_.cancel(ec); + // This method is only ever called from the same strand that calls + // Timer::on_timer, ensuring they never execute concurrently. + stopping_ = true; + timer_.cancel(); } void -OverlayImpl::Timer::run() +OverlayImpl::Timer::start() { - timer_.expires_from_now(std::chrono::seconds(1)); + timer_.expires_after(std::chrono::seconds(1)); timer_.async_wait(overlay_.strand_.wrap(std::bind( &Timer::on_timer, shared_from_this(), std::placeholders::_1))); } @@ -87,7 +89,7 @@ OverlayImpl::Timer::run() void OverlayImpl::Timer::on_timer(error_code ec) { - if (ec || overlay_.isStopping()) + if (ec || stopping_) { if (ec && ec != boost::asio::error::operation_aborted) { @@ -103,9 +105,7 @@ OverlayImpl::Timer::on_timer(error_code ec) if ((overlay_.timer_count_ % Tuning::checkIdlePeers) == 0) overlay_.deleteIdlePeers(); - timer_.expires_from_now(std::chrono::seconds(1)); - timer_.async_wait(overlay_.strand_.wrap(std::bind( - &Timer::on_timer, shared_from_this(), std::placeholders::_1))); + start(); } //------------------------------------------------------------------------------ @@ -113,15 +113,13 @@ OverlayImpl::Timer::on_timer(error_code ec) OverlayImpl::OverlayImpl( Application& app, Setup const& setup, - Stoppable& parent, ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, boost::asio::io_service& io_service, BasicConfig const& config, beast::insight::Collector::ptr const& collector) - : Overlay(parent) - , app_(app) + : app_(app) , io_service_(io_service) , work_(boost::in_place(std::ref(io_service_))) , strand_(io_service_) @@ -543,13 +541,13 @@ OverlayImpl::start() std::lock_guard lock(mutex_); list_.emplace(timer.get(), timer); timer_ = timer; - timer->run(); + timer->start(); } void -OverlayImpl::onStop() +OverlayImpl::stop() { - strand_.dispatch(std::bind(&OverlayImpl::stop, this)); + strand_.dispatch(std::bind(&OverlayImpl::stopChildren, this)); { std::unique_lock lock(mutex_); cond_.wait(lock, [this] { return list_.empty(); }); @@ -1276,7 +1274,7 @@ OverlayImpl::remove(Child& child) } void -OverlayImpl::stop() +OverlayImpl::stopChildren() { // Calling list_[].second->stop() may cause list_ to be modified // (OverlayImpl::remove() may be called on this same thread). So @@ -1530,11 +1528,10 @@ setup_Overlay(BasicConfig const& config) return setup; } -std::unique_ptr -make_Overlay( +std::unique_ptr +make_OverlayImpl( Application& app, Overlay::Setup const& setup, - Stoppable& parent, ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, @@ -1545,7 +1542,6 @@ make_Overlay( return std::make_unique( app, setup, - parent, serverHandler, resourceManager, resolver, diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index 8384b5d918e..2c95aecd134 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -81,6 +81,7 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler struct Timer : Child, std::enable_shared_from_this { boost::asio::basic_waitable_timer timer_; + bool stopping_{false}; explicit Timer(OverlayImpl& overlay); @@ -88,7 +89,7 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler stop() override; void - run(); + start(); void on_timer(error_code ec); @@ -141,7 +142,6 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler OverlayImpl( Application& app, Setup const& setup, - Stoppable& parent, ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, @@ -153,6 +153,12 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler OverlayImpl& operator=(OverlayImpl const&) = delete; + void + start(); + + void + stop(); + PeerFinder::Manager& peerFinder() { @@ -498,19 +504,6 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler //-------------------------------------------------------------------------- - // - // Stoppable - // - - void - checkStopped(); - - void - start() override; - - void - onStop() override; - // // PropertyStream // @@ -524,7 +517,7 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler remove(Child& child); void - stop(); + stopChildren(); void autoConnect(); diff --git a/src/ripple/overlay/make_Overlay.h b/src/ripple/overlay/make_Overlay.h index 5a6b647b7a0..a8774fb4a1a 100644 --- a/src/ripple/overlay/make_Overlay.h +++ b/src/ripple/overlay/make_Overlay.h @@ -21,8 +21,7 @@ #define RIPPLE_OVERLAY_MAKE_OVERLAY_H_INCLUDED #include -#include -#include +#include #include #include #include @@ -34,11 +33,10 @@ Overlay::Setup setup_Overlay(BasicConfig const& config); /** Creates the implementation of Overlay. */ -std::unique_ptr -make_Overlay( +std::unique_ptr +make_OverlayImpl( Application& app, Overlay::Setup const& setup, - Stoppable& parent, ServerHandler& serverHandler, Resource::Manager& resourceManager, Resolver& resolver, From 4a150d13ce42516619aed5644591ad1323bfba3d Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 8 Jan 2021 11:36:26 -0600 Subject: [PATCH 29/62] [fold] InboundTransactionsImp is not a Stoppable --- src/ripple/app/ledger/InboundTransactions.h | 5 +++-- .../app/ledger/impl/InboundTransactions.cpp | 20 +++++++++---------- src/ripple/app/main/Application.cpp | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/ripple/app/ledger/InboundTransactions.h b/src/ripple/app/ledger/InboundTransactions.h index 1275ca77b1c..f5b44f38616 100644 --- a/src/ripple/app/ledger/InboundTransactions.h +++ b/src/ripple/app/ledger/InboundTransactions.h @@ -21,7 +21,6 @@ #define RIPPLE_APP_LEDGER_INBOUNDTRANSACTIONS_H_INCLUDED #include -#include #include #include #include @@ -85,12 +84,14 @@ class InboundTransactions */ virtual void newRound(std::uint32_t seq) = 0; + + virtual void + stop() = 0; }; std::unique_ptr make_InboundTransactions( Application& app, - Stoppable& parent, beast::insight::Collector::ptr const& collector, std::function const&, bool)> gotSet); diff --git a/src/ripple/app/ledger/impl/InboundTransactions.cpp b/src/ripple/app/ledger/impl/InboundTransactions.cpp index f3819bb1d8d..e549369a700 100644 --- a/src/ripple/app/ledger/impl/InboundTransactions.cpp +++ b/src/ripple/app/ledger/impl/InboundTransactions.cpp @@ -58,18 +58,14 @@ class InboundTransactionSet } }; -class InboundTransactionsImp : public InboundTransactions, public Stoppable +class InboundTransactionsImp : public InboundTransactions { public: - Application& app_; - InboundTransactionsImp( Application& app, - Stoppable& parent, beast::insight::Collector::ptr const& collector, std::function const&, bool)> gotSet) - : Stoppable("InboundTransactions", parent) - , app_(app) + : app_(app) , m_seq(0) , m_zeroSet(m_map[uint256()]) , m_gotSet(std::move(gotSet)) @@ -116,7 +112,7 @@ class InboundTransactionsImp : public InboundTransactions, public Stoppable return it->second.mSet; } - if (!acquire || isStopping()) + if (!acquire || stopping_) return std::shared_ptr(); ta = std::make_shared(app_, hash); @@ -239,18 +235,21 @@ class InboundTransactionsImp : public InboundTransactions, public Stoppable } void - onStop() override + stop() override { std::lock_guard lock(mLock); - + stopping_ = true; m_map.clear(); } private: using MapType = hash_map; + Application& app_; + std::recursive_mutex mLock; + bool stopping_{false}; MapType m_map; std::uint32_t m_seq; @@ -267,12 +266,11 @@ InboundTransactions::~InboundTransactions() = default; std::unique_ptr make_InboundTransactions( Application& app, - Stoppable& parent, beast::insight::Collector::ptr const& collector, std::function const&, bool)> gotSet) { return std::make_unique( - app, parent, collector, std::move(gotSet)); + app, collector, std::move(gotSet)); } } // namespace ripple diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index e4d370da0d0..60fc1a498e4 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -361,7 +361,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , m_inboundTransactions(make_InboundTransactions( *this, - *m_jobQueue, m_collectorManager->collector(), [this](std::shared_ptr const& set, bool fromAcquire) { gotTXSet(set, fromAcquire); @@ -1715,6 +1714,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + m_inboundTransactions->stop(); overlay_->stop(); perfLog_->stop(); grpcServer_->stop(); From 2b35d462ea70638e2074dcba83aa3110c1a049da Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 8 Jan 2021 13:10:28 -0600 Subject: [PATCH 30/62] [fold] InboundLedgersImp is not a Stoppable --- src/ripple/app/ledger/InboundLedgers.h | 4 +--- src/ripple/app/ledger/impl/InboundLedgers.cpp | 20 +++++++++---------- src/ripple/app/main/Application.cpp | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/ripple/app/ledger/InboundLedgers.h b/src/ripple/app/ledger/InboundLedgers.h index ae27b03d9ce..dca4a80c54b 100644 --- a/src/ripple/app/ledger/InboundLedgers.h +++ b/src/ripple/app/ledger/InboundLedgers.h @@ -21,7 +21,6 @@ #define RIPPLE_APP_LEDGER_INBOUNDLEDGERS_H_INCLUDED #include -#include #include #include @@ -83,14 +82,13 @@ class InboundLedgers sweep() = 0; virtual void - onStop() = 0; + stop() = 0; }; std::unique_ptr make_InboundLedgers( Application& app, InboundLedgers::clock_type& clock, - Stoppable& parent, beast::insight::Collector::ptr const& collector); } // namespace ripple diff --git a/src/ripple/app/ledger/impl/InboundLedgers.cpp b/src/ripple/app/ledger/impl/InboundLedgers.cpp index 1d7ff081bac..11ea9df3254 100644 --- a/src/ripple/app/ledger/impl/InboundLedgers.cpp +++ b/src/ripple/app/ledger/impl/InboundLedgers.cpp @@ -33,7 +33,7 @@ namespace ripple { -class InboundLedgersImp : public InboundLedgers, public Stoppable +class InboundLedgersImp : public InboundLedgers { private: Application& app_; @@ -49,10 +49,8 @@ class InboundLedgersImp : public InboundLedgers, public Stoppable InboundLedgersImp( Application& app, clock_type& clock, - Stoppable& parent, beast::insight::Collector::ptr const& collector) - : Stoppable("InboundLedgers", parent) - , app_(app) + : app_(app) , fetchRate_(clock.now()) , j_(app.journal("InboundLedger")) , m_clock(clock) @@ -72,13 +70,15 @@ class InboundLedgersImp : public InboundLedgers, public Stoppable assert( reason != InboundLedger::Reason::SHARD || (seq != 0 && app_.getShardStore())); - if (isStopping()) - return {}; bool isNew = true; std::shared_ptr inbound; { ScopedLockType sl(mLock); + if (stopping_) + { + return {}; + } auto it = mLedgers.find(hash); if (it != mLedgers.end()) { @@ -382,10 +382,10 @@ class InboundLedgersImp : public InboundLedgers, public Stoppable } void - onStop() override + stop() override { ScopedLockType lock(mLock); - + stopping_ = true; mLedgers.clear(); mRecentFailures.clear(); } @@ -396,6 +396,7 @@ class InboundLedgersImp : public InboundLedgers, public Stoppable using ScopedLockType = std::unique_lock; std::recursive_mutex mLock; + bool stopping_ = false; using MapType = hash_map>; MapType mLedgers; @@ -410,10 +411,9 @@ std::unique_ptr make_InboundLedgers( Application& app, InboundLedgers::clock_type& clock, - Stoppable& parent, beast::insight::Collector::ptr const& collector) { - return std::make_unique(app, clock, parent, collector); + return std::make_unique(app, clock, collector); } } // namespace ripple diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 60fc1a498e4..0eeb40fa768 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -356,7 +356,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , m_inboundLedgers(make_InboundLedgers( *this, stopwatch(), - *m_jobQueue, m_collectorManager->collector())) , m_inboundTransactions(make_InboundTransactions( @@ -1714,6 +1713,7 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + m_inboundLedgers->stop(); m_inboundTransactions->stop(); overlay_->stop(); perfLog_->stop(); From 833767ed0cce567952f925598aa823ed587dde82 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 22 Jan 2021 11:13:01 -0600 Subject: [PATCH 31/62] [fold] ReportingETL is not a Stoppable --- src/ripple/app/main/Application.cpp | 6 ++++-- src/ripple/app/reporting/ReportingETL.cpp | 5 ++--- src/ripple/app/reporting/ReportingETL.h | 12 +++++------- src/ripple/nodestore/impl/DatabaseNodeImp.h | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 0eeb40fa768..a44071eb0bb 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -450,7 +450,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::chrono::milliseconds(100), get_io_service()) , grpcServer_(std::make_unique(*this)) - , reportingETL_(std::make_unique(*this, *this)) + , reportingETL_(std::make_unique(*this)) { add(m_resourceManager.get()); @@ -1663,7 +1663,7 @@ ApplicationImp::setup() if (config_->reporting()) { - reportingETL_->run(); + reportingETL_->start(); } return true; @@ -1713,6 +1713,8 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + if (config_->reporting()) + reportingETL_->stop(); m_inboundLedgers->stop(); m_inboundTransactions->stop(); overlay_->stop(); diff --git a/src/ripple/app/reporting/ReportingETL.cpp b/src/ripple/app/reporting/ReportingETL.cpp index 115b836d694..9408c46f4b2 100644 --- a/src/ripple/app/reporting/ReportingETL.cpp +++ b/src/ripple/app/reporting/ReportingETL.cpp @@ -825,9 +825,8 @@ ReportingETL::doWork() }); } -ReportingETL::ReportingETL(Application& app, Stoppable& parent) - : Stoppable("ReportingETL", parent) - , app_(app) +ReportingETL::ReportingETL(Application& app) + : app_(app) , journal_(app.journal("ReportingETL")) , publishStrand_(app_.getIOService()) , loadBalancer_(*this) diff --git a/src/ripple/app/reporting/ReportingETL.h b/src/ripple/app/reporting/ReportingETL.h index ddd70cbea31..59f109e033b 100644 --- a/src/ripple/app/reporting/ReportingETL.h +++ b/src/ripple/app/reporting/ReportingETL.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -67,7 +66,7 @@ struct AccountTransactionsData; * monitoring to writing and from writing to monitoring, based on the activity * of other processes running on different machines. */ -class ReportingETL : Stoppable +class ReportingETL { private: Application& app_; @@ -266,7 +265,7 @@ class ReportingETL : Stoppable ThreadSafeQueue>& writeQueue); public: - ReportingETL(Application& app, Stoppable& parent); + ReportingETL(Application& app); ~ReportingETL() { @@ -279,7 +278,7 @@ class ReportingETL : Stoppable } bool - isStopping() + isStopping() const { return stopping_; } @@ -322,7 +321,7 @@ class ReportingETL : Stoppable /// start all of the necessary components and begin ETL void - run() + start() { JLOG(journal_.info()) << "Starting reporting etl"; assert(app_.config().reporting()); @@ -335,9 +334,8 @@ class ReportingETL : Stoppable doWork(); } - /// Stop all the necessary components void - onStop() override + stop() { JLOG(journal_.info()) << "onStop called"; JLOG(journal_.debug()) << "Stopping Reporting ETL"; diff --git a/src/ripple/nodestore/impl/DatabaseNodeImp.h b/src/ripple/nodestore/impl/DatabaseNodeImp.h index 0e725a821ca..fdf0ffca4f1 100644 --- a/src/ripple/nodestore/impl/DatabaseNodeImp.h +++ b/src/ripple/nodestore/impl/DatabaseNodeImp.h @@ -72,7 +72,7 @@ class DatabaseNodeImp : public Database if (!cacheAge || *cacheAge == 0) cacheAge = 5; cache_ = std::make_shared>( - name, + "DatabaseNodeImp", cacheSize.value(), std::chrono::minutes{cacheAge.value()}, stopwatch(), From 77a6ac726d736db3b8accb35d3804c078c3c9a99 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 22 Jan 2021 17:48:26 -0600 Subject: [PATCH 32/62] [fold] PgPool is not a Stoppable --- src/ripple/app/main/Application.cpp | 6 +++++- src/ripple/core/Pg.cpp | 9 ++++----- src/ripple/core/Pg.h | 13 +++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index a44071eb0bb..35741d201e9 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -282,7 +282,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , pgPool_( config_->reporting() ? make_PgPool( config_->section("ledger_tx_tables"), - *this, logs_->journal("PgPool")) : nullptr) #endif @@ -1714,7 +1713,12 @@ ApplicationImp::run() JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); if (config_->reporting()) + { +#ifdef RIPPLED_REPORTING + pgPool_->stop(); +#endif reportingETL_->stop(); + } m_inboundLedgers->stop(); m_inboundTransactions->stop(); overlay_->stop(); diff --git a/src/ripple/core/Pg.cpp b/src/ripple/core/Pg.cpp index 3033077ae7c..3c75c00b3bc 100644 --- a/src/ripple/core/Pg.cpp +++ b/src/ripple/core/Pg.cpp @@ -324,8 +324,7 @@ Pg::clear() //----------------------------------------------------------------------------- -PgPool::PgPool(Section const& pgConfig, Stoppable& parent, beast::Journal j) - : Stoppable("PgPool", parent), j_(j) +PgPool::PgPool(Section const& pgConfig, beast::Journal j) : j_(j) { // Make sure that boost::asio initializes the SSL library. { @@ -501,7 +500,7 @@ PgPool::setup() } void -PgPool::onStop() +PgPool::stop() { std::lock_guard lock(mutex_); stop_ = true; @@ -594,9 +593,9 @@ PgPool::checkin(std::unique_ptr& pg) //----------------------------------------------------------------------------- std::shared_ptr -make_PgPool(Section const& pgConfig, Stoppable& parent, beast::Journal j) +make_PgPool(Section const& pgConfig, beast::Journal j) { - auto ret = std::make_shared(pgConfig, parent, j); + auto ret = std::make_shared(pgConfig, j); ret->setup(); return ret; } diff --git a/src/ripple/core/Pg.h b/src/ripple/core/Pg.h index 42e77619628..b2e8f465c30 100644 --- a/src/ripple/core/Pg.h +++ b/src/ripple/core/Pg.h @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -366,7 +365,7 @@ class Pg * This should be stored as a shared pointer so PgQuery objects can safely * outlive it. */ -class PgPool : public Stoppable +class PgPool { friend class PgQuery; @@ -409,9 +408,8 @@ class PgPool : public Stoppable * * @param pgConfig Postgres config. * @param j Logger object. - * @param parent Stoppable parent. */ - PgPool(Section const& pgConfig, Stoppable& parent, beast::Journal j); + PgPool(Section const& pgConfig, beast::Journal j); /** Initiate idle connection timer. * @@ -421,9 +419,9 @@ class PgPool : public Stoppable void setup(); - /** Prepare for process shutdown. (Stoppable) */ + /** Prepare for process shutdown. */ void - onStop() override; + stop(); /** Disconnect idle postgres connections. */ void @@ -501,11 +499,10 @@ class PgQuery * * @param pgConfig Configuration for Postgres. * @param j Logger object. - * @param parent Stoppable parent object. * @return Postgres connection pool manager */ std::shared_ptr -make_PgPool(Section const& pgConfig, Stoppable& parent, beast::Journal j); +make_PgPool(Section const& pgConfig, beast::Journal j); /** Initialize the Postgres schema. * From 8c5deef5a0ecc7ca8ef4308662e24af845b467f9 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 18 Jan 2021 15:14:19 -0600 Subject: [PATCH 33/62] [fold] NodeStore::Database is not a Stoppable --- src/ripple/app/main/Application.cpp | 9 +-- src/ripple/app/misc/SHAMapStore.h | 2 +- src/ripple/app/misc/SHAMapStoreImp.cpp | 6 +- src/ripple/app/misc/SHAMapStoreImp.h | 2 +- src/ripple/nodestore/Database.h | 19 ++--- src/ripple/nodestore/DatabaseRotating.h | 4 +- src/ripple/nodestore/DatabaseShard.h | 7 +- src/ripple/nodestore/Manager.h | 2 - src/ripple/nodestore/impl/Database.cpp | 20 +++-- src/ripple/nodestore/impl/DatabaseNodeImp.h | 11 +-- .../nodestore/impl/DatabaseRotatingImp.cpp | 4 +- .../nodestore/impl/DatabaseRotatingImp.h | 8 -- .../nodestore/impl/DatabaseShardImp.cpp | 12 +-- src/ripple/nodestore/impl/DatabaseShardImp.h | 4 +- src/ripple/nodestore/impl/ManagerImp.cpp | 10 +-- src/ripple/nodestore/impl/ManagerImp.h | 2 - src/test/nodestore/DatabaseShard_test.cpp | 3 +- src/test/nodestore/Database_test.cpp | 74 +++---------------- src/test/shamap/common.h | 4 +- 19 files changed, 43 insertions(+), 160 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 35741d201e9..950db131259 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -324,14 +324,13 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp m_collectorManager->collector(), logs_->journal("Resource"))) - , m_nodeStore(m_shaMapStore->makeNodeStore("NodeStore.main", 4)) + , m_nodeStore(m_shaMapStore->makeNodeStore(4)) , nodeFamily_(*this, *m_collectorManager) // The shard store is optional and make_ShardStore can return null. , shardStore_(make_ShardStore( *this, - *m_jobQueue, m_nodeStoreScheduler, 4, logs_->journal("ShardStore"))) @@ -975,15 +974,12 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp { auto j = logs_->journal("NodeObject"); NodeStore::DummyScheduler dummyScheduler; - RootStoppable dummyRoot{"DummyRoot"}; std::unique_ptr source = NodeStore::Manager::instance().make_Database( - "NodeStore.import", megabytes(config_->getValueFor( SizedItem::burstSize, boost::none)), dummyScheduler, 0, - dummyRoot, config_->section(ConfigSection::importNodeDatabase()), j); @@ -1712,6 +1708,9 @@ ApplicationImp::run() // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; stop(m_journal); + m_nodeStore->stop(); + if (shardStore_) + shardStore_->stop(); if (config_->reporting()) { #ifdef RIPPLED_REPORTING diff --git a/src/ripple/app/misc/SHAMapStore.h b/src/ripple/app/misc/SHAMapStore.h index dd48ca069db..8158dca8a55 100644 --- a/src/ripple/app/misc/SHAMapStore.h +++ b/src/ripple/app/misc/SHAMapStore.h @@ -53,7 +53,7 @@ class SHAMapStore clampFetchDepth(std::uint32_t fetch_depth) const = 0; virtual std::unique_ptr - makeNodeStore(std::string const& name, std::int32_t readThreads) = 0; + makeNodeStore(std::int32_t readThreads) = 0; /** Highest ledger that may be deleted. */ virtual LedgerIndex diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index 98bfd469389..62a9b95e298 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -233,7 +233,7 @@ SHAMapStoreImp::SHAMapStoreImp( } std::unique_ptr -SHAMapStoreImp::makeNodeStore(std::string const& name, std::int32_t readThreads) +SHAMapStoreImp::makeNodeStore(std::int32_t readThreads) { // Anything which calls addJob must be a descendant of the JobQueue. // Therefore Database objects use the JobQueue as Stoppable parent. @@ -258,10 +258,8 @@ SHAMapStoreImp::makeNodeStore(std::string const& name, std::int32_t readThreads) // Create NodeStore with two backends to allow online deletion of data auto dbr = std::make_unique( - name, scheduler_, readThreads, - app_.getJobQueue(), std::move(writableBackend), std::move(archiveBackend), app_.config().section(ConfigSection::nodeDatabase()), @@ -273,12 +271,10 @@ SHAMapStoreImp::makeNodeStore(std::string const& name, std::int32_t readThreads) else { db = NodeStore::Manager::instance().make_Database( - name, megabytes( app_.config().getValueFor(SizedItem::burstSize, boost::none)), scheduler_, readThreads, - app_.getJobQueue(), app_.config().section(ConfigSection::nodeDatabase()), app_.logs().journal(nodeStoreName_)); fdRequired_ += db->fdRequired(); diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h index e50fe1148b6..1c2d10c0029 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.h +++ b/src/ripple/app/misc/SHAMapStoreImp.h @@ -143,7 +143,7 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore } std::unique_ptr - makeNodeStore(std::string const& name, std::int32_t readThreads) override; + makeNodeStore(std::int32_t readThreads) override; LedgerIndex setCanDelete(LedgerIndex seq) override diff --git a/src/ripple/nodestore/Database.h b/src/ripple/nodestore/Database.h index ec7effa9801..2eef702a9f8 100644 --- a/src/ripple/nodestore/Database.h +++ b/src/ripple/nodestore/Database.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -49,23 +48,19 @@ namespace NodeStore { @see NodeObject */ -class Database : public Stoppable +class Database { public: Database() = delete; /** Construct the node store. - @param name The Stoppable name for this Database. - @param parent The parent Stoppable. @param scheduler The scheduler to use for performing asynchronous tasks. @param readThreads The number of asynchronous read threads to create. @param config The configuration settings @param journal Destination for logging output. */ Database( - std::string name, - Stoppable& parent, Scheduler& scheduler, int readThreads, Section const& config, @@ -225,8 +220,11 @@ class Database : public Stoppable return fdRequired_; } - void - onStop() override; + virtual void + stop(); + + bool + isStopping() const; /** @return The earliest ledger sequence allowed */ @@ -244,9 +242,6 @@ class Database : public Stoppable std::atomic fetchHitCount_{0}; std::atomic fetchSz_{0}; - void - stopReadThreads(); - void storeStats(std::uint64_t count, std::uint64_t sz) { @@ -282,7 +277,7 @@ class Database : public Stoppable std::atomic fetchDurationUs_{0}; std::atomic storeDurationUs_{0}; - std::mutex readLock_; + mutable std::mutex readLock_; std::condition_variable readCondVar_; // reads to do diff --git a/src/ripple/nodestore/DatabaseRotating.h b/src/ripple/nodestore/DatabaseRotating.h index 36d7041202e..c8d7104fe59 100644 --- a/src/ripple/nodestore/DatabaseRotating.h +++ b/src/ripple/nodestore/DatabaseRotating.h @@ -34,13 +34,11 @@ class DatabaseRotating : public Database { public: DatabaseRotating( - std::string const& name, - Stoppable& parent, Scheduler& scheduler, int readThreads, Section const& config, beast::Journal journal) - : Database(name, parent, scheduler, readThreads, config, journal) + : Database(scheduler, readThreads, config, journal) { } diff --git a/src/ripple/nodestore/DatabaseShard.h b/src/ripple/nodestore/DatabaseShard.h index 4a4f013fa61..1cc428514eb 100644 --- a/src/ripple/nodestore/DatabaseShard.h +++ b/src/ripple/nodestore/DatabaseShard.h @@ -39,21 +39,17 @@ class DatabaseShard : public Database public: /** Construct a shard store - @param name The Stoppable name for this Database - @param parent The parent Stoppable @param scheduler The scheduler to use for performing asynchronous tasks @param readThreads The number of asynchronous read threads to create @param config The shard configuration section for the database @param journal Destination for logging output */ DatabaseShard( - std::string const& name, - Stoppable& parent, Scheduler& scheduler, int readThreads, Section const& config, beast::Journal journal) - : Database(name, parent, scheduler, readThreads, config, journal) + : Database(scheduler, readThreads, config, journal) { } @@ -190,7 +186,6 @@ seqToShardIndex( extern std::unique_ptr make_ShardStore( Application& app, - Stoppable& parent, Scheduler& scheduler, int readThreads, beast::Journal j); diff --git a/src/ripple/nodestore/Manager.h b/src/ripple/nodestore/Manager.h index e7b4ecec919..d28fd2bcaf7 100644 --- a/src/ripple/nodestore/Manager.h +++ b/src/ripple/nodestore/Manager.h @@ -95,11 +95,9 @@ class Manager */ virtual std::unique_ptr make_Database( - std::string const& name, std::size_t burstSize, Scheduler& scheduler, int readThreads, - Stoppable& parent, Section const& backendParameters, beast::Journal journal) = 0; }; diff --git a/src/ripple/nodestore/impl/Database.cpp b/src/ripple/nodestore/impl/Database.cpp index 5784e9c8576..06e83aff44a 100644 --- a/src/ripple/nodestore/impl/Database.cpp +++ b/src/ripple/nodestore/impl/Database.cpp @@ -30,14 +30,11 @@ namespace ripple { namespace NodeStore { Database::Database( - std::string name, - Stoppable& parent, Scheduler& scheduler, int readThreads, Section const& config, beast::Journal journal) - : Stoppable(name, parent) - , j_(journal) + : j_(journal) , scheduler_(scheduler) , earliestLedgerSeq_( get(config, "earliest_seq", XRP_LEDGER_EARLIEST_SEQ)) @@ -57,20 +54,21 @@ Database::~Database() // crash during shutdown when its members are accessed by one of // these threads after the derived class is destroyed but before // this base class is destroyed. - stopReadThreads(); + stop(); } -void -Database::onStop() +bool +Database::isStopping() const { - // After stop time we can no longer use the JobQueue for background - // reads. Join the background read threads. - stopReadThreads(); + std::lock_guard lock(readLock_); + return readShut_; } void -Database::stopReadThreads() +Database::stop() { + // After stop time we can no longer use the JobQueue for background + // reads. Join the background read threads. { std::lock_guard lock(readLock_); if (readShut_) // Only stop threads once. diff --git a/src/ripple/nodestore/impl/DatabaseNodeImp.h b/src/ripple/nodestore/impl/DatabaseNodeImp.h index fdf0ffca4f1..f1b8e9b7c05 100644 --- a/src/ripple/nodestore/impl/DatabaseNodeImp.h +++ b/src/ripple/nodestore/impl/DatabaseNodeImp.h @@ -35,15 +35,12 @@ class DatabaseNodeImp : public Database operator=(DatabaseNodeImp const&) = delete; DatabaseNodeImp( - std::string const& name, Scheduler& scheduler, int readThreads, - Stoppable& parent, std::shared_ptr backend, Section const& config, beast::Journal j) - : Database(name, parent, scheduler, readThreads, config, j) - , cache_(nullptr) + : Database(scheduler, readThreads, config, j) , backend_(std::move(backend)) { std::optional cacheSize, cacheAge; @@ -81,12 +78,6 @@ class DatabaseNodeImp : public Database assert(backend_); } - ~DatabaseNodeImp() override - { - // Stop read threads in base before data members are destroyed - stopReadThreads(); - } - std::string getName() const override { diff --git a/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp b/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp index 2d8eadb3b51..56f3411162d 100644 --- a/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseRotatingImp.cpp @@ -25,15 +25,13 @@ namespace ripple { namespace NodeStore { DatabaseRotatingImp::DatabaseRotatingImp( - std::string const& name, Scheduler& scheduler, int readThreads, - Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend, Section const& config, beast::Journal j) - : DatabaseRotating(name, parent, scheduler, readThreads, config, j) + : DatabaseRotating(scheduler, readThreads, config, j) , writableBackend_(std::move(writableBackend)) , archiveBackend_(std::move(archiveBackend)) { diff --git a/src/ripple/nodestore/impl/DatabaseRotatingImp.h b/src/ripple/nodestore/impl/DatabaseRotatingImp.h index f066990af10..e3b0d54db2c 100644 --- a/src/ripple/nodestore/impl/DatabaseRotatingImp.h +++ b/src/ripple/nodestore/impl/DatabaseRotatingImp.h @@ -34,21 +34,13 @@ class DatabaseRotatingImp : public DatabaseRotating operator=(DatabaseRotatingImp const&) = delete; DatabaseRotatingImp( - std::string const& name, Scheduler& scheduler, int readThreads, - Stoppable& parent, std::shared_ptr writableBackend, std::shared_ptr archiveBackend, Section const& config, beast::Journal j); - ~DatabaseRotatingImp() override - { - // Stop read threads in base before data members are destroyed - stopReadThreads(); - } - void rotateWithLock( std::function( diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index fc4731afa16..70dfe866cd0 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -41,14 +41,10 @@ namespace NodeStore { DatabaseShardImp::DatabaseShardImp( Application& app, - Stoppable& parent, - std::string const& name, Scheduler& scheduler, int readThreads, beast::Journal j) : DatabaseShard( - name, - parent, scheduler, readThreads, app.config().section(ConfigSection::shardDatabase()), @@ -693,10 +689,10 @@ DatabaseShardImp::getCompleteShards() } void -DatabaseShardImp::onStop() +DatabaseShardImp::stop() { // Stop read threads in base before data members are destroyed - stopReadThreads(); + Database::stop(); { std::lock_guard lock(mutex_); for (auto const& [_, shard] : shards_) @@ -1889,7 +1885,6 @@ DatabaseShardImp::checkHistoricalPaths() const std::unique_ptr make_ShardStore( Application& app, - Stoppable& parent, Scheduler& scheduler, int readThreads, beast::Journal j) @@ -1900,8 +1895,7 @@ make_ShardStore( if (section.empty()) return nullptr; - return std::make_unique( - app, parent, "ShardStore", scheduler, readThreads, j); + return std::make_unique(app, scheduler, readThreads, j); } } // namespace NodeStore diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.h b/src/ripple/nodestore/impl/DatabaseShardImp.h index 05b8ddf6c7e..d90d61d8077 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.h +++ b/src/ripple/nodestore/impl/DatabaseShardImp.h @@ -42,8 +42,6 @@ class DatabaseShardImp : public DatabaseShard DatabaseShardImp( Application& app, - Stoppable& parent, - std::string const& name, Scheduler& scheduler, int readThreads, beast::Journal j); @@ -124,7 +122,7 @@ class DatabaseShardImp : public DatabaseShard } void - onStop() override; + stop() override; /** Import the application local node store diff --git a/src/ripple/nodestore/impl/ManagerImp.cpp b/src/ripple/nodestore/impl/ManagerImp.cpp index f27812f2ac8..707ef6d1ca8 100644 --- a/src/ripple/nodestore/impl/ManagerImp.cpp +++ b/src/ripple/nodestore/impl/ManagerImp.cpp @@ -70,24 +70,16 @@ ManagerImp::make_Backend( std::unique_ptr ManagerImp::make_Database( - std::string const& name, std::size_t burstSize, Scheduler& scheduler, int readThreads, - Stoppable& parent, Section const& config, beast::Journal journal) { auto backend{make_Backend(config, burstSize, scheduler, journal)}; backend->open(); return std::make_unique( - name, - scheduler, - readThreads, - parent, - std::move(backend), - config, - journal); + scheduler, readThreads, std::move(backend), config, journal); } void diff --git a/src/ripple/nodestore/impl/ManagerImp.h b/src/ripple/nodestore/impl/ManagerImp.h index b062d677a1c..42f8584ef07 100644 --- a/src/ripple/nodestore/impl/ManagerImp.h +++ b/src/ripple/nodestore/impl/ManagerImp.h @@ -61,11 +61,9 @@ class ManagerImp : public Manager std::unique_ptr make_Database( - std::string const& name, std::size_t burstSize, Scheduler& scheduler, int readThreads, - Stoppable& parent, Section const& config, beast::Journal journal) override; }; diff --git a/src/test/nodestore/DatabaseShard_test.cpp b/src/test/nodestore/DatabaseShard_test.cpp index c7a94da80f4..05f8738a4b9 100644 --- a/src/test/nodestore/DatabaseShard_test.cpp +++ b/src/test/nodestore/DatabaseShard_test.cpp @@ -532,10 +532,9 @@ class DatabaseShard_test : public TestBase beast::temp_dir shardDir; Env env{*this, testConfig(shardDir.path())}; DummyScheduler scheduler; - RootStoppable parent("TestRootStoppable"); std::unique_ptr db = - make_ShardStore(env.app(), parent, scheduler, 2, journal_); + make_ShardStore(env.app(), scheduler, 2, journal_); BEAST_EXPECT(db); BEAST_EXPECT(db->ledgersPerShard() == db->ledgersPerShardDefault); diff --git a/src/test/nodestore/Database_test.cpp b/src/test/nodestore/Database_test.cpp index 67d3a6b3741..dd8af68c78c 100644 --- a/src/test/nodestore/Database_test.cpp +++ b/src/test/nodestore/Database_test.cpp @@ -450,7 +450,6 @@ class Database_test : public TestBase std::int64_t seedValue) { DummyScheduler scheduler; - RootStoppable parent("TestRootStoppable"); beast::temp_dir node_db; Section srcParams; @@ -463,13 +462,7 @@ class Database_test : public TestBase // Write to source db { std::unique_ptr src = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - srcParams, - journal_); + megabytes(4), scheduler, 2, srcParams, journal_); storeBatch(*src, batch); } @@ -478,13 +471,7 @@ class Database_test : public TestBase { // Re-open the db std::unique_ptr src = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - srcParams, - journal_); + megabytes(4), scheduler, 2, srcParams, journal_); // Set up the destination database beast::temp_dir dest_db; @@ -493,13 +480,7 @@ class Database_test : public TestBase destParams.set("path", dest_db.path()); std::unique_ptr dest = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - destParams, - journal_); + megabytes(4), scheduler, 2, destParams, journal_); testcase( "import into '" + destBackendType + "' from '" + @@ -528,7 +509,6 @@ class Database_test : public TestBase int numObjsToTest = 2000) { DummyScheduler scheduler; - RootStoppable parent("TestRootStoppable"); std::string s = "NodeStore backend '" + type + "'"; @@ -547,13 +527,7 @@ class Database_test : public TestBase { // Open the database std::unique_ptr db = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - nodeParams, - journal_); + megabytes(4), scheduler, 2, nodeParams, journal_); // Write the batch storeBatch(*db, batch); @@ -578,13 +552,7 @@ class Database_test : public TestBase { // Re-open the database without the ephemeral DB std::unique_ptr db = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - nodeParams, - journal_); + megabytes(4), scheduler, 2, nodeParams, journal_); // Read it back in Batch copy; @@ -603,13 +571,7 @@ class Database_test : public TestBase // Verify default earliest ledger sequence std::unique_ptr db = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - nodeParams, - journal_); + megabytes(4), scheduler, 2, nodeParams, journal_); BEAST_EXPECT( db->earliestLedgerSeq() == XRP_LEDGER_EARLIEST_SEQ); } @@ -620,13 +582,7 @@ class Database_test : public TestBase nodeParams.set("earliest_seq", "0"); std::unique_ptr db = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - nodeParams, - journal_); + megabytes(4), scheduler, 2, nodeParams, journal_); } catch (std::runtime_error const& e) { @@ -639,13 +595,7 @@ class Database_test : public TestBase nodeParams.set("earliest_seq", "1"); std::unique_ptr db = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - nodeParams, - journal_); + megabytes(4), scheduler, 2, nodeParams, journal_); // Verify database uses the earliest ledger sequence setting BEAST_EXPECT(db->earliestLedgerSeq() == 1); @@ -659,13 +609,7 @@ class Database_test : public TestBase "earliest_seq", std::to_string(XRP_LEDGER_EARLIEST_SEQ)); std::unique_ptr db2 = Manager::instance().make_Database( - "test", - megabytes(4), - scheduler, - 2, - parent, - nodeParams, - journal_); + megabytes(4), scheduler, 2, nodeParams, journal_); } catch (std::runtime_error const& e) { diff --git a/src/test/shamap/common.h b/src/test/shamap/common.h index 7a13bb81405..59cee49fbcd 100644 --- a/src/test/shamap/common.h +++ b/src/test/shamap/common.h @@ -39,7 +39,6 @@ class TestNodeFamily : public Family TestStopwatch clock_; NodeStore::DummyScheduler scheduler_; - RootStoppable parent_; beast::Journal const j_; @@ -54,14 +53,13 @@ class TestNodeFamily : public Family std::chrono::minutes{1}, clock_, j)) - , parent_("TestRootStoppable") , j_(j) { Section testSection; testSection.set("type", "memory"); testSection.set("Path", "SHAMap_test"); db_ = NodeStore::Manager::instance().make_Database( - "test", megabytes(4), scheduler_, 1, parent_, testSection, j); + megabytes(4), scheduler_, 1, testSection, j); } NodeStore::Database& From 023998bf16f894f84c9d14a7c114d7ff5832b133 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 18 Jan 2021 18:02:54 -0600 Subject: [PATCH 34/62] [fold] SHAMapStoreImp is not a Stoppable --- src/ripple/app/main/Application.cpp | 8 +++----- src/ripple/app/misc/SHAMapStore.h | 5 +++-- src/ripple/app/misc/SHAMapStoreImp.cpp | 11 +++-------- src/ripple/app/misc/SHAMapStoreImp.h | 6 ++---- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 950db131259..0365c37d057 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -176,7 +176,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp AccountIDCache accountIDCache_; boost::optional openLedger_; - // These are not Stoppable-derived NodeCache m_tempNodeCache; CachedSLEs cachedSLEs_; std::pair nodeIdentity_; @@ -184,7 +183,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::unique_ptr m_resourceManager; - // These are Stoppable-related std::unique_ptr m_nodeStore; NodeFamily nodeFamily_; std::unique_ptr shardStore_; @@ -303,7 +301,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp , m_nodeStoreScheduler(*m_jobQueue) , m_shaMapStore(make_SHAMapStore( - *this, *this, m_nodeStoreScheduler, logs_->journal("SHAMapStore"))) @@ -1704,9 +1701,10 @@ ApplicationImp::run() cv_.wait(lk, [this] { return isTimeToStop; }); } - // Stop the server. When this returns, all - // Stoppable objects should be stopped. JLOG(m_journal.info()) << "Received shutdown request"; + // The order of these stop calls is delicate. + // Re-ordering them risks undefined behavior. + m_shaMapStore->stop(); stop(m_journal); m_nodeStore->stop(); if (shardStore_) diff --git a/src/ripple/app/misc/SHAMapStore.h b/src/ripple/app/misc/SHAMapStore.h index 8158dca8a55..068a1e6e79f 100644 --- a/src/ripple/app/misc/SHAMapStore.h +++ b/src/ripple/app/misc/SHAMapStore.h @@ -28,7 +28,6 @@ namespace ripple { class TransactionMaster; -class Stoppable; /** * class to create database, launch online delete thread, and @@ -49,6 +48,9 @@ class SHAMapStore virtual void rendezvous() const = 0; + virtual void + stop() = 0; + virtual std::uint32_t clampFetchDepth(std::uint32_t fetch_depth) const = 0; @@ -102,7 +104,6 @@ class SHAMapStore std::unique_ptr make_SHAMapStore( Application& app, - Stoppable& parent, NodeStore::Scheduler& scheduler, beast::Journal journal); } // namespace ripple diff --git a/src/ripple/app/misc/SHAMapStoreImp.cpp b/src/ripple/app/misc/SHAMapStoreImp.cpp index 62a9b95e298..9e9beb3b88a 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.cpp +++ b/src/ripple/app/misc/SHAMapStoreImp.cpp @@ -148,11 +148,9 @@ SHAMapStoreImp::SavedStateDB::setLastRotated(LedgerIndex seq) SHAMapStoreImp::SHAMapStoreImp( Application& app, - Stoppable& parent, NodeStore::Scheduler& scheduler, beast::Journal journal) - : Stoppable("SHAMapStore", parent) - , app_(app) + : app_(app) , scheduler_(scheduler) , journal_(journal) , working_(true) @@ -235,8 +233,6 @@ SHAMapStoreImp::SHAMapStoreImp( std::unique_ptr SHAMapStoreImp::makeNodeStore(std::int32_t readThreads) { - // Anything which calls addJob must be a descendant of the JobQueue. - // Therefore Database objects use the JobQueue as Stoppable parent. std::unique_ptr db; if (deleteInterval_) { @@ -748,7 +744,7 @@ SHAMapStoreImp::health() } void -SHAMapStoreImp::onStop() +SHAMapStoreImp::stop() { if (thread_.joinable()) { @@ -776,11 +772,10 @@ SHAMapStoreImp::minimumOnline() const std::unique_ptr make_SHAMapStore( Application& app, - Stoppable& parent, NodeStore::Scheduler& scheduler, beast::Journal journal) { - return std::make_unique(app, parent, scheduler, journal); + return std::make_unique(app, scheduler, journal); } } // namespace ripple diff --git a/src/ripple/app/misc/SHAMapStoreImp.h b/src/ripple/app/misc/SHAMapStoreImp.h index 1c2d10c0029..daac945e8da 100644 --- a/src/ripple/app/misc/SHAMapStoreImp.h +++ b/src/ripple/app/misc/SHAMapStoreImp.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,7 @@ namespace ripple { class NetworkOPs; -class SHAMapStoreImp : public Stoppable, public SHAMapStore +class SHAMapStoreImp : public SHAMapStore { private: struct SavedState @@ -131,7 +130,6 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore public: SHAMapStoreImp( Application& app, - Stoppable& parent, NodeStore::Scheduler& scheduler, beast::Journal journal); @@ -251,7 +249,7 @@ class SHAMapStoreImp : public Stoppable, public SHAMapStore } void - onStop() override; + stop() override; }; } // namespace ripple From 21db9790f1270fc9dd444148e1ad24a220e82068 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 18 Jan 2021 18:32:15 -0600 Subject: [PATCH 35/62] [fold] ShardArchiveHandler is not a Stoppable --- src/ripple/app/main/Application.cpp | 10 ++++--- src/ripple/net/ShardDownloader.md | 4 +-- src/ripple/rpc/ShardArchiveHandler.h | 18 ++++++------ src/ripple/rpc/impl/ShardArchiveHandler.cpp | 31 ++++++++++----------- 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 0365c37d057..f455a136370 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -663,8 +663,8 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp return nullptr; } - auto handler = RPC::ShardArchiveHandler::tryMakeRecoveryHandler( - *this, *m_jobQueue); + auto handler = + RPC::ShardArchiveHandler::tryMakeRecoveryHandler(*this); if (!initAndSet(std::move(handler))) return nullptr; @@ -673,8 +673,8 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // Construct the ShardArchiveHandler if (shardArchiveHandler_ == nullptr) { - auto handler = RPC::ShardArchiveHandler::makeShardArchiveHandler( - *this, *m_jobQueue); + auto handler = + RPC::ShardArchiveHandler::makeShardArchiveHandler(*this); if (!initAndSet(std::move(handler))) return nullptr; @@ -1706,6 +1706,8 @@ ApplicationImp::run() // Re-ordering them risks undefined behavior. m_shaMapStore->stop(); stop(m_journal); + if (shardArchiveHandler_) + shardArchiveHandler_->stop(); m_nodeStore->stop(); if (shardStore_) shardStore_->stop(); diff --git a/src/ripple/net/ShardDownloader.md b/src/ripple/net/ShardDownloader.md index 96938acb10a..ca9db7f53dd 100644 --- a/src/ripple/net/ShardDownloader.md +++ b/src/ripple/net/ShardDownloader.md @@ -86,12 +86,12 @@ std::atomic stop_; ##### Thread 1: -A graceful shutdown begins when the `onStop()` method of the +A graceful shutdown begins when the `stop()` method of the `ShardArchiveHandler` is invoked: ```c++ void -ShardArchiveHandler::onStop() +ShardArchiveHandler::stop() { std::lock_guard lock(m_); diff --git a/src/ripple/rpc/ShardArchiveHandler.h b/src/ripple/rpc/ShardArchiveHandler.h index c3566a2c71e..f8f1d384fa5 100644 --- a/src/ripple/rpc/ShardArchiveHandler.h +++ b/src/ripple/rpc/ShardArchiveHandler.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -37,7 +36,7 @@ class ShardArchiveHandler_test; namespace RPC { /** Handles the download and import of one or more shard archives. */ -class ShardArchiveHandler : public Stoppable +class ShardArchiveHandler { public: using TimerOpCounter = @@ -48,15 +47,15 @@ class ShardArchiveHandler : public Stoppable getDownloadDirectory(Config const& config); static std::unique_ptr - makeShardArchiveHandler(Application& app, Stoppable& parent); + makeShardArchiveHandler(Application& app); // Create a ShardArchiveHandler only if // the state database is present, indicating // that recovery is needed. static std::unique_ptr - tryMakeRecoveryHandler(Application& app, Stoppable& parent); + tryMakeRecoveryHandler(Application& app); - ShardArchiveHandler(Application& app, Stoppable& parent); + ShardArchiveHandler(Application& app); virtual ~ShardArchiveHandler() = default; @@ -70,6 +69,9 @@ class ShardArchiveHandler : public Stoppable bool start(); + void + stop(); + void release(); @@ -84,9 +86,6 @@ class ShardArchiveHandler : public Stoppable [[nodiscard]] bool initFromDB(std::lock_guard const&); - void - onStop() override; - /** Add an archive to be downloaded and imported. @param shardIndex the index of the shard to be imported. @param url the location of the archive. @@ -131,6 +130,7 @@ class ShardArchiveHandler : public Stoppable // destroying sqliteDB_. ///////////////////////////////////////////////// std::mutex mutable m_; + std::atomic_bool stopping_{false}; std::shared_ptr downloader_; std::map archives_; bool process_; @@ -162,7 +162,7 @@ class ShardArchiveHandler : public Stoppable class RecoveryHandler : public ShardArchiveHandler { public: - RecoveryHandler(Application& app, Stoppable& parent); + RecoveryHandler(Application& app); }; } // namespace RPC diff --git a/src/ripple/rpc/impl/ShardArchiveHandler.cpp b/src/ripple/rpc/impl/ShardArchiveHandler.cpp index a3f73c53bc2..2a9a3e101e3 100644 --- a/src/ripple/rpc/impl/ShardArchiveHandler.cpp +++ b/src/ripple/rpc/impl/ShardArchiveHandler.cpp @@ -45,15 +45,13 @@ ShardArchiveHandler::getDownloadDirectory(Config const& config) } std::unique_ptr -ShardArchiveHandler::makeShardArchiveHandler( - Application& app, - Stoppable& parent) +ShardArchiveHandler::makeShardArchiveHandler(Application& app) { - return std::make_unique(app, parent); + return std::make_unique(app); } std::unique_ptr -ShardArchiveHandler::tryMakeRecoveryHandler(Application& app, Stoppable& parent) +ShardArchiveHandler::tryMakeRecoveryHandler(Application& app) { auto const downloadDir(getDownloadDirectory(app.config())); @@ -62,15 +60,14 @@ ShardArchiveHandler::tryMakeRecoveryHandler(Application& app, Stoppable& parent) if (exists(downloadDir / stateDBName) && is_regular_file(downloadDir / stateDBName)) { - return std::make_unique(app, parent); + return std::make_unique(app); } return nullptr; } -ShardArchiveHandler::ShardArchiveHandler(Application& app, Stoppable& parent) - : Stoppable("ShardArchiveHandler", parent) - , process_(false) +ShardArchiveHandler::ShardArchiveHandler(Application& app) + : process_(false) , app_(app) , j_(app.journal("ShardArchiveHandler")) , downloadDir_(getDownloadDirectory(app.config())) @@ -190,8 +187,9 @@ ShardArchiveHandler::initFromDB(std::lock_guard const& lock) } void -ShardArchiveHandler::onStop() +ShardArchiveHandler::stop() { + stopping_ = true; { std::lock_guard lock(m_); @@ -312,7 +310,7 @@ ShardArchiveHandler::release() bool ShardArchiveHandler::next(std::lock_guard const& l) { - if (isStopping()) + if (stopping_) return false; if (archives_.empty()) @@ -409,7 +407,7 @@ ShardArchiveHandler::next(std::lock_guard const& l) void ShardArchiveHandler::complete(path dstPath) { - if (isStopping()) + if (stopping_) return; { @@ -437,7 +435,7 @@ ShardArchiveHandler::complete(path dstPath) // Make lambdas mutable captured vars can be moved from auto wrapper = jobCounter_.wrap([=, dstPath = std::move(dstPath)](Job&) mutable { - if (isStopping()) + if (stopping_) return; // If not synced then defer and retry @@ -474,7 +472,7 @@ ShardArchiveHandler::complete(path dstPath) if (!wrapper) { - if (isStopping()) + if (stopping_) return; JLOG(j_.error()) << "failed to wrap closure for process()"; @@ -587,7 +585,7 @@ ShardArchiveHandler::onClosureFailed( std::string const& errorMsg, std::lock_guard const& lock) { - if (isStopping()) + if (stopping_) return false; JLOG(j_.error()) << errorMsg; @@ -602,8 +600,7 @@ ShardArchiveHandler::removeAndProceed(std::lock_guard const& lock) return next(lock); } -RecoveryHandler::RecoveryHandler(Application& app, Stoppable& parent) - : ShardArchiveHandler(app, parent) +RecoveryHandler::RecoveryHandler(Application& app) : ShardArchiveHandler(app) { } From 0b142029ce723b325e24ef0b17d2fa2f0dea6495 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 18 Jan 2021 22:07:09 -0600 Subject: [PATCH 36/62] [fold] JobQueue is not a Stoppable --- src/ripple/app/main/Application.cpp | 2 +- src/ripple/core/JobQueue.h | 13 +++++++++---- src/ripple/core/impl/JobQueue.cpp | 9 ++++----- src/test/core/JobQueue_test.cpp | 4 ++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index f455a136370..414ecba3b3d 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -293,7 +293,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // , m_jobQueue(std::make_unique( m_collectorManager->group("jobq"), - *this, logs_->journal("JobQueue"), *logs_, *perfLog_)) @@ -1706,6 +1705,7 @@ ApplicationImp::run() // Re-ordering them risks undefined behavior. m_shaMapStore->stop(); stop(m_journal); + m_jobQueue->stop(); if (shardArchiveHandler_) shardArchiveHandler_->stop(); m_nodeStore->stop(); diff --git a/src/ripple/core/JobQueue.h b/src/ripple/core/JobQueue.h index 1176fdf033e..1d3fd5498ed 100644 --- a/src/ripple/core/JobQueue.h +++ b/src/ripple/core/JobQueue.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +52,7 @@ struct Coro_create_t When the JobQueue stops, it waits for all jobs and coroutines to finish. */ -class JobQueue : public Stoppable, private Workers::Callback +class JobQueue : private Workers::Callback { public: /** Coroutines must run to completion. */ @@ -143,7 +142,6 @@ class JobQueue : public Stoppable, private Workers::Callback JobQueue( beast::insight::Collector::ptr const& collector, - Stoppable& parent, beast::Journal journal, Logs& logs, perf::PerfLog& perfLog); @@ -230,7 +228,13 @@ class JobQueue : public Stoppable, private Workers::Callback rendezvous(); void - onStop() override; + stop(); + + bool + isStopping() const + { + return stopping_; + } // We may be able to move away from this, but we can keep it during the // transition. @@ -247,6 +251,7 @@ class JobQueue : public Stoppable, private Workers::Callback std::uint64_t m_lastJob; std::set m_jobSet; JobCounter jobCounter_; + std::atomic_bool stopping_{false}; std::atomic_bool stopped_{false}; JobDataMap m_jobData; JobTypeData m_invalidJobData; diff --git a/src/ripple/core/impl/JobQueue.cpp b/src/ripple/core/impl/JobQueue.cpp index 8eb4b679ff8..a8d4c569fa1 100644 --- a/src/ripple/core/impl/JobQueue.cpp +++ b/src/ripple/core/impl/JobQueue.cpp @@ -26,17 +26,15 @@ namespace ripple { JobQueue::JobQueue( beast::insight::Collector::ptr const& collector, - Stoppable& parent, beast::Journal journal, Logs& logs, perf::PerfLog& perfLog) - : Stoppable("JobQueue", parent) - , m_journal(journal) + : m_journal(journal) , m_lastJob(0) , m_invalidJobData(JobTypes::instance().getInvalid(), collector, logs) , m_processCount(0) , m_workers(*this, &perfLog, "JobQueue", 0) - , m_cancelCallback(std::bind(&Stoppable::isStopping, this)) + , m_cancelCallback(std::bind(&JobQueue::isStopping, this)) , perfLog_(perfLog) , m_collector(collector) { @@ -281,8 +279,9 @@ JobQueue::getJobTypeData(JobType type) } void -JobQueue::onStop() +JobQueue::stop() { + stopping_ = true; using namespace std::chrono_literals; jobCounter_.join("JobQueue", 1s, m_journal); { diff --git a/src/test/core/JobQueue_test.cpp b/src/test/core/JobQueue_test.cpp index 987f986ebe9..d0c698099c0 100644 --- a/src/test/core/JobQueue_test.cpp +++ b/src/test/core/JobQueue_test.cpp @@ -51,7 +51,7 @@ class JobQueue_test : public beast::unit_test::suite // longer be able to add Jobs (and calling addJob() should // return false). using namespace std::chrono_literals; - jQueue.onStop(); + jQueue.stop(); // The Job should never run, so having the Job access this // unprotected variable on the stack should be completely safe. @@ -134,7 +134,7 @@ class JobQueue_test : public beast::unit_test::suite // longer be able to add a Coro (and calling postCoro() should // return false). using namespace std::chrono_literals; - jQueue.onStop(); + jQueue.stop(); // The Coro should never run, so having the Coro access this // unprotected variable on the stack should be completely safe. From fe5d5dbfba31b2ea7c17e607817acc623f96d3fe Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 19 Jan 2021 09:53:45 -0600 Subject: [PATCH 37/62] [fold] Remove Stoppable --- Builds/CMake/RippledCore.cmake | 2 - src/ripple/app/main/Application.cpp | 68 +++--- src/ripple/core/Stoppable.h | 207 ------------------ src/ripple/core/impl/Stoppable.cpp | 95 --------- src/test/core/Stoppable_test.cpp | 311 ---------------------------- 5 files changed, 32 insertions(+), 651 deletions(-) delete mode 100644 src/ripple/core/Stoppable.h delete mode 100644 src/ripple/core/impl/Stoppable.cpp delete mode 100644 src/test/core/Stoppable_test.cpp diff --git a/Builds/CMake/RippledCore.cmake b/Builds/CMake/RippledCore.cmake index d4017d20e5c..04fb306058e 100644 --- a/Builds/CMake/RippledCore.cmake +++ b/Builds/CMake/RippledCore.cmake @@ -455,7 +455,6 @@ target_sources (rippled PRIVATE src/ripple/core/impl/LoadMonitor.cpp src/ripple/core/impl/SNTPClock.cpp src/ripple/core/impl/SociDB.cpp - src/ripple/core/impl/Stoppable.cpp src/ripple/core/impl/TimeKeeper.cpp src/ripple/core/impl/Workers.cpp src/ripple/core/Pg.cpp @@ -761,7 +760,6 @@ target_sources (rippled PRIVATE src/test/core/CryptoPRNG_test.cpp src/test/core/JobQueue_test.cpp src/test/core/SociDB_test.cpp - src/test/core/Stoppable_test.cpp src/test/core/Workers_test.cpp #[===============================[ test sources: diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 414ecba3b3d..f11fbdd8b8d 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -85,7 +84,7 @@ namespace ripple { // VFALCO TODO Move the function definitions into the class declaration -class ApplicationImp : public Application, public RootStoppable, public BasicApp +class ApplicationImp : public Application, public BasicApp { private: class io_latency_sampler @@ -217,12 +216,11 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::unique_ptr mLedgerDB; std::unique_ptr mWalletDB; std::unique_ptr overlay_; - std::vector> websocketServers_; boost::asio::signal_set m_signals; std::condition_variable cv_; - std::mutex mut_; + mutable std::mutex mut_; bool isTimeToStop = false; std::atomic checkSigs_; @@ -260,8 +258,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp std::unique_ptr config, std::unique_ptr logs, std::unique_ptr timeKeeper) - : RootStoppable("Application") - , BasicApp(numberOfThreads(*config)) + : BasicApp(numberOfThreads(*config)) , config_(std::move(config)) , logs_(std::move(logs)) , timeKeeper_(std::move(timeKeeper)) @@ -288,9 +285,6 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp config_->section(SECTION_INSIGHT), logs_->journal("Collector"))) - // The JobQueue has to come pretty early since - // almost everything is a Stoppable child of the JobQueue. - // , m_jobQueue(std::make_unique( m_collectorManager->group("jobq"), logs_->journal("JobQueue"), @@ -1007,7 +1001,7 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp // Called to indicate shutdown. void - onStop() override + stop() { JLOG(m_journal.debug()) << "Application stopping"; @@ -1069,6 +1063,31 @@ class ApplicationImp : public Application, public RootStoppable, public BasicApp [this](PublicKey const& pubKey) { return validators().trustedPublisher(pubKey); }); + + // The order of these stop calls is delicate. + // Re-ordering them risks undefined behavior. + m_shaMapStore->stop(); + m_jobQueue->stop(); + if (shardArchiveHandler_) + shardArchiveHandler_->stop(); + m_nodeStore->stop(); + if (shardStore_) + shardStore_->stop(); + if (config_->reporting()) + { +#ifdef RIPPLED_REPORTING + pgPool_->stop(); +#endif + reportingETL_->stop(); + } + m_inboundLedgers->stop(); + m_inboundTransactions->stop(); + overlay_->stop(); + perfLog_->stop(); + grpcServer_->stop(); + m_networkOPs->stop(); + m_ledgerMaster->stop(); + m_loadManager->stop(); } //-------------------------------------------------------------------------- @@ -1701,31 +1720,7 @@ ApplicationImp::run() } JLOG(m_journal.info()) << "Received shutdown request"; - // The order of these stop calls is delicate. - // Re-ordering them risks undefined behavior. - m_shaMapStore->stop(); - stop(m_journal); - m_jobQueue->stop(); - if (shardArchiveHandler_) - shardArchiveHandler_->stop(); - m_nodeStore->stop(); - if (shardStore_) - shardStore_->stop(); - if (config_->reporting()) - { -#ifdef RIPPLED_REPORTING - pgPool_->stop(); -#endif - reportingETL_->stop(); - } - m_inboundLedgers->stop(); - m_inboundTransactions->stop(); - overlay_->stop(); - perfLog_->stop(); - grpcServer_->stop(); - m_networkOPs->stop(); - m_ledgerMaster->stop(); - m_loadManager->stop(); + stop(); JLOG(m_journal.info()) << "Done."; } @@ -1758,7 +1753,8 @@ ApplicationImp::checkSigs(bool check) bool ApplicationImp::isStopping() const { - return Stoppable::isStopping(); + std::lock_guard lk{mut_}; + return isTimeToStop; } int diff --git a/src/ripple/core/Stoppable.h b/src/ripple/core/Stoppable.h deleted file mode 100644 index 8250f10e321..00000000000 --- a/src/ripple/core/Stoppable.h +++ /dev/null @@ -1,207 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012-2015 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef RIPPLE_CORE_STOPPABLE_H_INCLUDED -#define RIPPLE_CORE_STOPPABLE_H_INCLUDED - -#include -#include -#include -#include -#include -#include - -namespace ripple { - -class RootStoppable; - -/** Provides an interface for stopping. - - A common method of structuring server or peer to peer code is to isolate - conceptual portions of functionality into individual classes, aggregated - into some larger "application" or "core" object which holds all the parts. - Frequently, these components are dependent on each other in unavoidably - complex ways. They also often use threads and perform asynchronous i/o - operations involving sockets or other operating system objects. The process - of stopping such a system can be complex. This interface - provides a set of behaviors for ensuring that the stop of a - composite application-style object is well defined. - - Upon the initialization of the composite object these steps are performed: - - 1. Construct sub-components. - - These are all typically derived from Stoppable. There can be a deep - hierarchy: Stoppable objects may themselves have Stoppable child - objects. This captures the relationship of dependencies. - - This is the sequence of events involved in stopping: - - 4. stopAsync() [optional] - - This notifies the root Stoppable and all its children that a stop is - requested. - - 5. stop() - - This first calls stopAsync(), and then blocks on each child Stoppable in - the in the tree from the bottom up, until the Stoppable indicates it has - stopped. This will usually be called from the main thread of execution - when some external signal indicates that the process should stop. For - example, an RPC 'stop' command, or a SIGINT POSIX signal. - - 6. onStop() - - This override is called for the root Stoppable and all its children when - stopAsync() is called. Derived classes should cancel pending I/O and - timers, signal that threads should exit, queue cleanup jobs, and perform - any other necessary final actions in preparation for exit. - - Objects are called parent first. - - Derived class that manage one or more threads should typically notify - those threads in onStop that they should exit. In the thread function, - when the last thread is about to exit it would call stopped(). - - The form of the Stoppable tree in the rippled application evolves as - the source code changes and reacts to new demands. As of July in 2020 - the Stoppable tree had this form: - - @code - - Application - | - +--------------------+--------------------+ - | | | - LoadManager SHAMapStore NodeStoreScheduler - | - JobQueue - | - +------+---------+--------+----------+---+-----------+--+---+ - | | | | | | | | - | NetworkOPs | InboundLedgers | | OrderbookDB | - | | | GRPCServer | - | | | Database - Overlay InboundTransactions LedgerMaster | - | | | - PeerFinder LedgerCleaner TaskQueue - - @endcode -*/ -/** @{ */ -class Stoppable -{ -protected: - Stoppable(std::string name, RootStoppable& root); - -public: - /** Create the Stoppable. */ - Stoppable(std::string name, Stoppable& parent); - - /** Destroy the Stoppable. */ - virtual ~Stoppable() = default; - - /** Returns `true` if the stoppable should stop. */ - bool - isStopping() const; - - /** Override called when the stop notification is issued. - - The call is made on an unspecified, implementation-specific thread. - onStop will never be called concurrently, across - all Stoppable objects descended from the same root, inclusive of the - root. - - It is safe to call isStopping, isStopped, and areChildrenStopped from - within this function; The values returned will always be valid and never - change during the callback. - - The default implementation simply calls stopped(). This is applicable - when the Stoppable has a trivial stop operation (or no stop operation), - and we are merely using the Stoppable API to position it as a dependency - of some parent service. - - Thread safety: - May not block for long periods. - Guaranteed only to be called once. - Must be safe to call from any thread at any time. - */ - virtual void - onStop() = 0; - -private: - friend class RootStoppable; - - struct Child; - using Children = beast::LockFreeStack; - - struct Child : Children::Node - { - Child(Stoppable* stoppable_) : stoppable(stoppable_) - { - } - - Stoppable* stoppable; - }; - - void - stopAsyncRecursive(beast::Journal j); - - std::string m_name; - RootStoppable& m_root; - Child m_child; - Children m_children; -}; - -//------------------------------------------------------------------------------ - -class RootStoppable : public Stoppable -{ -public: - explicit RootStoppable(std::string name); - - virtual ~RootStoppable() = default; - - bool - isStopping() const; - - /** Notify a root stoppable and children to stop, and block until stopped. - Has no effect if the stoppable was already notified. - This blocks until the stoppable and all of its children have stopped. - Thread safety: - Safe to call from any thread not associated with a Stoppable. - */ - void - stop(beast::Journal j); - - void - onStop() override - { - } - -private: - // TODO [C++20]: Use std::atomic_flag instead. - std::atomic stopEntered_{false}; - std::mutex m_; -}; -/** @} */ - -} // namespace ripple - -#endif diff --git a/src/ripple/core/impl/Stoppable.cpp b/src/ripple/core/impl/Stoppable.cpp deleted file mode 100644 index 49c630280fe..00000000000 --- a/src/ripple/core/impl/Stoppable.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include -#include - -#include - -namespace ripple { - -Stoppable::Stoppable(std::string name, RootStoppable& root) - : m_name(std::move(name)), m_root(root), m_child(this) -{ -} - -Stoppable::Stoppable(std::string name, Stoppable& parent) - : m_name(std::move(name)), m_root(parent.m_root), m_child(this) -{ - assert(!parent.isStopping()); - parent.m_children.push_front(&m_child); -} - -bool -Stoppable::isStopping() const -{ - return m_root.isStopping(); -} - -//------------------------------------------------------------------------------ - -void -Stoppable::stopAsyncRecursive(beast::Journal j) -{ - onStop(); - - for (Children::const_iterator iter(m_children.cbegin()); - iter != m_children.cend(); - ++iter) - iter->stoppable->stopAsyncRecursive(j); -} - -//------------------------------------------------------------------------------ - -RootStoppable::RootStoppable(std::string name) - : Stoppable(std::move(name), *this) -{ -} - -bool -RootStoppable::isStopping() const -{ - // TODO [C++20]: When `stopEntered_` is changed to a `std::atomic_flag`, - // this implicit call to `load` needs to change to a call to `test`. - return stopEntered_; -} - -void -RootStoppable::stop(beast::Journal j) -{ - bool alreadyCalled; - { - // Even though stopEntered_ is atomic, we change its value under a - // lock. This removes a small timing window that occurs if the - // waiting thread is handling a spurious wakeup while stopEntered_ - // changes state. - std::unique_lock lock(m_); - alreadyCalled = stopEntered_.exchange(true); - } - if (alreadyCalled) - { - if (auto stream = j.warn()) - stream << "RootStoppable::stop called again"; - return; - } - - stopAsyncRecursive(j); -} - -} // namespace ripple diff --git a/src/test/core/Stoppable_test.cpp b/src/test/core/Stoppable_test.cpp deleted file mode 100644 index 47539a07f61..00000000000 --- a/src/test/core/Stoppable_test.cpp +++ /dev/null @@ -1,311 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#include -#include -#include -#include - -namespace ripple { -namespace test { - -class Stoppable_test : public beast::unit_test::suite -{ - /* - R - / | \ - / | \ - A B C - / | \ /\ | - D E F G H I - | - J - */ - unsigned count = 11; - - class D : public Stoppable - { - Stoppable_test& test_; - - public: - D(Stoppable& parent, Stoppable_test& test) - : Stoppable("D", parent), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 0, "D::onStop called out of order"); - } - }; - - class J : public Stoppable - { - Stoppable_test& test_; - - public: - J(Stoppable& parent, Stoppable_test& test) - : Stoppable("J", parent), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 1, "J::onStop called out of order"); - } - }; - - class E : public Stoppable - { - J j_; - Stoppable_test& test_; - - public: - E(Stoppable& parent, Stoppable_test& test) - : Stoppable("E", parent), j_(*this, test), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 2, "E::onStop called out of order"); - } - }; - - class F : public Stoppable - { - Stoppable_test& test_; - - public: - F(Stoppable& parent, Stoppable_test& test) - : Stoppable("F", parent), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 3, "F::onStop called out of order"); - } - }; - - class A : public Stoppable - { - enum { running, please_stop, stopping, stopped }; - D d_; - E e_; - F f_; - Stoppable_test& test_; - std::atomic stop_; - - public: - A(Stoppable& parent, Stoppable_test& test) - : Stoppable("A", parent) - , d_(*this, test) - , e_(*this, test) - , f_(*this, test) - , test_(test) - , stop_(running) - { - } - ~A() override - { - while (stop_ != stopped) - ; - } - - void - run() - { - while (stop_ == running) - ; - stop_ = stopping; - } - - void - onStop() override - { - test_.expect(--test_.count == 4, "A::onStop called out of order"); - // Must be able to call onStop twice. - if (stop_ == stopped) - return; - stop_ = please_stop; - while (stop_ != stopping) - ; - stop_ = stopped; - } - }; - - class G : public Stoppable - { - Stoppable_test& test_; - - public: - G(Stoppable& parent, Stoppable_test& test) - : Stoppable("G", parent), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 5, "G::onStop called out of order"); - } - }; - - class H : public Stoppable - { - Stoppable_test& test_; - - public: - H(Stoppable& parent, Stoppable_test& test) - : Stoppable("H", parent), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 6, "H::onStop called out of order"); - } - }; - - class B : public Stoppable - { - G g_; - H h_; - Stoppable_test& test_; - - public: - B(Stoppable& parent, Stoppable_test& test) - : Stoppable("B", parent) - , g_(*this, test) - , h_(*this, test) - , test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 7, "B::onStop called out of order"); - } - }; - - class I : public Stoppable - { - Stoppable_test& test_; - - public: - I(Stoppable& parent, Stoppable_test& test) - : Stoppable("I", parent), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 8, "I::onStop called out of order"); - } - }; - - class C : public Stoppable - { - I i_; - Stoppable_test& test_; - - public: - C(Stoppable& parent, Stoppable_test& test) - : Stoppable("C", parent), i_(*this, test), test_(test) - { - } - - void - onStop() override - { - test_.expect(--test_.count == 9, "C::onStop called out of order"); - } - }; - - class Root : public RootStoppable - { - std::thread a_; - B b_; - C c_; - Stoppable_test& test_; - SuiteJournal journal_; - - public: - explicit Root(Stoppable_test& test) - : RootStoppable("R") - , a_(&A::run, std::make_unique(*this, test)) - , b_(*this, test) - , c_(*this, test) - , test_(test) - , journal_("Stoppable_test", test) - { - } - - ~Root() - { - a_.join(); - } - - void - run() - { - stop(journal_); - } - - void - onStop() override - { - test_.expect( - --test_.count == 10, "Root::onStop called out of order"); - } - - void - secondStop() - { - // Calling stop() a second time should have no negative - // consequences. - stop(journal_); - } - }; - -public: - void - run() override - { - { - Root rt(*this); - rt.run(); - rt.secondStop(); - } - pass(); - } -}; - -BEAST_DEFINE_TESTSUITE(Stoppable, core, ripple); - -} // namespace test -} // namespace ripple From ddf177efa1ff2bb2d1caa953ae48fb6334ba32d7 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 19 Jan 2021 11:18:06 -0600 Subject: [PATCH 38/62] [fold] Document ClosureCounter and Workers --- src/ripple/core/ClosureCounter.h | 52 ++++++++++++++++++++------------ src/ripple/core/impl/Workers.h | 31 ++++++++++++++++++- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/ripple/core/ClosureCounter.h b/src/ripple/core/ClosureCounter.h index d71c5bcb54e..c4bc31b9ffa 100644 --- a/src/ripple/core/ClosureCounter.h +++ b/src/ripple/core/ClosureCounter.h @@ -29,13 +29,27 @@ namespace ripple { -// A class that does reference counting for postponed closures -- a closure -// who's execution is delayed by a timer or queue. The reference counting -// allows a Stoppable to assure that all such postponed closures are -// completed before the Stoppable declares itself stopped(). -// -// Ret_t is the type that the counted closure returns. -// Args_t are the types of the arguments that will be passed to the closure. +/** + * The role of a `ClosureCounter` is to assist in shutdown by letting callers + * wait for the completion of callbacks (of a single type signature) that they + * previously scheduled. The lifetime of a `ClosureCounter` consists of two + * phases: the initial expanding "fork" phase, and the subsequent shrinking + * "join" phase. + * + * In the fork phase, callers register a callback by passing the callback and + * receiving a substitute in return. The substitute has the same callable + * interface as the callback, and it informs the `ClosureCounter` whenever it + * is copied or destroyed, so that it can keep an accurate count of copies. + * + * The transition to the join phase is made by a call to `join`. In this + * phase, every substitute returned going forward will be empty, signaling to + * the caller that they should just drop the callback and cancel their + * asynchronous operation. `join` blocks until all existing callback + * substitutes are destroyed. + * + * \tparam Ret_t The return type of the closure. + * \tparam Args_t The argument types of the closure. + */ template class ClosureCounter { @@ -74,7 +88,7 @@ class ClosureCounter // in flight. This allows Stoppables to hold off declaring stopped() // until all their postponed closures are dispatched. template - class Wrapper + class Substitute { private: ClosureCounter& counter_; @@ -86,33 +100,33 @@ class ClosureCounter "Closure arguments don't match ClosureCounter Ret_t or Args_t"); public: - Wrapper() = delete; + Substitute() = delete; - Wrapper(Wrapper const& rhs) + Substitute(Substitute const& rhs) : counter_(rhs.counter_), closure_(rhs.closure_) { ++counter_; } - Wrapper(Wrapper&& rhs) noexcept( + Substitute(Substitute&& rhs) noexcept( std::is_nothrow_move_constructible::value) : counter_(rhs.counter_), closure_(std::move(rhs.closure_)) { ++counter_; } - Wrapper(ClosureCounter& counter, Closure&& closure) + Substitute(ClosureCounter& counter, Closure&& closure) : counter_(counter), closure_(std::forward(closure)) { ++counter_; } - Wrapper& - operator=(Wrapper const& rhs) = delete; - Wrapper& - operator=(Wrapper&& rhs) = delete; + Substitute& + operator=(Substitute const& rhs) = delete; + Substitute& + operator=(Substitute&& rhs) = delete; - ~Wrapper() + ~Substitute() { --counter_; } @@ -174,10 +188,10 @@ class ClosureCounter reference counter. */ template - boost::optional> + boost::optional> wrap(Closure&& closure) { - boost::optional> ret; + boost::optional> ret; std::lock_guard lock{mutex_}; if (!waitForClosures_) diff --git a/src/ripple/core/impl/Workers.h b/src/ripple/core/impl/Workers.h index f54093fba85..fe5072c568e 100644 --- a/src/ripple/core/impl/Workers.h +++ b/src/ripple/core/impl/Workers.h @@ -34,7 +34,36 @@ namespace perf { class PerfLog; } -/** A group of threads that process tasks. +/** + * `Workers` is effectively a thread pool. The constructor takes a "callback" + * that has a `void processTask(int instance)` method, and a number of + * workers. It creates that many Workers and then waits for calls to + * `Workers::addTask()`. It holds a semaphore that counts the number of + * waiting tasks, and a condition variable for the event when the last worker + * pauses itself. + * + * Creating a `Worker` creates a thread that calls `Worker::run()`. When that + * thread enters `Worker::run`, it increments the count of active workers in + * the parent `Workers` object and then blocks on the semaphore if there are + * no waiting tasks. It will be unblocked whenever the number of waiting tasks + * is incremented. That only happens in two circumstances: (1) when + * `Workers::addTask` is called and (2) when `Workers` wants to pause some + * workers ("pause one worker" is considered one task), which happens when + * someone wants to stop the workers or shrink the threadpool. No worker + * threads are ever destroyed until `Workers` is destroyed; it merely pauses + * workers until then. + * + * When an idle worker is woken, it checks whether `Workers` is trying to pause + * workers. If so, it adds itself to the set of paused workers and blocks on + * its own condition variable. If not, then it calls `processTask` on the + * "callback" held by `Workers`. + * + * When a paused worker is woken, it checks whether it should exit. The signal + * to exit is only set in the destructor of `Worker`, which unblocks the + * paused thread and waits for it to exit. A `Worker::run` thread checks + * whether it needs to exit only when it is woken from a pause (not when it is + * woken from idle). This is why the destructor for `Workers` pauses all the + * workers before destroying them. */ class Workers { From 846b0c7d91f316957fad59a83e968389fda58166 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 19 Jan 2021 11:23:39 -0600 Subject: [PATCH 39/62] [fold] Remove mentions of Stoppable --- src/ripple/core/ClosureCounter.h | 4 ++-- src/ripple/net/ShardDownloader.md | 2 +- src/ripple/net/impl/HTTPDownloader.cpp | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ripple/core/ClosureCounter.h b/src/ripple/core/ClosureCounter.h index c4bc31b9ffa..1468a3f2673 100644 --- a/src/ripple/core/ClosureCounter.h +++ b/src/ripple/core/ClosureCounter.h @@ -85,8 +85,8 @@ class ClosureCounter } // A private template class that helps count the number of closures - // in flight. This allows Stoppables to hold off declaring stopped() - // until all their postponed closures are dispatched. + // in flight. This allows callers to block until all their postponed + // closures are dispatched. template class Substitute { diff --git a/src/ripple/net/ShardDownloader.md b/src/ripple/net/ShardDownloader.md index ca9db7f53dd..8f63eb3317c 100644 --- a/src/ripple/net/ShardDownloader.md +++ b/src/ripple/net/ShardDownloader.md @@ -58,7 +58,7 @@ Much of the shard downloading process concerns the following classes: file, or simply return if there are no more downloads to process. When `complete` is invoked with no remaining files to be downloaded, the handler and downloader are not destroyed automatically, but persist for the duration - of the application to assist with graceful shutdowns by `Stoppable`. + of the application to assist with graceful shutdowns. - `DatabaseBody` diff --git a/src/ripple/net/impl/HTTPDownloader.cpp b/src/ripple/net/impl/HTTPDownloader.cpp index 3e3b511a75e..19fda003f3b 100644 --- a/src/ripple/net/impl/HTTPDownloader.cpp +++ b/src/ripple/net/impl/HTTPDownloader.cpp @@ -123,8 +123,9 @@ HTTPDownloader::do_session( // When the downloader is being stopped // because the server is shutting down, - // this method notifies a 'Stoppable' - // object that the session has ended. + // this method notifies a caller of `onStop` + // (`RPC::ShardArchiveHandler` to be specific) + // that the session has ended. auto exit = [this, &dstPath, complete] { if (!stop_) complete(std::move(dstPath)); From 6a45a85303073a617b05b59c76f351f4f1054bfe Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 19 Jan 2021 11:26:19 -0600 Subject: [PATCH 40/62] [fold] Rename HTTPDownloader::{onStop -> stop} --- src/ripple/net/HTTPDownloader.h | 2 +- src/ripple/net/ShardDownloader.md | 6 +++--- src/ripple/net/impl/HTTPDownloader.cpp | 2 +- src/ripple/rpc/impl/ShardArchiveHandler.cpp | 2 +- src/test/net/DatabaseDownloader_test.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ripple/net/HTTPDownloader.h b/src/ripple/net/HTTPDownloader.h index 971627e2f0c..1f2243a4fe4 100644 --- a/src/ripple/net/HTTPDownloader.h +++ b/src/ripple/net/HTTPDownloader.h @@ -57,7 +57,7 @@ class HTTPDownloader : public std::enable_shared_from_this bool ssl = true); void - onStop(); + stop(); virtual ~HTTPDownloader() = default; diff --git a/src/ripple/net/ShardDownloader.md b/src/ripple/net/ShardDownloader.md index 8f63eb3317c..786b7ad7b01 100644 --- a/src/ripple/net/ShardDownloader.md +++ b/src/ripple/net/ShardDownloader.md @@ -97,7 +97,7 @@ ShardArchiveHandler::stop() if (downloader_) { - downloader_->onStop(); + downloader_->stop(); downloader_.reset(); } @@ -105,13 +105,13 @@ ShardArchiveHandler::stop() } ``` -Inside of `HTTPDownloader::onStop()`, if a download is currently in progress, +Inside of `HTTPDownloader::stop()`, if a download is currently in progress, the `stop_` member variable is set and the thread waits for the download to stop: ```c++ void -HTTPDownloader::onStop() +HTTPDownloader::stop() { std::unique_lock lock(m_); diff --git a/src/ripple/net/impl/HTTPDownloader.cpp b/src/ripple/net/impl/HTTPDownloader.cpp index 19fda003f3b..5ed2ceae0db 100644 --- a/src/ripple/net/impl/HTTPDownloader.cpp +++ b/src/ripple/net/impl/HTTPDownloader.cpp @@ -281,7 +281,7 @@ HTTPDownloader::do_session( } void -HTTPDownloader::onStop() +HTTPDownloader::stop() { stop_ = true; diff --git a/src/ripple/rpc/impl/ShardArchiveHandler.cpp b/src/ripple/rpc/impl/ShardArchiveHandler.cpp index 2a9a3e101e3..3664d793fe1 100644 --- a/src/ripple/rpc/impl/ShardArchiveHandler.cpp +++ b/src/ripple/rpc/impl/ShardArchiveHandler.cpp @@ -195,7 +195,7 @@ ShardArchiveHandler::stop() if (downloader_) { - downloader_->onStop(); + downloader_->stop(); downloader_.reset(); } diff --git a/src/test/net/DatabaseDownloader_test.cpp b/src/test/net/DatabaseDownloader_test.cpp index c15f8e9b9ee..749000dc50a 100644 --- a/src/test/net/DatabaseDownloader_test.cpp +++ b/src/test/net/DatabaseDownloader_test.cpp @@ -95,7 +95,7 @@ class DatabaseDownloader_test : public beast::unit_test::suite ~Downloader() { - ptr_->onStop(); + ptr_->stop(); } DatabaseDownloader* From 5e892a787980ca733f0892e75db13968a7ad50e3 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 26 Jan 2021 14:51:12 -0600 Subject: [PATCH 41/62] [fold] review fixes --- src/ripple/app/ledger/LedgerCleaner.h | 7 ++++--- src/ripple/app/ledger/impl/LedgerCleaner.cpp | 8 -------- src/ripple/app/main/Application.cpp | 2 +- src/ripple/app/main/LoadManager.cpp | 2 +- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/ripple/app/ledger/LedgerCleaner.h b/src/ripple/app/ledger/LedgerCleaner.h index dadb4ad2624..0aded26711c 100644 --- a/src/ripple/app/ledger/LedgerCleaner.h +++ b/src/ripple/app/ledger/LedgerCleaner.h @@ -33,11 +33,12 @@ namespace detail { class LedgerCleaner : public beast::PropertyStream::Source { protected: - LedgerCleaner(); + LedgerCleaner() : beast::PropertyStream::Source("ledgercleaner") + { + } public: - /** Destroy the object. */ - virtual ~LedgerCleaner() = 0; + virtual ~LedgerCleaner() = default; virtual void start() = 0; diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index 299c957e5e6..10cb5ebd261 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -452,14 +452,6 @@ class LedgerCleanerImp : public LedgerCleaner } }; -//------------------------------------------------------------------------------ - -LedgerCleaner::LedgerCleaner() : beast::PropertyStream::Source("ledgercleaner") -{ -} - -LedgerCleaner::~LedgerCleaner() = default; - std::unique_ptr make_LedgerCleaner(Application& app, beast::Journal journal) { diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index f11fbdd8b8d..ca522b3708e 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1075,10 +1075,10 @@ class ApplicationImp : public Application, public BasicApp shardStore_->stop(); if (config_->reporting()) { + reportingETL_->stop(); #ifdef RIPPLED_REPORTING pgPool_->stop(); #endif - reportingETL_->stop(); } m_inboundLedgers->stop(); m_inboundTransactions->stop(); diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index e19685ce42c..e61baccd178 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -110,7 +110,7 @@ LoadManager::run() { { t += 1s; - std::unique_lock sl(mutex_); + std::unique_lock sl(mutex_); if (cv_.wait_until(sl, t, [this] { return stop_; })) { break; From e8a8d3e4bee3ac20fc477488a99e94ce3787b4b6 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 27 Jan 2021 10:42:51 -0600 Subject: [PATCH 42/62] [fold] LedgerReplayer is not a Stoppable --- src/ripple/app/ledger/LedgerReplayer.h | 8 +++----- src/ripple/app/ledger/impl/LedgerReplayer.cpp | 13 +++++-------- src/ripple/app/main/Application.cpp | 4 ++-- src/test/app/LedgerReplay_test.cpp | 18 +++++++----------- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/ripple/app/ledger/LedgerReplayer.h b/src/ripple/app/ledger/LedgerReplayer.h index 5ef9906de49..e9e94548b74 100644 --- a/src/ripple/app/ledger/LedgerReplayer.h +++ b/src/ripple/app/ledger/LedgerReplayer.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -70,14 +69,13 @@ std::uint32_t constexpr MAX_QUEUED_TASKS = 100; /** * Manages the lifetime of ledger replay tasks. */ -class LedgerReplayer final : public Stoppable +class LedgerReplayer final { public: LedgerReplayer( Application& app, InboundLedgers& inboundLedgers, - std::unique_ptr peerSetBuilder, - Stoppable& parent); + std::unique_ptr peerSetBuilder); ~LedgerReplayer(); @@ -125,7 +123,7 @@ class LedgerReplayer final : public Stoppable sweep(); void - onStop() override; + stop(); private: mutable std::mutex mtx_; diff --git a/src/ripple/app/ledger/impl/LedgerReplayer.cpp b/src/ripple/app/ledger/impl/LedgerReplayer.cpp index b9d4d014e39..9ec5c6f2cbd 100644 --- a/src/ripple/app/ledger/impl/LedgerReplayer.cpp +++ b/src/ripple/app/ledger/impl/LedgerReplayer.cpp @@ -27,10 +27,8 @@ namespace ripple { LedgerReplayer::LedgerReplayer( Application& app, InboundLedgers& inboundLedgers, - std::unique_ptr peerSetBuilder, - Stoppable& parent) - : Stoppable("LedgerReplayer", parent) - , app_(app) + std::unique_ptr peerSetBuilder) + : app_(app) , inboundLedgers_(inboundLedgers) , peerSetBuilder_(std::move(peerSetBuilder)) , j_(app.journal("LedgerReplayer")) @@ -61,7 +59,7 @@ LedgerReplayer::replay( bool newSkipList = false; { std::lock_guard lock(mtx_); - if (isStopping()) + if (app_.isStopping()) return; if (tasks_.size() >= LedgerReplayParameters::MAX_TASKS) { @@ -145,7 +143,7 @@ LedgerReplayer::createDeltas(std::shared_ptr task) bool newDelta = false; { std::lock_guard lock(mtx_); - if (isStopping()) + if (app_.isStopping()) return; auto i = deltas_.find(*skipListItem); if (i != deltas_.end()) @@ -256,7 +254,7 @@ LedgerReplayer::sweep() } void -LedgerReplayer::onStop() +LedgerReplayer::stop() { JLOG(j_.info()) << "Stopping..."; { @@ -276,7 +274,6 @@ LedgerReplayer::onStop() deltas_.clear(); } - stopped(); JLOG(j_.info()) << "Stopped"; } diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index f792792f69c..d261b25a60f 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -359,8 +359,7 @@ class ApplicationImp : public Application, public BasicApp , m_ledgerReplayer(std::make_unique( *this, *m_inboundLedgers, - make_PeerSetBuilder(*this), - *m_jobQueue)) + make_PeerSetBuilder(*this))) , m_acceptedLedgerCache( "AcceptedLedger", @@ -1097,6 +1096,7 @@ class ApplicationImp : public Application, public BasicApp } m_inboundLedgers->stop(); m_inboundTransactions->stop(); + m_ledgerReplayer->stop(); overlay_->stop(); perfLog_->stop(); grpcServer_->stop(); diff --git a/src/test/app/LedgerReplay_test.cpp b/src/test/app/LedgerReplay_test.cpp index 1b9f5ab7128..5ae5e683f8b 100644 --- a/src/test/app/LedgerReplay_test.cpp +++ b/src/test/app/LedgerReplay_test.cpp @@ -168,7 +168,7 @@ class MagicInboundLedgers : public InboundLedgers } virtual void - onStop() override + stop() override { } @@ -563,7 +563,6 @@ class LedgerReplayClient inboundBhvr) , serverMsgHandler(server.app, server.app.getLedgerReplayer()) , clientMsgHandler(env.app(), replayer) - , stopableParent("replayerStopParent") , replayer( env.app(), inboundLedgers, @@ -571,8 +570,7 @@ class LedgerReplayClient clientMsgHandler, serverMsgHandler, behavior, - peerFeature), - stopableParent) + peerFeature)) { } @@ -799,7 +797,6 @@ class LedgerReplayClient MagicInboundLedgers inboundLedgers; LedgerReplayMsgHandler serverMsgHandler; LedgerReplayMsgHandler clientMsgHandler; - RootStoppable stopableParent; LedgerReplayer replayer; }; @@ -847,7 +844,7 @@ struct NetworkOfTwo * -- replay a range of ledgers and fallback to InboundLedgers because * peers do not support ProtocolFeature::LedgerReplay * -- replay a range of ledgers and the network drops or repeats messages - * -- call onStop() and the tasks and subtasks are removed + * -- call stop() and the tasks and subtasks are removed * -- process a bad skip list * -- process a bad ledger delta * -- replay ledger ranges with different overlaps @@ -1228,9 +1225,9 @@ struct LedgerReplayer_test : public beast::unit_test::suite } void - testOnStop() + testStop() { - testcase("onStop before timeout"); + testcase("stop before timeout"); int totalReplay = 3; NetworkOfTwo net( *this, @@ -1252,9 +1249,8 @@ struct LedgerReplayer_test : public beast::unit_test::suite TaskStatus::NotDone, deltaStatuses)); - // onStop BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0)); - net.client.replayer.onStop(); + net.client.replayer.stop(); BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0)); } @@ -1436,7 +1432,7 @@ struct LedgerReplayer_test : public beast::unit_test::suite testPeerSetBehavior(PeerSetBehavior::Good); testPeerSetBehavior(PeerSetBehavior::Drop50); testPeerSetBehavior(PeerSetBehavior::Repeat); - testOnStop(); + testStop(); testSkipListBadReply(); testLedgerDeltaBadReply(); testLedgerReplayOverlap(); From bd22635e6f4a5f2978216dd1430ef7b79807939a Mon Sep 17 00:00:00 2001 From: John Freeman Date: Sat, 30 Jan 2021 18:07:31 -0600 Subject: [PATCH 43/62] [fold] Use CTAD --- src/ripple/rpc/impl/ServerHandlerImp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index eebcbdd7489..e8f51c01886 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -141,7 +141,7 @@ ServerHandlerImp::stop() { m_server->close(); { - std::unique_lock lock(mutex_); + std::unique_lock lock(mutex_); condition_.wait(lock, [&] { return stopped_; }); } } @@ -370,7 +370,7 @@ ServerHandlerImp::onClose(Session& session, boost::system::error_code const&) void ServerHandlerImp::onStopped(Server&) { - std::lock_guard lock(mutex_); + std::lock_guard lock(mutex_); stopped_ = true; condition_.notify_one(); } From a40ddf28abd9b3b9b25ddcfd7d6ac744ae40aca2 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Sat, 30 Jan 2021 18:14:45 -0600 Subject: [PATCH 44/62] [fold] Move start, stop to PerfLog interface and use it --- src/ripple/app/main/Application.cpp | 8 ++++---- src/ripple/basics/PerfLog.h | 20 ++++++++++++++++++++ src/ripple/basics/impl/PerfLogImp.cpp | 4 ++-- src/ripple/basics/impl/PerfLogImp.h | 13 ++----------- src/test/basics/PerfLog_test.cpp | 6 +++--- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index d261b25a60f..744abbd7406 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -47,8 +47,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -159,7 +159,7 @@ class ApplicationImp : public Application, public BasicApp std::unique_ptr timeKeeper_; beast::Journal m_journal; - std::unique_ptr perfLog_; + std::unique_ptr perfLog_; Application::MutexType m_masterMutex; // Required by the SHAMapStore @@ -268,12 +268,12 @@ class ApplicationImp : public Application, public BasicApp , m_journal(logs_->journal("Application")) // PerfLog must be started before any other threads are launched. - , perfLog_(perf::make_PerfLogImp( + , perfLog_(perf::make_PerfLog( perf::setup_PerfLog( config_->section("perf"), config_->CONFIG_DIR), logs_->journal("PerfLog"), - [&] { signalStop(); })) + [this] { signalStop(); })) , m_txMaster(*this) #ifdef RIPPLED_REPORTING diff --git a/src/ripple/basics/PerfLog.h b/src/ripple/basics/PerfLog.h index b1ec2603252..f62fd4f78a8 100644 --- a/src/ripple/basics/PerfLog.h +++ b/src/ripple/basics/PerfLog.h @@ -20,6 +20,7 @@ #ifndef RIPPLE_BASICS_PERFLOG_H #define RIPPLE_BASICS_PERFLOG_H +#include #include #include #include @@ -66,6 +67,16 @@ class PerfLog virtual ~PerfLog() = default; + virtual void + start() + { + } + + virtual void + stop() + { + } + /** * Log start of RPC call. * @@ -157,6 +168,15 @@ class PerfLog rotate() = 0; }; +PerfLog::Setup +setup_PerfLog(Section const& section, boost::filesystem::path const& configDir); + +std::unique_ptr +make_PerfLog( + PerfLog::Setup const& setup, + beast::Journal journal, + std::function&& signalStop); + } // namespace perf } // namespace ripple diff --git a/src/ripple/basics/impl/PerfLogImp.cpp b/src/ripple/basics/impl/PerfLogImp.cpp index dcd1c78230b..c09661e3c26 100644 --- a/src/ripple/basics/impl/PerfLogImp.cpp +++ b/src/ripple/basics/impl/PerfLogImp.cpp @@ -488,8 +488,8 @@ setup_PerfLog(Section const& section, boost::filesystem::path const& configDir) return setup; } -std::unique_ptr -make_PerfLogImp( +std::unique_ptr +make_PerfLog( PerfLog::Setup const& setup, beast::Journal journal, std::function&& signalStop) diff --git a/src/ripple/basics/impl/PerfLogImp.h b/src/ripple/basics/impl/PerfLogImp.h index 014a7b5453a..412f4e2e7a8 100644 --- a/src/ripple/basics/impl/PerfLogImp.h +++ b/src/ripple/basics/impl/PerfLogImp.h @@ -199,21 +199,12 @@ class PerfLogImp : public PerfLog rotate() override; void - start(); + start() override; void - stop(); + stop() override; }; -PerfLog::Setup -setup_PerfLog(Section const& section, boost::filesystem::path const& configDir); - -std::unique_ptr -make_PerfLogImp( - PerfLog::Setup const& setup, - beast::Journal journal, - std::function&& signalStop); - } // namespace perf } // namespace ripple diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index 5f9e941419c..13f3cb9f54d 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include #include #include #include @@ -97,12 +97,12 @@ class PerfLog_test : public beast::unit_test::suite return std::chrono::milliseconds{10}; } - std::unique_ptr + std::unique_ptr perfLog(WithFile withFile) { perf::PerfLog::Setup const setup{ withFile == WithFile::no ? "" : logFile(), logInterval()}; - return perf::make_PerfLogImp( + return perf::make_PerfLog( setup, j_, [this]() { return signalStop(); }); } From 6fe6f26151c2b241ad7c0ae4c458b2eb6dae70e1 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Sat, 30 Jan 2021 18:20:19 -0600 Subject: [PATCH 45/62] [fold] Prefer narrow capture list --- src/ripple/app/ledger/impl/LedgerCleaner.cpp | 2 +- src/ripple/core/impl/JobQueue.cpp | 5 +++-- src/ripple/rpc/impl/ServerHandlerImp.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index 10cb5ebd261..08a34f2724f 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -377,7 +377,7 @@ class LedgerCleanerImp : public LedgerCleaner void doLedgerCleaner() { - auto shouldExit = [&] { + auto shouldExit = [this] { std::lock_guard lock(mutex_); return shouldExit_; }; diff --git a/src/ripple/core/impl/JobQueue.cpp b/src/ripple/core/impl/JobQueue.cpp index a8d4c569fa1..29bd64e0653 100644 --- a/src/ripple/core/impl/JobQueue.cpp +++ b/src/ripple/core/impl/JobQueue.cpp @@ -261,7 +261,7 @@ void JobQueue::rendezvous() { std::unique_lock lock(m_mutex); - cv_.wait(lock, [&] { return m_processCount == 0 && m_jobSet.empty(); }); + cv_.wait(lock, [this] { return m_processCount == 0 && m_jobSet.empty(); }); } JobTypeData& @@ -291,7 +291,8 @@ JobQueue::stop() // `Job::doJob` and the return of `JobQueue::processTask`. That is why // we must wait on the condition variable to make these assertions. std::unique_lock lock(m_mutex); - cv_.wait(lock, [&] { return m_processCount == 0 && m_jobSet.empty(); }); + cv_.wait( + lock, [this] { return m_processCount == 0 && m_jobSet.empty(); }); assert(m_processCount == 0); assert(m_jobSet.empty()); assert(nSuspend_ == 0); diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index e8f51c01886..8116205401d 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -142,7 +142,7 @@ ServerHandlerImp::stop() m_server->close(); { std::unique_lock lock(mutex_); - condition_.wait(lock, [&] { return stopped_; }); + condition_.wait(lock, [this] { return stopped_; }); } } From 905a274b3adccfb92ba467843e1e5d556a4e0408 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Sat, 30 Jan 2021 18:26:28 -0600 Subject: [PATCH 46/62] [fold] Rename Timer::{start -> async_wait} --- src/ripple/overlay/impl/OverlayImpl.cpp | 6 +++--- src/ripple/overlay/impl/OverlayImpl.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 503d5b55f46..20aef443c5f 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -79,7 +79,7 @@ OverlayImpl::Timer::stop() } void -OverlayImpl::Timer::start() +OverlayImpl::Timer::async_wait() { timer_.expires_after(std::chrono::seconds(1)); timer_.async_wait(overlay_.strand_.wrap(std::bind( @@ -105,7 +105,7 @@ OverlayImpl::Timer::on_timer(error_code ec) if ((overlay_.timer_count_ % Tuning::checkIdlePeers) == 0) overlay_.deleteIdlePeers(); - start(); + async_wait(); } //------------------------------------------------------------------------------ @@ -541,7 +541,7 @@ OverlayImpl::start() std::lock_guard lock(mutex_); list_.emplace(timer.get(), timer); timer_ = timer; - timer->start(); + timer->async_wait(); } void diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index 2c95aecd134..1ccc14b1b84 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -89,7 +89,7 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler stop() override; void - start(); + async_wait(); void on_timer(error_code ec); From f556e0734dcb84ddb1ec6084b4ece983318e68ba Mon Sep 17 00:00:00 2001 From: John Freeman Date: Sat, 30 Jan 2021 19:15:29 -0600 Subject: [PATCH 47/62] [fold] Move start, stop to Overlay interface and use it --- src/ripple/app/main/Application.cpp | 4 ++-- src/ripple/overlay/Overlay.h | 10 ++++++++++ src/ripple/overlay/impl/OverlayImpl.cpp | 4 ++-- src/ripple/overlay/impl/OverlayImpl.h | 4 ++-- src/ripple/overlay/make_Overlay.h | 6 +++--- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 744abbd7406..8d164bf7c8d 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -218,7 +218,7 @@ class ApplicationImp : public Application, public BasicApp std::unique_ptr mTxnDB; std::unique_ptr mLedgerDB; std::unique_ptr mWalletDB; - std::unique_ptr overlay_; + std::unique_ptr overlay_; boost::asio::signal_set m_signals; @@ -1520,7 +1520,7 @@ ApplicationImp::setup() // if (!config_.standalone()) if (!config_->reporting()) { - overlay_ = make_OverlayImpl( + overlay_ = make_Overlay( *this, setup_Overlay(*config_), *serverHandler_, diff --git a/src/ripple/overlay/Overlay.h b/src/ripple/overlay/Overlay.h index d0c7b09ad26..1faa698b444 100644 --- a/src/ripple/overlay/Overlay.h +++ b/src/ripple/overlay/Overlay.h @@ -80,6 +80,16 @@ class Overlay : public beast::PropertyStream::Source virtual ~Overlay() = default; + virtual void + start() + { + } + + virtual void + stop() + { + } + /** Conditionally accept an incoming HTTP request. */ virtual Handoff onHandoff( diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 20aef443c5f..960c75f02b1 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -1528,8 +1528,8 @@ setup_Overlay(BasicConfig const& config) return setup; } -std::unique_ptr -make_OverlayImpl( +std::unique_ptr +make_Overlay( Application& app, Overlay::Setup const& setup, ServerHandler& serverHandler, diff --git a/src/ripple/overlay/impl/OverlayImpl.h b/src/ripple/overlay/impl/OverlayImpl.h index 1ccc14b1b84..6aa5f6350f0 100644 --- a/src/ripple/overlay/impl/OverlayImpl.h +++ b/src/ripple/overlay/impl/OverlayImpl.h @@ -154,10 +154,10 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler operator=(OverlayImpl const&) = delete; void - start(); + start() override; void - stop(); + stop() override; PeerFinder::Manager& peerFinder() diff --git a/src/ripple/overlay/make_Overlay.h b/src/ripple/overlay/make_Overlay.h index a8774fb4a1a..9a63f5a46af 100644 --- a/src/ripple/overlay/make_Overlay.h +++ b/src/ripple/overlay/make_Overlay.h @@ -21,7 +21,7 @@ #define RIPPLE_OVERLAY_MAKE_OVERLAY_H_INCLUDED #include -#include +#include #include #include #include @@ -33,8 +33,8 @@ Overlay::Setup setup_Overlay(BasicConfig const& config); /** Creates the implementation of Overlay. */ -std::unique_ptr -make_OverlayImpl( +std::unique_ptr +make_Overlay( Application& app, Overlay::Setup const& setup, ServerHandler& serverHandler, From a4fbb6c736d0fe632b4c87e886601523087a88f0 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 1 Feb 2021 09:06:15 -0600 Subject: [PATCH 48/62] [fold] Stop at the beginning of every NodeStore::Database destructor --- src/ripple/nodestore/Database.h | 2 +- src/ripple/nodestore/impl/Database.cpp | 15 +++++------ src/ripple/nodestore/impl/DatabaseNodeImp.h | 5 ++++ .../nodestore/impl/DatabaseRotatingImp.h | 5 ++++ .../nodestore/impl/DatabaseShardImp.cpp | 25 +++++++------------ src/ripple/nodestore/impl/DatabaseShardImp.h | 5 ++++ 6 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/ripple/nodestore/Database.h b/src/ripple/nodestore/Database.h index 2eef702a9f8..d9c48880a13 100644 --- a/src/ripple/nodestore/Database.h +++ b/src/ripple/nodestore/Database.h @@ -292,7 +292,7 @@ class Database uint256 readLastHash_; std::vector readThreads_; - bool readShut_{false}; + bool readStopping_{false}; // The default is 32570 to match the XRP ledger network's earliest // allowed sequence. Alternate networks may set this value. diff --git a/src/ripple/nodestore/impl/Database.cpp b/src/ripple/nodestore/impl/Database.cpp index 06e83aff44a..8ff2dc179c9 100644 --- a/src/ripple/nodestore/impl/Database.cpp +++ b/src/ripple/nodestore/impl/Database.cpp @@ -61,7 +61,7 @@ bool Database::isStopping() const { std::lock_guard lock(readLock_); - return readShut_; + return readStopping_; } void @@ -71,10 +71,10 @@ Database::stop() // reads. Join the background read threads. { std::lock_guard lock(readLock_); - if (readShut_) // Only stop threads once. + if (readStopping_) // Only stop threads once. return; - readShut_ = true; + readStopping_ = true; readCondVar_.notify_all(); } @@ -272,12 +272,9 @@ Database::threadEntry() { std::unique_lock lock(readLock_); - while (!readShut_ && read_.empty()) - { - // All work is done - readCondVar_.wait(lock); - } - if (readShut_) + readCondVar_.wait( + lock, [this] { return readStopping_ || !read_.empty(); }); + if (readStopping_) break; // Read in key order to make the back end more efficient diff --git a/src/ripple/nodestore/impl/DatabaseNodeImp.h b/src/ripple/nodestore/impl/DatabaseNodeImp.h index f1b8e9b7c05..4c97e56bbc9 100644 --- a/src/ripple/nodestore/impl/DatabaseNodeImp.h +++ b/src/ripple/nodestore/impl/DatabaseNodeImp.h @@ -78,6 +78,11 @@ class DatabaseNodeImp : public Database assert(backend_); } + ~DatabaseNodeImp() + { + stop(); + } + std::string getName() const override { diff --git a/src/ripple/nodestore/impl/DatabaseRotatingImp.h b/src/ripple/nodestore/impl/DatabaseRotatingImp.h index e3b0d54db2c..9903f4a404f 100644 --- a/src/ripple/nodestore/impl/DatabaseRotatingImp.h +++ b/src/ripple/nodestore/impl/DatabaseRotatingImp.h @@ -41,6 +41,11 @@ class DatabaseRotatingImp : public DatabaseRotating Section const& config, beast::Journal j); + ~DatabaseRotatingImp() + { + stop(); + } + void rotateWithLock( std::function( diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index 70dfe866cd0..3d8384f996a 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -693,32 +693,25 @@ DatabaseShardImp::stop() { // Stop read threads in base before data members are destroyed Database::stop(); - { - std::lock_guard lock(mutex_); - for (auto const& [_, shard] : shards_) - shard->stop(); - } - taskQueue_.stop(); - std::vector> shards; { std::lock_guard lock(mutex_); - shards.reserve(shards_.size()); - for (auto const& e : shards_) - shards.push_back(e.second); + for (auto const& [_, shard] : shards_) + { + shards.push_back(shard); + shard->stop(); + } shards_.clear(); } + taskQueue_.stop(); // All shards should be expired at this point - for (auto const& e : shards) + for (auto const& wptr : shards) { - if (!e.expired()) + if (auto const shard{wptr.lock()}) { - std::string shardIndex; - if (auto const shard{e.lock()}; shard) - shardIndex = std::to_string(shard->index()); - + std::string shardIndex = std::to_string(shard->index()); JLOG(j_.warn()) << " shard " << shardIndex << " unexpired"; } } diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.h b/src/ripple/nodestore/impl/DatabaseShardImp.h index d90d61d8077..aee6fed54f8 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.h +++ b/src/ripple/nodestore/impl/DatabaseShardImp.h @@ -46,6 +46,11 @@ class DatabaseShardImp : public DatabaseShard int readThreads, beast::Journal j); + ~DatabaseShardImp() + { + stop(); + } + [[nodiscard]] bool init() override; From 954c6fbc1a8484ed978db213427934be6a57ad60 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 1 Feb 2021 09:07:50 -0600 Subject: [PATCH 49/62] [fold] Rename Workers::{pauseAllThreadsAndWait -> stop} --- src/ripple/core/impl/Workers.cpp | 4 ++-- src/ripple/core/impl/Workers.h | 2 +- src/ripple/nodestore/impl/TaskQueue.cpp | 2 +- src/test/core/Workers_test.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ripple/core/impl/Workers.cpp b/src/ripple/core/impl/Workers.cpp index 321ca368568..732e6f0ec8a 100644 --- a/src/ripple/core/impl/Workers.cpp +++ b/src/ripple/core/impl/Workers.cpp @@ -44,7 +44,7 @@ Workers::Workers( Workers::~Workers() { - pauseAllThreadsAndWait(); + stop(); deleteWorkers(m_everyone); } @@ -111,7 +111,7 @@ Workers::setNumberOfThreads(int numberOfThreads) } void -Workers::pauseAllThreadsAndWait() +Workers::stop() { setNumberOfThreads(0); diff --git a/src/ripple/core/impl/Workers.h b/src/ripple/core/impl/Workers.h index fe5072c568e..0abbbe429ce 100644 --- a/src/ripple/core/impl/Workers.h +++ b/src/ripple/core/impl/Workers.h @@ -133,7 +133,7 @@ class Workers @note This function is not thread-safe. */ void - pauseAllThreadsAndWait(); + stop(); /** Add a task to be performed. diff --git a/src/ripple/nodestore/impl/TaskQueue.cpp b/src/ripple/nodestore/impl/TaskQueue.cpp index d069307dcd2..7b917fdd77d 100644 --- a/src/ripple/nodestore/impl/TaskQueue.cpp +++ b/src/ripple/nodestore/impl/TaskQueue.cpp @@ -31,7 +31,7 @@ TaskQueue::TaskQueue() : workers_(*this, nullptr, "Shard store taskQueue", 1) void TaskQueue::stop() { - workers_.pauseAllThreadsAndWait(); + workers_.stop(); } void diff --git a/src/test/core/Workers_test.cpp b/src/test/core/Workers_test.cpp index 7243732af10..155dd14f030 100644 --- a/src/test/core/Workers_test.cpp +++ b/src/test/core/Workers_test.cpp @@ -156,7 +156,7 @@ class Workers_test : public beast::unit_test::suite testForThreadCount(tc1); testForThreadCount(tc2); testForThreadCount(tc3); - w.pauseAllThreadsAndWait(); + w.stop(); // We had better finished all our work! BEAST_EXPECT(cb.count == 0); From 3596ce58b7762549973dd1c1cbf57fea8c8f0f77 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 1 Feb 2021 09:47:15 -0600 Subject: [PATCH 50/62] [fold] Ignore overlay when it is missing --- src/ripple/app/main/Application.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 8d164bf7c8d..3fee22ab5e6 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1097,7 +1097,8 @@ class ApplicationImp : public Application, public BasicApp m_inboundLedgers->stop(); m_inboundTransactions->stop(); m_ledgerReplayer->stop(); - overlay_->stop(); + if (overlay_) + overlay_->stop(); perfLog_->stop(); grpcServer_->stop(); m_networkOPs->stop(); @@ -1712,7 +1713,8 @@ ApplicationImp::start(bool withTimers) m_resolver->start(); m_loadManager->start(); m_shaMapStore->start(); - overlay_->start(); + if (overlay_) + overlay_->start(); grpcServer_->start(); m_ledgerMaster->start(); perfLog_->start(); From fcba4a648f29bdb98c1aa6d218300a4611c3a5e1 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 2 Feb 2021 10:30:25 -0600 Subject: [PATCH 51/62] [fold] Fix comment --- src/ripple/nodestore/impl/Database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ripple/nodestore/impl/Database.cpp b/src/ripple/nodestore/impl/Database.cpp index 8ff2dc179c9..9ae4d36e919 100644 --- a/src/ripple/nodestore/impl/Database.cpp +++ b/src/ripple/nodestore/impl/Database.cpp @@ -49,7 +49,7 @@ Database::Database( Database::~Database() { // NOTE! - // Any derived class should call the stopReadThreads() method in its + // Any derived class should call the stop() method in its // destructor. Otherwise, occasionally, the derived class may // crash during shutdown when its members are accessed by one of // these threads after the derived class is destroyed but before From 92e9c6a1fab6d5d17bff7c125f127b3d9fdacfa4 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Wed, 3 Feb 2021 10:13:23 -0600 Subject: [PATCH 52/62] [fold] Stop ServerHandlerImp --- src/ripple/app/main/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 3fee22ab5e6..a6ee3744978 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1101,6 +1101,7 @@ class ApplicationImp : public Application, public BasicApp overlay_->stop(); perfLog_->stop(); grpcServer_->stop(); + serverHandler_->stop(); m_networkOPs->stop(); m_ledgerMaster->stop(); m_loadManager->stop(); From 01521e5310a3ad69a1562581b54f02670238f0d2 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Sat, 6 Feb 2021 21:04:40 -0600 Subject: [PATCH 53/62] [fold] Rearrange stop sequence --- src/ripple/app/main/Application.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index a6ee3744978..476bf6a5a95 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1080,13 +1080,22 @@ class ApplicationImp : public Application, public BasicApp // The order of these stop calls is delicate. // Re-ordering them risks undefined behavior. + m_loadManager->stop(); m_shaMapStore->stop(); m_jobQueue->stop(); if (shardArchiveHandler_) shardArchiveHandler_->stop(); - m_nodeStore->stop(); + if (overlay_) + overlay_->stop(); if (shardStore_) shardStore_->stop(); + grpcServer_->stop(); + m_networkOPs->stop(); + serverHandler_->stop(); + m_ledgerReplayer->stop(); + m_inboundTransactions->stop(); + m_inboundLedgers->stop(); + m_ledgerMaster->stop(); if (config_->reporting()) { reportingETL_->stop(); @@ -1094,17 +1103,8 @@ class ApplicationImp : public Application, public BasicApp pgPool_->stop(); #endif } - m_inboundLedgers->stop(); - m_inboundTransactions->stop(); - m_ledgerReplayer->stop(); - if (overlay_) - overlay_->stop(); + m_nodeStore->stop(); perfLog_->stop(); - grpcServer_->stop(); - serverHandler_->stop(); - m_networkOPs->stop(); - m_ledgerMaster->stop(); - m_loadManager->stop(); } //-------------------------------------------------------------------------- From 6a025ff729d94185a2030ce4af6ffaa91854ff45 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 5 Feb 2021 15:59:24 -0600 Subject: [PATCH 54/62] Fix declaration of CassandraBackend::counters_ --- src/ripple/nodestore/backend/CassandraFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ripple/nodestore/backend/CassandraFactory.cpp b/src/ripple/nodestore/backend/CassandraFactory.cpp index a568ce58b23..ff57c983a2f 100644 --- a/src/ripple/nodestore/backend/CassandraFactory.cpp +++ b/src/ripple/nodestore/backend/CassandraFactory.cpp @@ -128,7 +128,7 @@ class CassandraBackend : public Backend std::mutex syncMutex_; std::condition_variable syncCv_; - Counters counters_; + Counters> counters_; public: CassandraBackend( From 51adc26e91abaff8bc7e9fd71fa00df0b971a379 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 8 Feb 2021 11:54:42 -0600 Subject: [PATCH 55/62] [fold] review fixes --- src/ripple/app/main/Application.cpp | 2 +- src/ripple/app/main/CollectorManager.cpp | 4 +--- src/ripple/app/main/CollectorManager.h | 8 +++++--- src/ripple/app/main/LoadManager.cpp | 2 +- src/ripple/app/main/NodeStoreScheduler.cpp | 9 ++++----- src/ripple/app/main/NodeStoreScheduler.h | 2 +- src/ripple/nodestore/impl/DatabaseShardImp.cpp | 3 +-- src/ripple/rpc/impl/ServerHandlerImp.cpp | 2 +- 8 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 476bf6a5a95..f92b9a4c354 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -284,7 +284,7 @@ class ApplicationImp : public Application, public BasicApp : nullptr) #endif - , m_collectorManager(CollectorManager::New( + , m_collectorManager(make_CollectorManager( config_->section(SECTION_INSIGHT), logs_->journal("Collector"))) diff --git a/src/ripple/app/main/CollectorManager.cpp b/src/ripple/app/main/CollectorManager.cpp index d23aeb8a3f4..0781b271e60 100644 --- a/src/ripple/app/main/CollectorManager.cpp +++ b/src/ripple/app/main/CollectorManager.cpp @@ -68,10 +68,8 @@ class CollectorManagerImp : public CollectorManager //------------------------------------------------------------------------------ -CollectorManager::~CollectorManager() = default; - std::unique_ptr -CollectorManager::New(Section const& params, beast::Journal journal) +make_CollectorManager(Section const& params, beast::Journal journal) { return std::make_unique(params, journal); } diff --git a/src/ripple/app/main/CollectorManager.h b/src/ripple/app/main/CollectorManager.h index 0b352a57a3d..46e113082d4 100644 --- a/src/ripple/app/main/CollectorManager.h +++ b/src/ripple/app/main/CollectorManager.h @@ -29,16 +29,18 @@ namespace ripple { class CollectorManager { public: - static std::unique_ptr - New(Section const& params, beast::Journal journal); + virtual ~CollectorManager() = default; - virtual ~CollectorManager() = 0; virtual beast::insight::Collector::ptr const& collector() = 0; + virtual beast::insight::Group::ptr const& group(std::string const& name) = 0; }; +std::unique_ptr +make_CollectorManager(Section const& params, beast::Journal journal); + } // namespace ripple #endif diff --git a/src/ripple/app/main/LoadManager.cpp b/src/ripple/app/main/LoadManager.cpp index e61baccd178..be4b7ec97fc 100644 --- a/src/ripple/app/main/LoadManager.cpp +++ b/src/ripple/app/main/LoadManager.cpp @@ -82,7 +82,7 @@ void LoadManager::stop() { { - std::lock_guard sl(mutex_); + std::lock_guard lock(mutex_); stop_ = true; // There is at most one thread waiting on this condition. cv_.notify_all(); diff --git a/src/ripple/app/main/NodeStoreScheduler.cpp b/src/ripple/app/main/NodeStoreScheduler.cpp index d1bab68b5a0..d94c7ee3f07 100644 --- a/src/ripple/app/main/NodeStoreScheduler.cpp +++ b/src/ripple/app/main/NodeStoreScheduler.cpp @@ -22,15 +22,14 @@ namespace ripple { -NodeStoreScheduler::NodeStoreScheduler(JobQueue& jobQueue) - : m_jobQueue(&jobQueue) +NodeStoreScheduler::NodeStoreScheduler(JobQueue& jobQueue) : jobQueue_(jobQueue) { } void NodeStoreScheduler::scheduleTask(NodeStore::Task& task) { - if (!m_jobQueue->addJob(jtWRITE, "NodeObject::store", [&task](Job&) { + if (!jobQueue_.addJob(jtWRITE, "NodeObject::store", [&task](Job&) { task.performScheduledTask(); })) { @@ -43,7 +42,7 @@ NodeStoreScheduler::scheduleTask(NodeStore::Task& task) void NodeStoreScheduler::onFetch(NodeStore::FetchReport const& report) { - m_jobQueue->addLoadEvents( + jobQueue_.addLoadEvents( report.fetchType == NodeStore::FetchType::async ? jtNS_ASYNC_READ : jtNS_SYNC_READ, 1, @@ -53,7 +52,7 @@ NodeStoreScheduler::onFetch(NodeStore::FetchReport const& report) void NodeStoreScheduler::onBatchWrite(NodeStore::BatchWriteReport const& report) { - m_jobQueue->addLoadEvents(jtNS_WRITE, report.writeCount, report.elapsed); + jobQueue_.addLoadEvents(jtNS_WRITE, report.writeCount, report.elapsed); } } // namespace ripple diff --git a/src/ripple/app/main/NodeStoreScheduler.h b/src/ripple/app/main/NodeStoreScheduler.h index 6073be760cf..533b7497b2c 100644 --- a/src/ripple/app/main/NodeStoreScheduler.h +++ b/src/ripple/app/main/NodeStoreScheduler.h @@ -40,7 +40,7 @@ class NodeStoreScheduler : public NodeStore::Scheduler onBatchWrite(NodeStore::BatchWriteReport const& report) override; private: - JobQueue* m_jobQueue; + JobQueue& jobQueue_; }; } // namespace ripple diff --git a/src/ripple/nodestore/impl/DatabaseShardImp.cpp b/src/ripple/nodestore/impl/DatabaseShardImp.cpp index bc3c805d4b3..028312d5692 100644 --- a/src/ripple/nodestore/impl/DatabaseShardImp.cpp +++ b/src/ripple/nodestore/impl/DatabaseShardImp.cpp @@ -705,8 +705,7 @@ DatabaseShardImp::stop() { if (auto const shard{wptr.lock()}) { - std::string shardIndex = std::to_string(shard->index()); - JLOG(j_.warn()) << " shard " << shardIndex << " unexpired"; + JLOG(j_.warn()) << " shard " << shard->index() << " unexpired"; } } } diff --git a/src/ripple/rpc/impl/ServerHandlerImp.cpp b/src/ripple/rpc/impl/ServerHandlerImp.cpp index 8116205401d..55e0561eb87 100644 --- a/src/ripple/rpc/impl/ServerHandlerImp.cpp +++ b/src/ripple/rpc/impl/ServerHandlerImp.cpp @@ -163,7 +163,7 @@ ServerHandlerImp::onAccept( if (port.limit && c >= port.limit) { JLOG(m_journal.trace()) - << session.port().name << " is full; dropping " << endpoint; + << port.name << " is full; dropping " << endpoint; return false; } From e5313540922822ee0ea3f3c006589c7d9f990477 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Mon, 8 Feb 2021 12:22:37 -0600 Subject: [PATCH 56/62] [fold] Move LedgerCleaner from LedgerMaster to ApplicationImp --- src/ripple/app/ledger/LedgerCleaner.h | 4 +-- src/ripple/app/ledger/LedgerMaster.h | 16 ------------ src/ripple/app/ledger/impl/LedgerCleaner.cpp | 4 +-- src/ripple/app/ledger/impl/LedgerMaster.cpp | 26 ------------------- src/ripple/app/main/Application.cpp | 17 +++++++++--- src/ripple/app/main/Application.h | 3 +++ .../rpc/handlers/LedgerCleanerHandler.cpp | 4 +-- 7 files changed, 21 insertions(+), 53 deletions(-) diff --git a/src/ripple/app/ledger/LedgerCleaner.h b/src/ripple/app/ledger/LedgerCleaner.h index 0aded26711c..9f82a851f21 100644 --- a/src/ripple/app/ledger/LedgerCleaner.h +++ b/src/ripple/app/ledger/LedgerCleaner.h @@ -27,7 +27,6 @@ #include namespace ripple { -namespace detail { /** Check the ledger/transaction databases to make sure they have continuity */ class LedgerCleaner : public beast::PropertyStream::Source @@ -57,13 +56,12 @@ class LedgerCleaner : public beast::PropertyStream::Source @param parameters A Json object with configurable parameters. */ virtual void - doClean(Json::Value const& parameters) = 0; + clean(Json::Value const& parameters) = 0; }; std::unique_ptr make_LedgerCleaner(Application& app, beast::Journal journal); -} // namespace detail } // namespace ripple #endif diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index c89872fd6ee..64f0c392a2e 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -84,9 +82,6 @@ class LedgerMaster : public AbstractFetchPackContainer virtual ~LedgerMaster() = default; - void - stop(); - LedgerIndex getCurrentLedgerIndex(); LedgerIndex @@ -262,15 +257,6 @@ class LedgerMaster : public AbstractFetchPackContainer bool fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash); - void - start(); - - void - doLedgerCleaner(Json::Value const& parameters); - - beast::PropertyStream::Source& - getPropertySource(); - void clearPriorLedgers(LedgerIndex seq); @@ -391,8 +377,6 @@ class LedgerMaster : public AbstractFetchPackContainer std::recursive_mutex mCompleteLock; RangeSet mCompleteLedgers; - std::unique_ptr mLedgerCleaner; - // Publish thread is running. bool mAdvanceThread{false}; diff --git a/src/ripple/app/ledger/impl/LedgerCleaner.cpp b/src/ripple/app/ledger/impl/LedgerCleaner.cpp index 08a34f2724f..65cbfe85161 100644 --- a/src/ripple/app/ledger/impl/LedgerCleaner.cpp +++ b/src/ripple/app/ledger/impl/LedgerCleaner.cpp @@ -25,7 +25,6 @@ #include namespace ripple { -namespace detail { /* @@ -133,7 +132,7 @@ class LedgerCleanerImp : public LedgerCleaner //-------------------------------------------------------------------------- void - doClean(Json::Value const& params) override + clean(Json::Value const& params) override { LedgerIndex minRange = 0; LedgerIndex maxRange = 0; @@ -458,5 +457,4 @@ make_LedgerCleaner(Application& app, beast::Journal journal) return std::make_unique(app, journal); } -} // namespace detail } // namespace ripple diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index 9a0060a5e3c..139fb674169 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -187,8 +187,6 @@ LedgerMaster::LedgerMaster( : app_(app) , m_journal(journal) , mLedgerHistory(collector, app) - , mLedgerCleaner( - detail::make_LedgerCleaner(app, app_.journal("LedgerCleaner"))) , standalone_(app_.config().standalone()) , fetch_depth_( app_.getSHAMapStore().clampFetchDepth(app_.config().FETCH_DEPTH)) @@ -204,12 +202,6 @@ LedgerMaster::LedgerMaster( { } -void -LedgerMaster::stop() -{ - mLedgerCleaner->stop(); -} - LedgerIndex LedgerMaster::getCurrentLedgerIndex() { @@ -1830,18 +1822,6 @@ LedgerMaster::getLedgerByHash(uint256 const& hash) return {}; } -void -LedgerMaster::start() -{ - mLedgerCleaner->start(); -} - -void -LedgerMaster::doLedgerCleaner(Json::Value const& parameters) -{ - mLedgerCleaner->doClean(parameters); -} - void LedgerMaster::setLedgerRangePresent(std::uint32_t minV, std::uint32_t maxV) { @@ -1868,12 +1848,6 @@ LedgerMaster::getCacheHitRate() return mLedgerHistory.getCacheHitRate(); } -beast::PropertyStream::Source& -LedgerMaster::getPropertySource() -{ - return *mLedgerCleaner; -} - void LedgerMaster::clearPriorLedgers(LedgerIndex seq) { diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index f92b9a4c354..7e0447c44c6 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -193,6 +194,7 @@ class ApplicationImp : public Application, public BasicApp OrderBookDB m_orderBookDB; std::unique_ptr m_pathRequests; std::unique_ptr m_ledgerMaster; + std::unique_ptr ledgerCleaner_; std::unique_ptr m_inboundLedgers; std::unique_ptr m_inboundTransactions; std::unique_ptr m_ledgerReplayer; @@ -341,6 +343,9 @@ class ApplicationImp : public Application, public BasicApp m_collectorManager->collector(), logs_->journal("LedgerMaster"))) + , ledgerCleaner_( + make_LedgerCleaner(*this, logs_->journal("LedgerCleaner"))) + // VFALCO NOTE must come before NetworkOPs to prevent a crash due // to dependencies in the destructor. // @@ -465,7 +470,7 @@ class ApplicationImp : public Application, public BasicApp // started in this constructor. // - add(m_ledgerMaster->getPropertySource()); + add(ledgerCleaner_.get()); } //-------------------------------------------------------------------------- @@ -569,6 +574,12 @@ class ApplicationImp : public Application, public BasicApp return *m_ledgerMaster; } + LedgerCleaner& + getLedgerCleaner() override + { + return *ledgerCleaner_; + } + LedgerReplayer& getLedgerReplayer() override { @@ -1095,7 +1106,7 @@ class ApplicationImp : public Application, public BasicApp m_ledgerReplayer->stop(); m_inboundTransactions->stop(); m_inboundLedgers->stop(); - m_ledgerMaster->stop(); + ledgerCleaner_->stop(); if (config_->reporting()) { reportingETL_->stop(); @@ -1717,7 +1728,7 @@ ApplicationImp::start(bool withTimers) if (overlay_) overlay_->start(); grpcServer_->start(); - m_ledgerMaster->start(); + ledgerCleaner_->start(); perfLog_->start(); } diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h index 6ede3953dbb..f5f7c826024 100644 --- a/src/ripple/app/main/Application.h +++ b/src/ripple/app/main/Application.h @@ -64,6 +64,7 @@ class InboundTransactions; class AcceptedLedger; class Ledger; class LedgerMaster; +class LedgerCleaner; class LedgerReplayer; class LoadManager; class ManifestCache; @@ -205,6 +206,8 @@ class Application : public beast::PropertyStream::Source virtual LedgerMaster& getLedgerMaster() = 0; + virtual LedgerCleaner& + getLedgerCleaner() = 0; virtual LedgerReplayer& getLedgerReplayer() = 0; virtual NetworkOPs& diff --git a/src/ripple/rpc/handlers/LedgerCleanerHandler.cpp b/src/ripple/rpc/handlers/LedgerCleanerHandler.cpp index 00e142c4d61..5b76f3f8b9d 100644 --- a/src/ripple/rpc/handlers/LedgerCleanerHandler.cpp +++ b/src/ripple/rpc/handlers/LedgerCleanerHandler.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include #include #include #include @@ -28,7 +28,7 @@ namespace ripple { Json::Value doLedgerCleaner(RPC::JsonContext& context) { - context.app.getLedgerMaster().doLedgerCleaner(context.params); + context.app.getLedgerCleaner().clean(context.params); return RPC::makeObjectValue("Cleaner configured"); } From 2a39b7ce44f47311bd330922765816accfd80eba Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 23 Mar 2021 12:28:33 -0500 Subject: [PATCH 57/62] [fold] Add missing include --- src/ripple/nodestore/Database.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ripple/nodestore/Database.h b/src/ripple/nodestore/Database.h index a6f86b39395..861378551ef 100644 --- a/src/ripple/nodestore/Database.h +++ b/src/ripple/nodestore/Database.h @@ -27,6 +27,7 @@ #include #include +#include #include namespace ripple { From d3c1c1ff79eb8821ec77f7c0821a25955d767be3 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Tue, 23 Mar 2021 12:28:40 -0500 Subject: [PATCH 58/62] Fix compilation of krb5 dependency with GCC 10 See: https://github.com/cockroachdb/cockroach/issues/49734#issuecomment-758389602 --- Builds/CMake/deps/cassandra.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Builds/CMake/deps/cassandra.cmake b/Builds/CMake/deps/cassandra.cmake index 46142c8f09f..ca19bd528ff 100644 --- a/Builds/CMake/deps/cassandra.cmake +++ b/Builds/CMake/deps/cassandra.cmake @@ -47,7 +47,7 @@ if(reporting) GIT_REPOSITORY https://github.com/krb5/krb5.git GIT_TAG master UPDATE_COMMAND "" - CONFIGURE_COMMAND autoreconf src && ./src/configure --enable-static --disable-shared > /dev/null + CONFIGURE_COMMAND autoreconf src && CFLAGS=-fcommon ./src/configure --enable-static --disable-shared > /dev/null BUILD_IN_SOURCE 1 BUILD_COMMAND make INSTALL_COMMAND "" From f1beb4f949db1a5f72efa27f035e5baca3452d86 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 2 Apr 2021 11:24:08 -0500 Subject: [PATCH 59/62] [fold] Put PgPool behind conditional compilation --- src/ripple/app/rdb/backend/RelationalDBInterfacePostgres.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ripple/app/rdb/backend/RelationalDBInterfacePostgres.cpp b/src/ripple/app/rdb/backend/RelationalDBInterfacePostgres.cpp index 5cb6dcc533c..91e85d043d1 100644 --- a/src/ripple/app/rdb/backend/RelationalDBInterfacePostgres.cpp +++ b/src/ripple/app/rdb/backend/RelationalDBInterfacePostgres.cpp @@ -67,7 +67,9 @@ class RelationalDBInterfacePostgresImp : public RelationalDBInterfacePostgres void stop() override { +#ifdef RIPPLED_REPORTING pgPool_->stop(); +#endif } void From 145f5a177ff4bf5f08070ec53f55dedb6b056603 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 2 Apr 2021 11:27:27 -0500 Subject: [PATCH 60/62] [fold] More conditional compilation --- src/ripple/app/main/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index af43c581bd6..4a2c15f982c 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1020,9 +1020,11 @@ class ApplicationImp : public Application, public BasicApp if (config_->reporting()) { reportingETL_->stop(); +#ifdef RIPPLED_REPORTING dynamic_cast( &*mRelationalDBInterface) ->stop(); +#endif } m_nodeStore->stop(); perfLog_->stop(); From 220f44013e734fcd943785ae40536e1e4c7ac2bd Mon Sep 17 00:00:00 2001 From: John Freeman Date: Fri, 30 Apr 2021 11:30:12 -0500 Subject: [PATCH 61/62] [fold] Requested changes --- src/ripple/app/main/Application.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 4a2c15f982c..f0495087db2 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1020,11 +1020,9 @@ class ApplicationImp : public Application, public BasicApp if (config_->reporting()) { reportingETL_->stop(); -#ifdef RIPPLED_REPORTING dynamic_cast( &*mRelationalDBInterface) ->stop(); -#endif } m_nodeStore->stop(); perfLog_->stop(); @@ -1565,7 +1563,6 @@ ApplicationImp::start(bool withTimers) JLOG(m_journal.info()) << "Application starting. Version is " << BuildInfo::getVersionString(); - using namespace std::chrono_literals; if (withTimers) { setSweepTimer(); From 7b459ca1cb7f0e0e05bf4723a0500cab0063db53 Mon Sep 17 00:00:00 2001 From: John Freeman Date: Thu, 13 May 2021 15:23:48 -0500 Subject: [PATCH 62/62] [fold] Requested changes --- src/ripple/app/main/Application.cpp | 25 +++++++++++-------------- src/test/basics/PerfLog_test.cpp | 4 ++-- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index f0495087db2..3f80c2ae01e 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -443,7 +443,9 @@ class ApplicationImp : public Application, public BasicApp std::chrono::milliseconds(100), get_io_service()) , grpcServer_(std::make_unique(*this)) - , reportingETL_(std::make_unique(*this)) + , reportingETL_( + config_->reporting() ? std::make_unique(*this) + : nullptr) { add(m_resourceManager.get()); @@ -1017,13 +1019,11 @@ class ApplicationImp : public Application, public BasicApp m_inboundTransactions->stop(); m_inboundLedgers->stop(); ledgerCleaner_->stop(); - if (config_->reporting()) - { + if (reportingETL_) reportingETL_->stop(); - dynamic_cast( - &*mRelationalDBInterface) - ->stop(); - } + if (auto pg = dynamic_cast( + &*mRelationalDBInterface)) + pg->stop(); m_nodeStore->stop(); perfLog_->stop(); } @@ -1128,10 +1128,9 @@ class ApplicationImp : public Application, public BasicApp cachedSLEs_.expire(); #ifdef RIPPLED_REPORTING - if (config().reporting()) - dynamic_cast( - &*mRelationalDBInterface) - ->sweep(); + if (auto pg = dynamic_cast( + &*mRelationalDBInterface)) + pg->sweep(); #endif // Set timer to do another sweep later. @@ -1549,10 +1548,8 @@ ApplicationImp::setup() validatorSites_->start(); - if (config_->reporting()) - { + if (reportingETL_) reportingETL_->start(); - } return true; } diff --git a/src/test/basics/PerfLog_test.cpp b/src/test/basics/PerfLog_test.cpp index 13f3cb9f54d..db0cf885101 100644 --- a/src/test/basics/PerfLog_test.cpp +++ b/src/test/basics/PerfLog_test.cpp @@ -193,12 +193,12 @@ class PerfLog_test : public beast::unit_test::suite { // Verify a PerfLog creates its file when constructed. Fixture fixture{j_}; - BEAST_EXPECT(!exists(fixture.logDir())); + BEAST_EXPECT(!exists(fixture.logFile())); auto perfLog{fixture.perfLog(WithFile::yes)}; BEAST_EXPECT(fixture.stopSignaled == false); - BEAST_EXPECT(exists(fixture.logDir())); + BEAST_EXPECT(exists(fixture.logFile())); } { // Create a file where PerfLog wants to put its directory.