mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-03 01:15:53 +00:00
Use continuation in legacy pathfinding:
Handle legacy (ripple_path_find) requests that don't specify a ledger the same way regular path_find requests are. This provides a performance improvement for these requests and reduces the problem of server busy errors. Conflicts: src/ripple/app/paths/PathRequest.cpp
This commit is contained in:
@@ -58,6 +58,27 @@ PathRequest::PathRequest (
|
|||||||
ptCreated = boost::posix_time::microsec_clock::universal_time ();
|
ptCreated = boost::posix_time::microsec_clock::universal_time ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PathRequest::PathRequest (
|
||||||
|
std::function <void(void)> const& completion,
|
||||||
|
int id,
|
||||||
|
PathRequests& owner,
|
||||||
|
beast::Journal journal)
|
||||||
|
: m_journal (journal)
|
||||||
|
, mOwner (owner)
|
||||||
|
, fCompletion (completion)
|
||||||
|
, jvStatus (Json::objectValue)
|
||||||
|
, bValid (false)
|
||||||
|
, mLastIndex (0)
|
||||||
|
, mInProgress (false)
|
||||||
|
, iLastLevel (0)
|
||||||
|
, bLastSuccess (false)
|
||||||
|
, iIdentifier (id)
|
||||||
|
{
|
||||||
|
if (m_journal.debug)
|
||||||
|
m_journal.debug << iIdentifier << " created";
|
||||||
|
ptCreated = boost::posix_time::microsec_clock::universal_time ();
|
||||||
|
}
|
||||||
|
|
||||||
static std::string const get_milli_diff (
|
static std::string const get_milli_diff (
|
||||||
boost::posix_time::ptime const& after,
|
boost::posix_time::ptime const& after,
|
||||||
boost::posix_time::ptime
|
boost::posix_time::ptime
|
||||||
@@ -132,12 +153,23 @@ bool PathRequest::needsUpdate (bool newOnly, LedgerIndex index)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PathRequest::hasCompletion ()
|
||||||
|
{
|
||||||
|
return bool (fCompletion);
|
||||||
|
}
|
||||||
|
|
||||||
void PathRequest::updateComplete ()
|
void PathRequest::updateComplete ()
|
||||||
{
|
{
|
||||||
ScopedLockType sl (mIndexLock);
|
ScopedLockType sl (mIndexLock);
|
||||||
|
|
||||||
assert (mInProgress);
|
assert (mInProgress);
|
||||||
mInProgress = false;
|
mInProgress = false;
|
||||||
|
|
||||||
|
if (fCompletion)
|
||||||
|
{
|
||||||
|
fCompletion();
|
||||||
|
fCompletion = std::function<void (void)>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathRequest::isValid (RippleLineCache::ref crCache)
|
bool PathRequest::isValid (RippleLineCache::ref crCache)
|
||||||
@@ -407,6 +439,15 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasCompletion ())
|
||||||
|
{
|
||||||
|
// Old ripple_path_find API gives destination_currencies
|
||||||
|
auto& destCurrencies = (jvStatus[jss::destination_currencies] = Json::arrayValue);
|
||||||
|
auto usCurrencies = accountDestCurrencies (*raDstAccount, cache, true);
|
||||||
|
for (auto const& c : usCurrencies)
|
||||||
|
destCurrencies.append (to_string (c));
|
||||||
|
}
|
||||||
|
|
||||||
jvStatus[jss::source_account] = getApp().accountIDCache().toBase58(*raSrcAccount);
|
jvStatus[jss::source_account] = getApp().accountIDCache().toBase58(*raSrcAccount);
|
||||||
jvStatus[jss::destination_account] = getApp().accountIDCache().toBase58(*raDstAccount);
|
jvStatus[jss::destination_account] = getApp().accountIDCache().toBase58(*raDstAccount);
|
||||||
jvStatus[jss::destination_amount] = saDstAmount.getJson (0);
|
jvStatus[jss::destination_amount] = saDstAmount.getJson (0);
|
||||||
@@ -535,6 +576,13 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
|
|
||||||
jvEntry[jss::source_amount] = rc.actualAmountIn.getJson (0);
|
jvEntry[jss::source_amount] = rc.actualAmountIn.getJson (0);
|
||||||
jvEntry[jss::paths_computed] = spsPaths.getJson (0);
|
jvEntry[jss::paths_computed] = spsPaths.getJson (0);
|
||||||
|
|
||||||
|
if (hasCompletion ())
|
||||||
|
{
|
||||||
|
// Old ripple_path_find API requires this
|
||||||
|
jvEntry[jss::paths_canonical] = Json::arrayValue;
|
||||||
|
}
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
jvArray.append (jvEntry);
|
jvArray.append (jvEntry);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ public:
|
|||||||
PathRequests&,
|
PathRequests&,
|
||||||
beast::Journal journal);
|
beast::Journal journal);
|
||||||
|
|
||||||
|
PathRequest (
|
||||||
|
std::function <void (void)> const& completion,
|
||||||
|
int id,
|
||||||
|
PathRequests&,
|
||||||
|
beast::Journal journal);
|
||||||
|
|
||||||
~PathRequest ();
|
~PathRequest ();
|
||||||
|
|
||||||
bool isValid ();
|
bool isValid ();
|
||||||
@@ -80,6 +86,7 @@ public:
|
|||||||
// update jvStatus
|
// update jvStatus
|
||||||
Json::Value doUpdate (const std::shared_ptr<RippleLineCache>&, bool fast);
|
Json::Value doUpdate (const std::shared_ptr<RippleLineCache>&, bool fast);
|
||||||
InfoSub::pointer getSubscriber ();
|
InfoSub::pointer getSubscriber ();
|
||||||
|
bool hasCompletion ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isValid (RippleLineCache::ref crCache);
|
bool isValid (RippleLineCache::ref crCache);
|
||||||
@@ -96,6 +103,7 @@ private:
|
|||||||
PathRequests& mOwner;
|
PathRequests& mOwner;
|
||||||
|
|
||||||
std::weak_ptr<InfoSub> wpSubscriber; // Who this request came from
|
std::weak_ptr<InfoSub> wpSubscriber; // Who this request came from
|
||||||
|
std::function <void (void)> fCompletion;
|
||||||
|
|
||||||
Json::Value jvId;
|
Json::Value jvId;
|
||||||
Json::Value jvStatus; // Last result
|
Json::Value jvStatus; // Last result
|
||||||
|
|||||||
@@ -105,6 +105,13 @@ void PathRequests::updateAll (Ledger::ref inLedger,
|
|||||||
++processed;
|
++processed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (pRequest->hasCompletion ())
|
||||||
|
{
|
||||||
|
// One-shot request with completion function
|
||||||
|
pRequest->doUpdate (cache, false);
|
||||||
|
pRequest->updateComplete();
|
||||||
|
++processed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +175,25 @@ void PathRequests::updateAll (Ledger::ref inLedger,
|
|||||||
removed << " removed";
|
removed << " removed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathRequests::insertPathRequest (PathRequest::pointer const& req)
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock);
|
||||||
|
|
||||||
|
// Insert after any older unserviced requests but before any serviced requests
|
||||||
|
std::vector<PathRequest::wptr>::iterator it = mRequests.begin ();
|
||||||
|
while (it != mRequests.end ())
|
||||||
|
{
|
||||||
|
PathRequest::pointer req = it->lock ();
|
||||||
|
if (req && !req->isNew ())
|
||||||
|
break; // This request has been handled, we come before it
|
||||||
|
|
||||||
|
// This is a newer request, we come after it
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
mRequests.insert (it, PathRequest::wptr (req));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a new-style path_find request
|
||||||
Json::Value PathRequests::makePathRequest(
|
Json::Value PathRequests::makePathRequest(
|
||||||
std::shared_ptr <InfoSub> const& subscriber,
|
std::shared_ptr <InfoSub> const& subscriber,
|
||||||
const std::shared_ptr<Ledger>& inLedger,
|
const std::shared_ptr<Ledger>& inLedger,
|
||||||
@@ -189,27 +215,47 @@ Json::Value PathRequests::makePathRequest(
|
|||||||
|
|
||||||
if (valid)
|
if (valid)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
ScopedLockType sl (mLock);
|
|
||||||
|
|
||||||
// Insert after any older unserviced requests but before any serviced requests
|
|
||||||
std::vector<PathRequest::wptr>::iterator it = mRequests.begin ();
|
|
||||||
while (it != mRequests.end ())
|
|
||||||
{
|
|
||||||
PathRequest::pointer req = it->lock ();
|
|
||||||
if (req && !req->isNew ())
|
|
||||||
break; // This request has been handled, we come before it
|
|
||||||
|
|
||||||
// This is a newer request, we come after it
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
mRequests.insert (it, PathRequest::wptr (req));
|
|
||||||
|
|
||||||
}
|
|
||||||
subscriber->setPathRequest (req);
|
subscriber->setPathRequest (req);
|
||||||
|
insertPathRequest (req);
|
||||||
getApp().getLedgerMaster().newPathRequest();
|
getApp().getLedgerMaster().newPathRequest();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make an old-style ripple_path_find request
|
||||||
|
Json::Value PathRequests::makeLegacyPathRequest(
|
||||||
|
PathRequest::pointer& req,
|
||||||
|
std::function <void (void)> completion,
|
||||||
|
const std::shared_ptr<Ledger>& inLedger,
|
||||||
|
Json::Value const& request)
|
||||||
|
{
|
||||||
|
// This assignment must take place before the
|
||||||
|
// completion function is called
|
||||||
|
req = std::make_shared<PathRequest> (
|
||||||
|
completion, ++mLastIdentifier, *this, mJournal);
|
||||||
|
|
||||||
|
auto ledger = inLedger;
|
||||||
|
RippleLineCache::pointer cache;
|
||||||
|
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock);
|
||||||
|
cache = getLineCache (ledger, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
Json::Value result = req->doCreate (ledger, cache, request, valid);
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
req.reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
insertPathRequest (req);
|
||||||
|
getApp().getLedgerMaster().newPathRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ public:
|
|||||||
const std::shared_ptr<Ledger>& ledger,
|
const std::shared_ptr<Ledger>& ledger,
|
||||||
Json::Value const& request);
|
Json::Value const& request);
|
||||||
|
|
||||||
|
Json::Value makeLegacyPathRequest (
|
||||||
|
PathRequest::pointer& req,
|
||||||
|
std::function <void (void)> completion,
|
||||||
|
const std::shared_ptr<Ledger>& inLedger,
|
||||||
|
Json::Value const& request);
|
||||||
|
|
||||||
void reportFast (int milliseconds)
|
void reportFast (int milliseconds)
|
||||||
{
|
{
|
||||||
mFast.notify (static_cast < beast::insight::Event::value_type> (milliseconds));
|
mFast.notify (static_cast < beast::insight::Event::value_type> (milliseconds));
|
||||||
@@ -60,6 +66,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void insertPathRequest (PathRequest::pointer const&);
|
||||||
|
|
||||||
beast::Journal mJournal;
|
beast::Journal mJournal;
|
||||||
|
|
||||||
beast::insight::Event mFast;
|
beast::insight::Event mFast;
|
||||||
|
|||||||
@@ -59,6 +59,25 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
|||||||
if (!lpLedger)
|
if (!lpLedger)
|
||||||
return jvResult;
|
return jvResult;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.loadType = Resource::feeHighBurdenRPC;
|
||||||
|
lpLedger = context.netOps.getClosedLedger();
|
||||||
|
|
||||||
|
PathRequest::pointer request;
|
||||||
|
context.suspend ([&request, &context, &jvResult, &lpLedger](RPC::Callback const& c)
|
||||||
|
{
|
||||||
|
jvResult = getApp().getPathRequests().makeLegacyPathRequest (
|
||||||
|
request, c, lpLedger, context.params);
|
||||||
|
if (! request)
|
||||||
|
c();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (request)
|
||||||
|
jvResult = request->doStatus (context.params);
|
||||||
|
|
||||||
|
return jvResult;
|
||||||
|
}
|
||||||
|
|
||||||
if (!context.params.isMember (jss::source_account))
|
if (!context.params.isMember (jss::source_account))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ ServerHandlerImp::ServerHandlerImp (Stoppable& parent,
|
|||||||
: ServerHandler (parent)
|
: ServerHandler (parent)
|
||||||
, m_resourceManager (resourceManager)
|
, m_resourceManager (resourceManager)
|
||||||
, m_journal (deprecatedLogs().journal("Server"))
|
, m_journal (deprecatedLogs().journal("Server"))
|
||||||
, m_jobQueue (jobQueue)
|
|
||||||
, m_networkOPs (networkOPs)
|
, m_networkOPs (networkOPs)
|
||||||
, m_server (HTTP::make_Server(
|
, m_server (HTTP::make_Server(
|
||||||
*this, io_service, deprecatedLogs().journal("Server")))
|
*this, io_service, deprecatedLogs().journal("Server")))
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class ServerHandlerImp
|
|||||||
private:
|
private:
|
||||||
Resource::Manager& m_resourceManager;
|
Resource::Manager& m_resourceManager;
|
||||||
beast::Journal m_journal;
|
beast::Journal m_journal;
|
||||||
JobQueue& m_jobQueue;
|
|
||||||
NetworkOPs& m_networkOPs;
|
NetworkOPs& m_networkOPs;
|
||||||
std::unique_ptr<HTTP::Server> m_server;
|
std::unique_ptr<HTTP::Server> m_server;
|
||||||
RPC::Continuation m_continuation;
|
RPC::Continuation m_continuation;
|
||||||
|
|||||||
Reference in New Issue
Block a user