Rework of InboundLedgers::mRecentFailures:

This provides more precise tracking of failed ledger acquires
and more useful information in fetch_info.
This commit is contained in:
JoelKatz
2015-06-19 11:24:40 -07:00
committed by Vinnie Falco
parent b27d078c67
commit 924a8cdd4b
3 changed files with 31 additions and 12 deletions

View File

@@ -63,7 +63,7 @@ public:
virtual int getFetchCount (int& timeoutCount) = 0; 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; virtual bool isFailure (uint256 const& h) = 0;

View File

@@ -330,6 +330,9 @@ static void LADispatch (
getApp().getLedgerMaster().checkAccept(la->getLedger()); getApp().getLedgerMaster().checkAccept(la->getLedger());
getApp().getLedgerMaster().tryAdvance(); getApp().getLedgerMaster().tryAdvance();
} }
else
getApp().getInboundLedgers().logFailure (la->getHash(), la->getSeq());
for (unsigned int i = 0; i < trig.size (); ++i) for (unsigned int i = 0; i < trig.size (); ++i)
trig[i] (la); trig[i] (la);
} }
@@ -361,8 +364,6 @@ void InboundLedger::done ()
getApp().getLedgerMaster ().storeLedger (mLedger); getApp().getLedgerMaster ().storeLedger (mLedger);
getApp().getInboundLedgers().onLedgerFetched(mReason); getApp().getInboundLedgers().onLedgerFetched(mReason);
} }
else
getApp().getInboundLedgers ().logFailure (mHash);
// We hold the PeerSet lock, so must dispatch // We hold the PeerSet lock, so must dispatch
getApp().getJobQueue ().addJob (jtLEDGER_DATA, "triggers", getApp().getJobQueue ().addJob (jtLEDGER_DATA, "triggers",

View File

@@ -24,8 +24,10 @@
#include <ripple/basics/DecayingSample.h> #include <ripple/basics/DecayingSample.h>
#include <ripple/basics/Log.h> #include <ripple/basics/Log.h>
#include <ripple/core/JobQueue.h> #include <ripple/core/JobQueue.h>
#include <ripple/protocol/JsonFields.h>
#include <beast/cxx14/memory.h> // <memory> #include <beast/cxx14/memory.h> // <memory>
#include <beast/module/core/text/LexicalCast.h> #include <beast/module/core/text/LexicalCast.h>
#include <beast/container/aged_map.h>
namespace ripple { namespace ripple {
@@ -41,15 +43,14 @@ private:
public: public:
using u256_acq_pair = std::pair<uint256, InboundLedger::pointer>; using u256_acq_pair = std::pair<uint256, InboundLedger::pointer>;
// How long before we try again to acquire the same ledger // 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, InboundLedgersImp (clock_type& clock, Stoppable& parent,
beast::insight::Collector::ptr const& collector) beast::insight::Collector::ptr const& collector)
: Stoppable ("InboundLedgers", parent) : Stoppable ("InboundLedgers", parent)
, fetchRate_(clock.now()) , fetchRate_(clock.now())
, m_clock (clock) , m_clock (clock)
, mRecentFailures ("LedgerAcquireRecentFailures", , mRecentFailures (clock)
clock, 0, kReacquireIntervalSeconds)
, mCounter(collector->make_counter("ledger_fetches")) , mCounter(collector->make_counter("ledger_fetches"))
{ {
} }
@@ -200,14 +201,19 @@ public:
return ret; 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) 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) void doLedgerData (Job&, LedgerHash hash)
@@ -292,10 +298,19 @@ public:
assert (it.second); assert (it.second);
acquires.push_back (it); acquires.push_back (it);
} }
for (auto const& it : mRecentFailures)
{
if (it.second > 1)
ret[beast::lexicalCastThrow <std::string>(
it.second)][jss::failed] = true;
else
ret[to_string (it.first)][jss::failed] = true;
}
} }
for (auto const& it : acquires) for (auto const& it : acquires)
{ {
// getJson is expensive, so call without the lock
std::uint32_t seq = it.second->getSeq(); std::uint32_t seq = it.second->getSeq();
if (seq > 1) if (seq > 1)
ret[beast::lexicalCastThrow <std::string>(seq)] = it.second->getJson(0); ret[beast::lexicalCastThrow <std::string>(seq)] = it.second->getJson(0);
@@ -328,8 +343,6 @@ public:
void sweep () void sweep ()
{ {
mRecentFailures.sweep ();
clock_type::time_point const now (m_clock.now()); clock_type::time_point const now (m_clock.now());
// Make a list of things to sweep, while holding the lock // Make a list of things to sweep, while holding the lock
@@ -360,6 +373,9 @@ public:
++it; ++it;
} }
} }
beast::expire (mRecentFailures, kReacquireInterval);
} }
WriteLog (lsDEBUG, InboundLedger) << WriteLog (lsDEBUG, InboundLedger) <<
@@ -387,13 +403,15 @@ private:
LockType mLock; LockType mLock;
MapType mLedgers; MapType mLedgers;
KeyCache <uint256> mRecentFailures; beast::aged_map <uint256, std::uint32_t> mRecentFailures;
beast::insight::Counter mCounter; beast::insight::Counter mCounter;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
decltype(InboundLedgersImp::kReacquireInterval) InboundLedgersImp::kReacquireInterval{5};
InboundLedgers::~InboundLedgers() InboundLedgers::~InboundLedgers()
{ {
} }