mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-01 00:15:51 +00:00
Move PathRequests to separate files
This commit is contained in:
@@ -1096,6 +1096,12 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\ripple_app\paths\PathRequests.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple_app\paths\PathState.cpp">
|
<ClCompile Include="..\..\src\ripple_app\paths\PathState.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
@@ -2464,6 +2470,7 @@
|
|||||||
<ClInclude Include="..\..\src\ripple_app\node\SqliteFactory.h" />
|
<ClInclude Include="..\..\src\ripple_app\node\SqliteFactory.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\paths\Pathfinder.h" />
|
<ClInclude Include="..\..\src\ripple_app\paths\Pathfinder.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\paths\PathRequest.h" />
|
<ClInclude Include="..\..\src\ripple_app\paths\PathRequest.h" />
|
||||||
|
<ClInclude Include="..\..\src\ripple_app\paths\PathRequests.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\paths\PathState.h" />
|
<ClInclude Include="..\..\src\ripple_app\paths\PathState.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\paths\RippleCalc.h" />
|
<ClInclude Include="..\..\src\ripple_app\paths\RippleCalc.h" />
|
||||||
<ClInclude Include="..\..\src\ripple_app\paths\RippleLineCache.h" />
|
<ClInclude Include="..\..\src\ripple_app\paths\RippleLineCache.h" />
|
||||||
|
|||||||
@@ -1443,6 +1443,9 @@
|
|||||||
<ClCompile Include="..\..\src\ripple\rpc\impl\ErrorCodes.cpp">
|
<ClCompile Include="..\..\src\ripple\rpc\impl\ErrorCodes.cpp">
|
||||||
<Filter>[1] Ripple\rpc\impl</Filter>
|
<Filter>[1] Ripple\rpc\impl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\ripple_app\paths\PathRequests.cpp">
|
||||||
|
<Filter>[2] Old Ripple\ripple_app\paths</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
|
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
|
||||||
@@ -2928,6 +2931,9 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\rpc\api\ErrorCodes.h">
|
<ClInclude Include="..\..\src\ripple\rpc\api\ErrorCodes.h">
|
||||||
<Filter>[1] Ripple\rpc\api</Filter>
|
<Filter>[1] Ripple\rpc\api</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple_app\paths\PathRequests.h">
|
||||||
|
<Filter>[2] Old Ripple\ripple_app\paths</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">
|
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">
|
||||||
|
|||||||
@@ -19,8 +19,11 @@
|
|||||||
|
|
||||||
SETUP_LOG (PathRequest)
|
SETUP_LOG (PathRequest)
|
||||||
|
|
||||||
PathRequest::PathRequest (const boost::shared_ptr<InfoSub>& subscriber, int id, PathRequests& owner)
|
PathRequest::PathRequest (
|
||||||
: mLock (this, "PathRequest", __FILE__, __LINE__)
|
const boost::shared_ptr<InfoSub>& subscriber, int id, PathRequests& owner,
|
||||||
|
Journal journal)
|
||||||
|
: m_journal (journal)
|
||||||
|
, mLock (this, "PathRequest", __FILE__, __LINE__)
|
||||||
, mOwner (owner)
|
, mOwner (owner)
|
||||||
, wpSubscriber (subscriber)
|
, wpSubscriber (subscriber)
|
||||||
, jvStatus (Json::objectValue)
|
, jvStatus (Json::objectValue)
|
||||||
@@ -30,16 +33,11 @@ PathRequest::PathRequest (const boost::shared_ptr<InfoSub>& subscriber, int id,
|
|||||||
, bLastSuccess (false)
|
, bLastSuccess (false)
|
||||||
, iIdentifier (id)
|
, iIdentifier (id)
|
||||||
{
|
{
|
||||||
if (journal().debug)
|
if (m_journal.debug)
|
||||||
journal().debug << iIdentifier << " created";
|
m_journal.debug << iIdentifier << " created";
|
||||||
ptCreated = boost::posix_time::microsec_clock::universal_time ();
|
ptCreated = boost::posix_time::microsec_clock::universal_time ();
|
||||||
}
|
}
|
||||||
|
|
||||||
Journal& PathRequest::journal ()
|
|
||||||
{
|
|
||||||
return mOwner.journal ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string const get_milli_diff (boost::posix_time::ptime const& after, boost::posix_time::ptime const& before)
|
static std::string const get_milli_diff (boost::posix_time::ptime const& after, boost::posix_time::ptime const& before)
|
||||||
{
|
{
|
||||||
return lexicalCastThrow <std::string> (static_cast <unsigned> ((after - before).total_milliseconds()));
|
return lexicalCastThrow <std::string> (static_cast <unsigned> ((after - before).total_milliseconds()));
|
||||||
@@ -65,8 +63,8 @@ PathRequest::~PathRequest()
|
|||||||
full += get_milli_diff (ptFullReply, ptCreated);
|
full += get_milli_diff (ptFullReply, ptCreated);
|
||||||
full += "ms";
|
full += "ms";
|
||||||
}
|
}
|
||||||
if (journal().info)
|
if (m_journal.info)
|
||||||
journal().info << iIdentifier << " complete:" << fast << full <<
|
m_journal.info << iIdentifier << " complete:" << fast << full <<
|
||||||
" total:" << get_milli_diff(ptCreated) << "ms";
|
" total:" << get_milli_diff(ptCreated) << "ms";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,15 +169,15 @@ Json::Value PathRequest::doCreate (Ledger::ref lrLedger, RippleLineCache::ref& c
|
|||||||
status = jvStatus;
|
status = jvStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (journal().debug)
|
if (m_journal.debug)
|
||||||
{
|
{
|
||||||
if (bValid)
|
if (bValid)
|
||||||
{
|
{
|
||||||
journal().debug << iIdentifier << " valid: " << raSrcAccount.humanAccountID () <<
|
m_journal.debug << iIdentifier << " valid: " << raSrcAccount.humanAccountID () <<
|
||||||
journal().debug << iIdentifier << " Deliver: " << saDstAmount.getFullText ();
|
m_journal.debug << iIdentifier << " Deliver: " << saDstAmount.getFullText ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
journal().debug << iIdentifier << " invalid";
|
m_journal.debug << iIdentifier << " invalid";
|
||||||
}
|
}
|
||||||
|
|
||||||
valid = bValid;
|
valid = bValid;
|
||||||
@@ -280,7 +278,7 @@ int PathRequest::parseJson (const Json::Value& jvParams, bool complete)
|
|||||||
}
|
}
|
||||||
Json::Value PathRequest::doClose (const Json::Value&)
|
Json::Value PathRequest::doClose (const Json::Value&)
|
||||||
{
|
{
|
||||||
journal().debug << iIdentifier << " closed";
|
m_journal.debug << iIdentifier << " closed";
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
return jvStatus;
|
return jvStatus;
|
||||||
}
|
}
|
||||||
@@ -299,7 +297,7 @@ void PathRequest::resetLevel (int l)
|
|||||||
|
|
||||||
Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||||
{
|
{
|
||||||
journal().debug << iIdentifier << " update " << (fast ? "fast" : "normal");
|
m_journal.debug << iIdentifier << " update " << (fast ? "fast" : "normal");
|
||||||
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
|
||||||
@@ -364,7 +362,7 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
--iLevel;
|
--iLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
journal().debug << iIdentifier << " processing at level " << iLevel;
|
m_journal.debug << iIdentifier << " processing at level " << iLevel;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
@@ -372,8 +370,8 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
STAmount test (currIssuer.first, currIssuer.second, 1);
|
STAmount test (currIssuer.first, currIssuer.second, 1);
|
||||||
if (journal().debug)
|
if (m_journal.debug)
|
||||||
journal().debug << iIdentifier << " Trying to find paths: " << test.getFullText ();
|
m_journal.debug << iIdentifier << " Trying to find paths: " << test.getFullText ();
|
||||||
}
|
}
|
||||||
bool valid;
|
bool valid;
|
||||||
STPathSet& spsPaths = mContext[currIssuer];
|
STPathSet& spsPaths = mContext[currIssuer];
|
||||||
@@ -392,7 +390,7 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
currIssuer.second.isNonZero () ? currIssuer.second :
|
currIssuer.second.isNonZero () ? currIssuer.second :
|
||||||
(currIssuer.first.isZero () ? ACCOUNT_XRP : raSrcAccount.getAccountID ()), 1);
|
(currIssuer.first.isZero () ? ACCOUNT_XRP : raSrcAccount.getAccountID ()), 1);
|
||||||
saMaxAmount.negate ();
|
saMaxAmount.negate ();
|
||||||
journal().debug << iIdentifier << " Paths found, calling rippleCalc";
|
m_journal.debug << iIdentifier << " Paths found, calling rippleCalc";
|
||||||
TER terResult = RippleCalc::rippleCalc (lesSandbox, saMaxAmountAct, saDstAmountAct,
|
TER terResult = RippleCalc::rippleCalc (lesSandbox, saMaxAmountAct, saDstAmountAct,
|
||||||
vpsExpanded, saMaxAmount, saDstAmount,
|
vpsExpanded, saMaxAmount, saDstAmount,
|
||||||
raDstAccount.getAccountID (), raSrcAccount.getAccountID (),
|
raDstAccount.getAccountID (), raSrcAccount.getAccountID (),
|
||||||
@@ -401,14 +399,14 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
|
|
||||||
if ((extraPath.size() > 0) && ((terResult == terNO_LINE) || (terResult == tecPATH_PARTIAL)))
|
if ((extraPath.size() > 0) && ((terResult == terNO_LINE) || (terResult == tecPATH_PARTIAL)))
|
||||||
{
|
{
|
||||||
journal().debug << iIdentifier << " Trying with an extra path element";
|
m_journal.debug << iIdentifier << " Trying with an extra path element";
|
||||||
spsPaths.addPath(extraPath);
|
spsPaths.addPath(extraPath);
|
||||||
vpsExpanded.clear ();
|
vpsExpanded.clear ();
|
||||||
terResult = RippleCalc::rippleCalc (lesSandbox, saMaxAmountAct, saDstAmountAct,
|
terResult = RippleCalc::rippleCalc (lesSandbox, saMaxAmountAct, saDstAmountAct,
|
||||||
vpsExpanded, saMaxAmount, saDstAmount,
|
vpsExpanded, saMaxAmount, saDstAmount,
|
||||||
raDstAccount.getAccountID (), raSrcAccount.getAccountID (),
|
raDstAccount.getAccountID (), raSrcAccount.getAccountID (),
|
||||||
spsPaths, false, false, false, true);
|
spsPaths, false, false, false, true);
|
||||||
journal().debug << iIdentifier << " Extra path element gives " << transHuman (terResult);
|
m_journal.debug << iIdentifier << " Extra path element gives " << transHuman (terResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (terResult == tesSUCCESS)
|
if (terResult == tesSUCCESS)
|
||||||
@@ -421,12 +419,12 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
journal().debug << iIdentifier << " rippleCalc returns " << transHuman (terResult);
|
m_journal.debug << iIdentifier << " rippleCalc returns " << transHuman (terResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
journal().debug << iIdentifier << " No paths found";
|
m_journal.debug << iIdentifier << " No paths found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,177 +451,3 @@ InfoSub::pointer PathRequest::getSubscriber ()
|
|||||||
return wpSubscriber.lock ();
|
return wpSubscriber.lock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the current RippleLineCache, updating it if necessary.
|
|
||||||
Get the correct ledger to use.
|
|
||||||
*/
|
|
||||||
RippleLineCache::pointer PathRequests::getLineCache (Ledger::pointer& ledger, bool authoritative)
|
|
||||||
{
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
|
||||||
|
|
||||||
uint32 lineSeq = mLineCache ? mLineCache->getLedger()->getLedgerSeq() : 0;
|
|
||||||
uint32 lgrSeq = ledger->getLedgerSeq();
|
|
||||||
|
|
||||||
if ( (lineSeq == 0) || // no ledger
|
|
||||||
(authoritative && (lgrSeq > lineSeq)) || // newer authoritative ledger
|
|
||||||
(authoritative && ((lgrSeq + 8) < lineSeq)) || // we jumped way back for some reason
|
|
||||||
(lgrSeq > (lineSeq + 8))) // we jumped way forward for some reason
|
|
||||||
{
|
|
||||||
ledger = boost::make_shared<Ledger>(*ledger, false); // Take a snapshot of the ledger
|
|
||||||
mLineCache = boost::make_shared<RippleLineCache> (ledger);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ledger = mLineCache->getLedger();
|
|
||||||
}
|
|
||||||
return mLineCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PathRequests::updateAll (Ledger::ref inLedger, CancelCallback shouldCancel)
|
|
||||||
{
|
|
||||||
std::vector<PathRequest::wptr> requests;
|
|
||||||
|
|
||||||
LoadEvent::autoptr event (getApp().getJobQueue().getLoadEventAP(jtPATH_FIND, "PathRequest::updateAll"));
|
|
||||||
|
|
||||||
// Get the ledger and cache we should be using
|
|
||||||
Ledger::pointer ledger = inLedger;
|
|
||||||
RippleLineCache::pointer cache;
|
|
||||||
{
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
|
||||||
requests = mRequests;
|
|
||||||
cache = getLineCache (ledger, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool newRequests = getApp().getLedgerMaster().isNewPathRequest();
|
|
||||||
bool mustBreak = false;
|
|
||||||
|
|
||||||
journal().trace << "updateAll seq=" << ledger->getLedgerSeq() << ", " <<
|
|
||||||
requests.size() << " requests";
|
|
||||||
int processed = 0, removed = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
|
|
||||||
{ // Get the latest requests, cache, and ledger
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
|
||||||
|
|
||||||
if (mRequests.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Newest request is last in mRequests, but we want to serve it first
|
|
||||||
requests.empty();
|
|
||||||
requests.reserve (mRequests.size ());
|
|
||||||
BOOST_REVERSE_FOREACH (PathRequest::wptr& req, mRequests)
|
|
||||||
{
|
|
||||||
requests.push_back (req);
|
|
||||||
}
|
|
||||||
|
|
||||||
cache = getLineCache (ledger, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH (PathRequest::wref wRequest, requests)
|
|
||||||
{
|
|
||||||
if (shouldCancel())
|
|
||||||
break;
|
|
||||||
|
|
||||||
bool remove = true;
|
|
||||||
PathRequest::pointer pRequest = wRequest.lock ();
|
|
||||||
|
|
||||||
if (pRequest)
|
|
||||||
{
|
|
||||||
if (!pRequest->needsUpdate (newRequests, ledger->getLedgerSeq ()))
|
|
||||||
remove = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InfoSub::pointer ipSub = pRequest->getSubscriber ();
|
|
||||||
if (ipSub)
|
|
||||||
{
|
|
||||||
Json::Value update = pRequest->doUpdate (cache, false);
|
|
||||||
update["type"] = "path_find";
|
|
||||||
ipSub->send (update, false);
|
|
||||||
remove = false;
|
|
||||||
++processed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remove)
|
|
||||||
{
|
|
||||||
PathRequest::pointer pRequest = wRequest.lock ();
|
|
||||||
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
|
||||||
|
|
||||||
// Remove any dangling weak pointers or weak pointers that refer to this path request.
|
|
||||||
std::vector<PathRequest::wptr>::iterator it = mRequests.begin();
|
|
||||||
while (it != mRequests.end())
|
|
||||||
{
|
|
||||||
PathRequest::pointer itRequest = it->lock ();
|
|
||||||
if (!itRequest || (itRequest == pRequest))
|
|
||||||
{
|
|
||||||
++removed;
|
|
||||||
it = mRequests.erase (it);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mustBreak = !newRequests && getApp().getLedgerMaster().isNewPathRequest();
|
|
||||||
if (mustBreak) // We weren't handling new requests and then there was a new request
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mustBreak)
|
|
||||||
{ // a new request came in while we were working
|
|
||||||
newRequests = true;
|
|
||||||
}
|
|
||||||
else if (newRequests)
|
|
||||||
{ // we only did new requests, so we always need a last pass
|
|
||||||
newRequests = getApp().getLedgerMaster().isNewPathRequest();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // check if there are any new requests, otherwise we are done
|
|
||||||
newRequests = getApp().getLedgerMaster().isNewPathRequest();
|
|
||||||
if (!newRequests) // We did a full pass and there are no new requests
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
while (!shouldCancel ());
|
|
||||||
|
|
||||||
journal().debug << "updateAll complete " << processed << " process and " <<
|
|
||||||
removed << " removed";
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value PathRequests::makePathRequest(
|
|
||||||
boost::shared_ptr <InfoSub> const& subscriber,
|
|
||||||
const boost::shared_ptr<Ledger>& inLedger,
|
|
||||||
const Json::Value& requestJson)
|
|
||||||
{
|
|
||||||
PathRequest::pointer req = boost::make_shared<PathRequest> (subscriber, ++mLastIdentifier, *this);
|
|
||||||
|
|
||||||
Ledger::pointer ledger = inLedger;
|
|
||||||
RippleLineCache::pointer cache;
|
|
||||||
|
|
||||||
{
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
|
||||||
cache = getLineCache (ledger, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool valid = false;
|
|
||||||
Json::Value result = req->doCreate (ledger, cache, requestJson, valid);
|
|
||||||
|
|
||||||
if (valid)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
|
||||||
mRequests.push_back (req);
|
|
||||||
}
|
|
||||||
subscriber->setPathRequest (req);
|
|
||||||
getApp().getLedgerMaster().newPathRequest();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// vim:ts=4
|
|
||||||
|
|||||||
@@ -31,10 +31,11 @@ class PathRequests;
|
|||||||
#define PFR_PJ_NOCHANGE 0
|
#define PFR_PJ_NOCHANGE 0
|
||||||
#define PFR_PJ_CHANGE 1
|
#define PFR_PJ_CHANGE 1
|
||||||
|
|
||||||
class PathRequest : public boost::enable_shared_from_this<PathRequest>, public CountedObject <PathRequest>
|
class PathRequest :
|
||||||
|
public boost::enable_shared_from_this <PathRequest>,
|
||||||
|
public CountedObject <PathRequest>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static char const* getCountedObjectName () { return "PathRequest"; }
|
static char const* getCountedObjectName () { return "PathRequest"; }
|
||||||
|
|
||||||
typedef boost::weak_ptr<PathRequest> wptr;
|
typedef boost::weak_ptr<PathRequest> wptr;
|
||||||
@@ -45,7 +46,9 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// VFALCO TODO Break the cyclic dependency on InfoSub
|
// VFALCO TODO Break the cyclic dependency on InfoSub
|
||||||
explicit PathRequest (boost::shared_ptr <InfoSub> const& subscriber, int id, PathRequests&);
|
PathRequest (boost::shared_ptr <InfoSub> const& subscriber,
|
||||||
|
int id, PathRequests&, Journal journal);
|
||||||
|
|
||||||
~PathRequest ();
|
~PathRequest ();
|
||||||
|
|
||||||
bool isValid (const boost::shared_ptr<Ledger>&);
|
bool isValid (const boost::shared_ptr<Ledger>&);
|
||||||
@@ -59,13 +62,14 @@ public:
|
|||||||
Json::Value doStatus (const Json::Value&);
|
Json::Value doStatus (const Json::Value&);
|
||||||
Json::Value doUpdate (const boost::shared_ptr<RippleLineCache>&, bool fast); // update jvStatus
|
Json::Value doUpdate (const boost::shared_ptr<RippleLineCache>&, bool fast); // update jvStatus
|
||||||
InfoSub::pointer getSubscriber ();
|
InfoSub::pointer getSubscriber ();
|
||||||
Journal& journal ();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setValid ();
|
void setValid ();
|
||||||
void resetLevel (int level);
|
void resetLevel (int level);
|
||||||
int parseJson (const Json::Value&, bool complete);
|
int parseJson (const Json::Value&, bool complete);
|
||||||
|
|
||||||
|
Journal m_journal;
|
||||||
|
|
||||||
typedef RippleRecursiveMutex LockType;
|
typedef RippleRecursiveMutex LockType;
|
||||||
typedef LockType::ScopedLockType ScopedLockType;
|
typedef LockType::ScopedLockType ScopedLockType;
|
||||||
LockType mLock;
|
LockType mLock;
|
||||||
@@ -98,64 +102,4 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PathRequests
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
PathRequests (Journal journal, std::shared_ptr <insight::Collector> const& collector)
|
|
||||||
: mJournal (journal)
|
|
||||||
, mLastIdentifier (0)
|
|
||||||
, mLock ("PathRequests", __FILE__, __LINE__)
|
|
||||||
{
|
|
||||||
mFast = collector->make_event ("pathfind_fast");
|
|
||||||
mFull = collector->make_event ("pathfind_full");
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateAll (const boost::shared_ptr<Ledger>& ledger, CancelCallback shouldCancel);
|
|
||||||
|
|
||||||
RippleLineCache::pointer getLineCache (Ledger::pointer& ledger, bool authoritative);
|
|
||||||
|
|
||||||
Json::Value makePathRequest (
|
|
||||||
boost::shared_ptr <InfoSub> const& subscriber,
|
|
||||||
const boost::shared_ptr<Ledger>& ledger,
|
|
||||||
const Json::Value& request);
|
|
||||||
|
|
||||||
Journal& journal ()
|
|
||||||
{
|
|
||||||
return mJournal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reportFast (int milliseconds)
|
|
||||||
{
|
|
||||||
mFast.notify (static_cast < insight::Event::value_type> (milliseconds));
|
|
||||||
}
|
|
||||||
|
|
||||||
void reportFull (int milliseconds)
|
|
||||||
{
|
|
||||||
mFull.notify (static_cast < insight::Event::value_type> (milliseconds));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Journal mJournal;
|
|
||||||
|
|
||||||
insight::Event mFast;
|
|
||||||
insight::Event mFull;
|
|
||||||
|
|
||||||
// Track all requests
|
|
||||||
std::vector<PathRequest::wptr> mRequests;
|
|
||||||
|
|
||||||
// Use a RippleLineCache
|
|
||||||
RippleLineCache::pointer mLineCache;
|
|
||||||
|
|
||||||
Atomic<int> mLastIdentifier;
|
|
||||||
|
|
||||||
typedef RippleRecursiveMutex LockType;
|
|
||||||
typedef LockType::ScopedLockType ScopedLockType;
|
|
||||||
LockType mLock;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// vim:ts=4
|
|
||||||
|
|||||||
194
src/ripple_app/paths/PathRequests.cpp
Normal file
194
src/ripple_app/paths/PathRequests.cpp
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
/** Get the current RippleLineCache, updating it if necessary.
|
||||||
|
Get the correct ledger to use.
|
||||||
|
*/
|
||||||
|
RippleLineCache::pointer PathRequests::getLineCache (Ledger::pointer& ledger, bool authoritative)
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
uint32 lineSeq = mLineCache ? mLineCache->getLedger()->getLedgerSeq() : 0;
|
||||||
|
uint32 lgrSeq = ledger->getLedgerSeq();
|
||||||
|
|
||||||
|
if ( (lineSeq == 0) || // no ledger
|
||||||
|
(authoritative && (lgrSeq > lineSeq)) || // newer authoritative ledger
|
||||||
|
(authoritative && ((lgrSeq + 8) < lineSeq)) || // we jumped way back for some reason
|
||||||
|
(lgrSeq > (lineSeq + 8))) // we jumped way forward for some reason
|
||||||
|
{
|
||||||
|
ledger = boost::make_shared<Ledger>(*ledger, false); // Take a snapshot of the ledger
|
||||||
|
mLineCache = boost::make_shared<RippleLineCache> (ledger);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ledger = mLineCache->getLedger();
|
||||||
|
}
|
||||||
|
return mLineCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathRequests::updateAll (Ledger::ref inLedger, CancelCallback shouldCancel)
|
||||||
|
{
|
||||||
|
std::vector<PathRequest::wptr> requests;
|
||||||
|
|
||||||
|
LoadEvent::autoptr event (getApp().getJobQueue().getLoadEventAP(jtPATH_FIND, "PathRequest::updateAll"));
|
||||||
|
|
||||||
|
// Get the ledger and cache we should be using
|
||||||
|
Ledger::pointer ledger = inLedger;
|
||||||
|
RippleLineCache::pointer cache;
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
requests = mRequests;
|
||||||
|
cache = getLineCache (ledger, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool newRequests = getApp().getLedgerMaster().isNewPathRequest();
|
||||||
|
bool mustBreak = false;
|
||||||
|
|
||||||
|
mJournal.trace << "updateAll seq=" << ledger->getLedgerSeq() << ", " <<
|
||||||
|
requests.size() << " requests";
|
||||||
|
int processed = 0, removed = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
|
||||||
|
{ // Get the latest requests, cache, and ledger
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
if (mRequests.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Newest request is last in mRequests, but we want to serve it first
|
||||||
|
requests.empty();
|
||||||
|
requests.reserve (mRequests.size ());
|
||||||
|
BOOST_REVERSE_FOREACH (PathRequest::wptr& req, mRequests)
|
||||||
|
{
|
||||||
|
requests.push_back (req);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache = getLineCache (ledger, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH (PathRequest::wref wRequest, requests)
|
||||||
|
{
|
||||||
|
if (shouldCancel())
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool remove = true;
|
||||||
|
PathRequest::pointer pRequest = wRequest.lock ();
|
||||||
|
|
||||||
|
if (pRequest)
|
||||||
|
{
|
||||||
|
if (!pRequest->needsUpdate (newRequests, ledger->getLedgerSeq ()))
|
||||||
|
remove = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InfoSub::pointer ipSub = pRequest->getSubscriber ();
|
||||||
|
if (ipSub)
|
||||||
|
{
|
||||||
|
Json::Value update = pRequest->doUpdate (cache, false);
|
||||||
|
update["type"] = "path_find";
|
||||||
|
ipSub->send (update, false);
|
||||||
|
remove = false;
|
||||||
|
++processed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove)
|
||||||
|
{
|
||||||
|
PathRequest::pointer pRequest = wRequest.lock ();
|
||||||
|
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
// Remove any dangling weak pointers or weak pointers that refer to this path request.
|
||||||
|
std::vector<PathRequest::wptr>::iterator it = mRequests.begin();
|
||||||
|
while (it != mRequests.end())
|
||||||
|
{
|
||||||
|
PathRequest::pointer itRequest = it->lock ();
|
||||||
|
if (!itRequest || (itRequest == pRequest))
|
||||||
|
{
|
||||||
|
++removed;
|
||||||
|
it = mRequests.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mustBreak = !newRequests && getApp().getLedgerMaster().isNewPathRequest();
|
||||||
|
if (mustBreak) // We weren't handling new requests and then there was a new request
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mustBreak)
|
||||||
|
{ // a new request came in while we were working
|
||||||
|
newRequests = true;
|
||||||
|
}
|
||||||
|
else if (newRequests)
|
||||||
|
{ // we only did new requests, so we always need a last pass
|
||||||
|
newRequests = getApp().getLedgerMaster().isNewPathRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // check if there are any new requests, otherwise we are done
|
||||||
|
newRequests = getApp().getLedgerMaster().isNewPathRequest();
|
||||||
|
if (!newRequests) // We did a full pass and there are no new requests
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
while (!shouldCancel ());
|
||||||
|
|
||||||
|
mJournal.debug << "updateAll complete " << processed << " process and " <<
|
||||||
|
removed << " removed";
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value PathRequests::makePathRequest(
|
||||||
|
boost::shared_ptr <InfoSub> const& subscriber,
|
||||||
|
const boost::shared_ptr<Ledger>& inLedger,
|
||||||
|
const Json::Value& requestJson)
|
||||||
|
{
|
||||||
|
PathRequest::pointer req = boost::make_shared<PathRequest> (
|
||||||
|
subscriber, ++mLastIdentifier, *this, mJournal);
|
||||||
|
|
||||||
|
Ledger::pointer ledger = inLedger;
|
||||||
|
RippleLineCache::pointer cache;
|
||||||
|
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
cache = getLineCache (ledger, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
Json::Value result = req->doCreate (ledger, cache, requestJson, valid);
|
||||||
|
|
||||||
|
if (valid)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
mRequests.push_back (req);
|
||||||
|
}
|
||||||
|
subscriber->setPathRequest (req);
|
||||||
|
getApp().getLedgerMaster().newPathRequest();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// vim:ts=4
|
||||||
74
src/ripple_app/paths/PathRequests.h
Normal file
74
src/ripple_app/paths/PathRequests.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_PATHREQUESTS_H
|
||||||
|
#define RIPPLE_PATHREQUESTS_H
|
||||||
|
|
||||||
|
class PathRequests
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PathRequests (Journal journal, insight::Collector::ptr const& collector)
|
||||||
|
: mJournal (journal)
|
||||||
|
, mLastIdentifier (0)
|
||||||
|
, mLock ("PathRequests", __FILE__, __LINE__)
|
||||||
|
{
|
||||||
|
mFast = collector->make_event ("pathfind_fast");
|
||||||
|
mFull = collector->make_event ("pathfind_full");
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateAll (const boost::shared_ptr<Ledger>& ledger, CancelCallback shouldCancel);
|
||||||
|
|
||||||
|
RippleLineCache::pointer getLineCache (Ledger::pointer& ledger, bool authoritative);
|
||||||
|
|
||||||
|
Json::Value makePathRequest (
|
||||||
|
boost::shared_ptr <InfoSub> const& subscriber,
|
||||||
|
const boost::shared_ptr<Ledger>& ledger,
|
||||||
|
const Json::Value& request);
|
||||||
|
|
||||||
|
void reportFast (int milliseconds)
|
||||||
|
{
|
||||||
|
mFast.notify (static_cast < insight::Event::value_type> (milliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
void reportFull (int milliseconds)
|
||||||
|
{
|
||||||
|
mFull.notify (static_cast < insight::Event::value_type> (milliseconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Journal mJournal;
|
||||||
|
|
||||||
|
insight::Event mFast;
|
||||||
|
insight::Event mFull;
|
||||||
|
|
||||||
|
// Track all requests
|
||||||
|
std::vector<PathRequest::wptr> mRequests;
|
||||||
|
|
||||||
|
// Use a RippleLineCache
|
||||||
|
RippleLineCache::pointer mLineCache;
|
||||||
|
|
||||||
|
Atomic<int> mLastIdentifier;
|
||||||
|
|
||||||
|
typedef RippleRecursiveMutex LockType;
|
||||||
|
typedef LockType::ScopedLockType ScopedLockType;
|
||||||
|
LockType mLock;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -134,6 +134,7 @@ namespace ripple {
|
|||||||
#include "tx/OfferCreateTransactor.h"
|
#include "tx/OfferCreateTransactor.h"
|
||||||
#include "paths/RippleLineCache.h"
|
#include "paths/RippleLineCache.h"
|
||||||
#include "paths/PathRequest.h"
|
#include "paths/PathRequest.h"
|
||||||
|
#include "paths/PathRequests.h"
|
||||||
#include "main/ParameterTable.h"
|
#include "main/ParameterTable.h"
|
||||||
#include "paths/RippleLineCache.h"
|
#include "paths/RippleLineCache.h"
|
||||||
#include "paths/PathState.h"
|
#include "paths/PathState.h"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace ripple
|
|||||||
{
|
{
|
||||||
|
|
||||||
#include "paths/PathRequest.cpp"
|
#include "paths/PathRequest.cpp"
|
||||||
|
#include "paths/PathRequests.cpp"
|
||||||
#include "paths/RippleCalc.cpp"
|
#include "paths/RippleCalc.cpp"
|
||||||
#include "paths/PathState.cpp"
|
#include "paths/PathState.cpp"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user