Instantiate an RPCHandler per request.

RPCHandlers are pretty light objects and this allows us to pass in
parameters like the InfoSub object without locking or adding more
parameters to the RPC methods.
This commit is contained in:
Stefan Thomas
2012-11-10 15:51:45 -08:00
parent b6bbef84cf
commit f5a6fdbab9
5 changed files with 34 additions and 31 deletions

View File

@@ -93,6 +93,13 @@ Json::Value RPCHandler::rpcError(int iError)
RPCHandler::RPCHandler(NetworkOPs* netOps)
{
mNetOps=netOps;
mInfoSub=NULL;
}
RPCHandler::RPCHandler(NetworkOPs* netOps, InfoSub* infoSub)
{
mNetOps=netOps;
mInfoSub=infoSub;
}
int RPCHandler::getParamCount(const Json::Value& params)
@@ -1299,7 +1306,7 @@ Json::Value RPCHandler::doLogRotate(const Json::Value& params)
return Log::rotateLog();
}
Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& params, int role, InfoSub* sub)
Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& params, int role)
{
cLog(lsTRACE) << "RPC:" << command;
cLog(lsTRACE) << "RPC params:" << params;
@@ -1376,7 +1383,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
{
return rpcError(rpcNO_PERMISSION);
}
else if (commandsA[i].mEvented && sub == NULL)
else if (commandsA[i].mEvented && mInfoSub == NULL)
{
return rpcError(rpcNO_EVENTS);
}
@@ -1406,11 +1413,6 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param
}
else
{
if (sub != NULL)
{
isCurrent = sub;
}
try {
return (this->*(commandsA[i].dfpFunc))(params);
}
@@ -1993,16 +1995,16 @@ Json::Value RPCHandler::doSubscribe(const Json::Value& jvRequest)
if(streamName=="server")
{
mNetOps->subServer(isCurrent, jvResult);
mNetOps->subServer(mInfoSub, jvResult);
}else if(streamName=="ledger")
{
mNetOps->subLedger(isCurrent, jvResult);
mNetOps->subLedger(mInfoSub, jvResult);
}else if(streamName=="transactions")
{
mNetOps->subTransactions(isCurrent);
mNetOps->subTransactions(mInfoSub);
}else if(streamName=="rt_transactions")
{
mNetOps->subRTTransactions(isCurrent);
mNetOps->subRTTransactions(mInfoSub);
}else
{
jvResult["error"] = str(boost::format("Unknown stream: %s") % streamName);
@@ -2025,10 +2027,10 @@ Json::Value RPCHandler::doSubscribe(const Json::Value& jvRequest)
{
BOOST_FOREACH(const RippleAddress& naAccountID, usnaAccoundIds)
{
isCurrent->insertSubAccountInfo(naAccountID);
mInfoSub->insertSubAccountInfo(naAccountID);
}
mNetOps->subAccount(isCurrent, usnaAccoundIds, true);
mNetOps->subAccount(mInfoSub, usnaAccoundIds, true);
}
}
@@ -2043,10 +2045,10 @@ Json::Value RPCHandler::doSubscribe(const Json::Value& jvRequest)
{
BOOST_FOREACH(const RippleAddress& naAccountID, usnaAccoundIds)
{
isCurrent->insertSubAccountInfo(naAccountID);
mInfoSub->insertSubAccountInfo(naAccountID);
}
mNetOps->subAccount(isCurrent, usnaAccoundIds, false);
mNetOps->subAccount(mInfoSub, usnaAccoundIds, false);
}
}
@@ -2067,16 +2069,16 @@ Json::Value RPCHandler::doUnsubscribe(const Json::Value& jvRequest)
if(streamName=="server")
{
mNetOps->unsubServer(isCurrent);
mNetOps->unsubServer(mInfoSub);
}else if(streamName=="ledger")
{
mNetOps->unsubLedger(isCurrent);
mNetOps->unsubLedger(mInfoSub);
}else if(streamName=="transactions")
{
mNetOps->unsubTransactions(isCurrent);
mNetOps->unsubTransactions(mInfoSub);
}else if(streamName=="rt_transactions")
{
mNetOps->unsubRTTransactions(isCurrent);
mNetOps->unsubRTTransactions(mInfoSub);
}else
{
jvResult["error"] = str(boost::format("Unknown stream: %s") % streamName);
@@ -2099,10 +2101,10 @@ Json::Value RPCHandler::doUnsubscribe(const Json::Value& jvRequest)
{
BOOST_FOREACH(const RippleAddress& naAccountID, usnaAccoundIds)
{
isCurrent->insertSubAccountInfo(naAccountID);
mInfoSub->insertSubAccountInfo(naAccountID);
}
mNetOps->unsubAccount(isCurrent, usnaAccoundIds,true);
mNetOps->unsubAccount(mInfoSub, usnaAccoundIds,true);
}
}
@@ -2117,10 +2119,10 @@ Json::Value RPCHandler::doUnsubscribe(const Json::Value& jvRequest)
{
BOOST_FOREACH(const RippleAddress& naAccountID, usnaAccoundIds)
{
isCurrent->insertSubAccountInfo(naAccountID);
mInfoSub->insertSubAccountInfo(naAccountID);
}
mNetOps->unsubAccount(isCurrent, usnaAccoundIds,false);
mNetOps->unsubAccount(mInfoSub, usnaAccoundIds,false);
}
}

View File

@@ -7,7 +7,7 @@ class NetworkOPs;
class RPCHandler
{
NetworkOPs* mNetOps;
InfoSub* isCurrent;
InfoSub* mInfoSub;
typedef Json::Value (RPCHandler::*doFuncPtr)(const Json::Value &params);
enum {
@@ -157,8 +157,9 @@ public:
enum { GUEST, USER, ADMIN };
RPCHandler(NetworkOPs* netOps);
RPCHandler(NetworkOPs* netOps, InfoSub* infoSub);
Json::Value doCommand(const std::string& command, Json::Value& params, int role, InfoSub* sub = NULL);
Json::Value doCommand(const std::string& command, Json::Value& params, int role);
Json::Value rpcError(int iError);
Json::Value handleJSONSubmit(const Json::Value& jvRequest);

View File

@@ -26,7 +26,7 @@ SETUP_LOG();
#endif
RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork)
: mNetOps(nopNetwork), mRPCHandler(nopNetwork), mSocket(io_service)
: mNetOps(nopNetwork), mSocket(io_service)
{
mRole = RPCHandler::GUEST;
@@ -142,6 +142,8 @@ std::string RPCServer::handleRequest(const std::string& requestStr)
else if (!valParams.isArray())
return(HTTPReply(400, "params unparseable"));
RPCHandler mRPCHandler(mNetOps);
cLog(lsTRACE) << valParams;
Json::Value result = mRPCHandler.doCommand(strMethod, valParams,mRole);
cLog(lsTRACE) << result;

View File

@@ -22,9 +22,7 @@ public:
private:
NetworkOPs* mNetOps;
RPCHandler mRPCHandler;
boost::asio::ip::tcp::socket mSocket;

View File

@@ -45,16 +45,16 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest)
return jvResult;
}
RPCHandler mRPCHandler(&mNetwork, this);
Json::Value jvResult(Json::objectValue);
// Regular RPC command
jvResult["result"] = theApp->getRPCHandler().doCommand(
jvResult["result"] = mRPCHandler.doCommand(
jvRequest["command"].asString(),
jvRequest.isMember("params")
? jvRequest["params"]
: jvRequest,
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN,
this);
mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN);
// Currently we will simply unwrap errors returned by the RPC
// API, in the future maybe we can make the responses