Fix some cases where the acquire engine can stall.

This commit is contained in:
JoelKatz
2012-12-25 21:05:12 -08:00
parent f685e9e9ee
commit be2e55d49c
4 changed files with 64 additions and 7 deletions

View File

@@ -1176,8 +1176,13 @@ void Ledger::pendSave(bool fromConsensus)
void Ledger::decPendingSaves()
{
boost::recursive_mutex::scoped_lock sl(sPendingSaveLock);
--sPendingSaves;
{
boost::recursive_mutex::scoped_lock sl(sPendingSaveLock);
--sPendingSaves;
if (sPendingSaves != 0)
return;
}
theApp->getLedgerMaster().resumeAcquiring();
}
void Ledger::ownerDirDescriber(SLE::ref sle, const uint160& owner)

View File

@@ -124,7 +124,10 @@ void LedgerAcquire::onTimer(bool progress)
else if (!progress)
{
if (!getPeerCount())
{
addPeers();
resetTimer();
}
else
trigger(Peer::pointer(), true);
}

View File

@@ -171,8 +171,46 @@ static bool shouldAcquire(uint32 currentLedger, uint32 ledgerHistory, uint32 can
return ret;
}
void LedgerMaster::resumeAcquiring()
{
boost::recursive_mutex::scoped_lock ml(mLock);
if (!mTooFast)
return;
mTooFast = false;
if (mMissingLedger && (mMissingLedger->isComplete() || mMissingLedger->isFailed()))
mMissingLedger.reset();
if (mMissingLedger || !theConfig.LEDGER_HISTORY)
{
tLog(mMissingLedger, lsDEBUG) << "Fetch already in progress, not resuming";
return;
}
uint32 prevMissing = mCompleteLedgers.prevMissing(mFinalizedLedger->getLedgerSeq());
if (prevMissing == RangeSet::RangeSetAbsent)
{
cLog(lsDEBUG) << "no prior missing ledger, not resuming";
return;
}
if (shouldAcquire(mCurrentLedger->getLedgerSeq(), theConfig.LEDGER_HISTORY, prevMissing))
{
cLog(lsINFO) << "Resuming at " << prevMissing;
assert(!mCompleteLedgers.hasValue(prevMissing));
Ledger::pointer nextLedger = getLedgerBySeq(prevMissing + 1);
if (nextLedger)
acquireMissingLedger(nextLedger->getParentHash(), nextLedger->getLedgerSeq() - 1);
else
{
mCompleteLedgers.clearValue(prevMissing);
cLog(lsWARNING) << "We have a gap at: " << prevMissing + 1;
}
}
}
void LedgerMaster::setFullLedger(Ledger::ref ledger)
{ // A new ledger has been accepted as part of the trusted chain
cLog(lsDEBUG) << "Ledger " << ledger->getLedgerSeq() << " accepted :" << ledger->getHash();
boost::recursive_mutex::scoped_lock ml(mLock);
@@ -197,10 +235,14 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger)
mMissingLedger.reset();
if (mMissingLedger || !theConfig.LEDGER_HISTORY)
return;
if (Ledger::getPendingSaves() > 3)
{
tLog(mMissingLedger, lsDEBUG) << "Fetch already in progress, " << mMissingLedger->getTimeouts() << " timeouts";
return;
}
if (Ledger::getPendingSaves() > 2)
{
mTooFast = true;
cLog(lsINFO) << "Too many pending ledger saves";
return;
}
@@ -217,10 +259,14 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger)
{
uint32 prevMissing = mCompleteLedgers.prevMissing(ledger->getLedgerSeq());
if (prevMissing == RangeSet::RangeSetAbsent)
{
cLog(lsDEBUG) << "no prior missing ledger";
return;
}
cLog(lsTRACE) << "Ledger " << prevMissing << " is missing";
if (shouldAcquire(mCurrentLedger->getLedgerSeq(), theConfig.LEDGER_HISTORY, prevMissing))
{
cLog(lsINFO) << "Ledger " << prevMissing << " is missing";
cLog(lsINFO) << "Ledger " << prevMissing << " is needed";
assert(!mCompleteLedgers.hasValue(prevMissing));
Ledger::pointer nextLedger = getLedgerBySeq(prevMissing + 1);
if (nextLedger)

View File

@@ -31,6 +31,7 @@ class LedgerMaster
RangeSet mCompleteLedgers;
LedgerAcquire::pointer mMissingLedger;
uint32 mMissingSeq;
bool mTooFast; // We are acquiring faster than we're writing
void applyFutureTransactions(uint32 ledgerIndex);
bool isValidTransaction(const Transaction::pointer& trans);
@@ -41,7 +42,7 @@ class LedgerMaster
public:
LedgerMaster() : mHeldTransactions(uint256()), mMissingSeq(0) { ; }
LedgerMaster() : mHeldTransactions(uint256()), mMissingSeq(0), mTooFast(false) { ; }
uint32 getCurrentLedgerIndex();
@@ -95,6 +96,8 @@ public:
bool haveLedgerRange(uint32 from, uint32 to);
void resumeAcquiring();
void sweep(void) { mLedgerHistory.sweep(); }
};