diff --git a/src/ripple/app/ledger/InboundLedgers.h b/src/ripple/app/ledger/InboundLedgers.h index 31d95d4d8..d2116a6f4 100644 --- a/src/ripple/app/ledger/InboundLedgers.h +++ b/src/ripple/app/ledger/InboundLedgers.h @@ -63,7 +63,7 @@ public: virtual int getFetchCount (int& timeoutCount) = 0; - virtual void logFailure (uint256 const& h) = 0; + virtual void logFailure (uint256 const& h, std::uint32_t seq) = 0; virtual bool isFailure (uint256 const& h) = 0; diff --git a/src/ripple/app/ledger/impl/InboundLedger.cpp b/src/ripple/app/ledger/impl/InboundLedger.cpp index 682f31fdf..39585bf5b 100644 --- a/src/ripple/app/ledger/impl/InboundLedger.cpp +++ b/src/ripple/app/ledger/impl/InboundLedger.cpp @@ -330,6 +330,9 @@ static void LADispatch ( getApp().getLedgerMaster().checkAccept(la->getLedger()); getApp().getLedgerMaster().tryAdvance(); } + else + getApp().getInboundLedgers().logFailure (la->getHash(), la->getSeq()); + for (unsigned int i = 0; i < trig.size (); ++i) trig[i] (la); } @@ -361,8 +364,6 @@ void InboundLedger::done () getApp().getLedgerMaster ().storeLedger (mLedger); getApp().getInboundLedgers().onLedgerFetched(mReason); } - else - getApp().getInboundLedgers ().logFailure (mHash); // We hold the PeerSet lock, so must dispatch getApp().getJobQueue ().addJob (jtLEDGER_DATA, "triggers", diff --git a/src/ripple/app/ledger/impl/InboundLedgers.cpp b/src/ripple/app/ledger/impl/InboundLedgers.cpp index c676dd62f..87a536fb5 100644 --- a/src/ripple/app/ledger/impl/InboundLedgers.cpp +++ b/src/ripple/app/ledger/impl/InboundLedgers.cpp @@ -24,8 +24,10 @@ #include #include #include +#include #include // #include +#include namespace ripple { @@ -41,15 +43,14 @@ private: public: using u256_acq_pair = std::pair; // How long before we try again to acquire the same ledger - static const int kReacquireIntervalSeconds = 300; + static const std::chrono::minutes kReacquireInterval; InboundLedgersImp (clock_type& clock, Stoppable& parent, beast::insight::Collector::ptr const& collector) : Stoppable ("InboundLedgers", parent) , fetchRate_(clock.now()) , m_clock (clock) - , mRecentFailures ("LedgerAcquireRecentFailures", - clock, 0, kReacquireIntervalSeconds) + , mRecentFailures (clock) , mCounter(collector->make_counter("ledger_fetches")) { } @@ -200,14 +201,19 @@ public: return ret; } - void logFailure (uint256 const& h) + void logFailure (uint256 const& h, std::uint32_t seq) { - mRecentFailures.insert (h); + ScopedLockType sl (mLock); + + mRecentFailures.emplace(h, seq); } bool isFailure (uint256 const& h) { - return mRecentFailures.exists (h); + ScopedLockType sl (mLock); + + beast::expire (mRecentFailures, kReacquireInterval); + return mRecentFailures.find (h) != mRecentFailures.end(); } void doLedgerData (Job&, LedgerHash hash) @@ -292,10 +298,19 @@ public: assert (it.second); acquires.push_back (it); } + for (auto const& it : mRecentFailures) + { + if (it.second > 1) + ret[beast::lexicalCastThrow ( + it.second)][jss::failed] = true; + else + ret[to_string (it.first)][jss::failed] = true; + } } for (auto const& it : acquires) { + // getJson is expensive, so call without the lock std::uint32_t seq = it.second->getSeq(); if (seq > 1) ret[beast::lexicalCastThrow (seq)] = it.second->getJson(0); @@ -328,8 +343,6 @@ public: void sweep () { - mRecentFailures.sweep (); - clock_type::time_point const now (m_clock.now()); // Make a list of things to sweep, while holding the lock @@ -360,6 +373,9 @@ public: ++it; } } + + beast::expire (mRecentFailures, kReacquireInterval); + } WriteLog (lsDEBUG, InboundLedger) << @@ -387,13 +403,15 @@ private: LockType mLock; MapType mLedgers; - KeyCache mRecentFailures; + beast::aged_map mRecentFailures; beast::insight::Counter mCounter; }; //------------------------------------------------------------------------------ +decltype(InboundLedgersImp::kReacquireInterval) InboundLedgersImp::kReacquireInterval{5}; + InboundLedgers::~InboundLedgers() { }