Changeset View
Standalone View
src/rpc/server.cpp
Show All 29 Lines | |||||
static bool fRPCInWarmup = true; | static bool fRPCInWarmup = true; | ||||
static std::string rpcWarmupStatus("RPC server started"); | static std::string rpcWarmupStatus("RPC server started"); | ||||
static CCriticalSection cs_rpcWarmup; | static CCriticalSection cs_rpcWarmup; | ||||
/* Timer-creating functions */ | /* Timer-creating functions */ | ||||
static RPCTimerInterface *timerInterface = nullptr; | static RPCTimerInterface *timerInterface = nullptr; | ||||
/* Map of name to timer. */ | /* Map of name to timer. */ | ||||
static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers; | static std::map<std::string, std::unique_ptr<RPCTimerBase>> deadlineTimers; | ||||
UniValue RPCServer::ExecuteCommand(Config &config, | |||||
const JSONRPCRequest &request) const { | |||||
// Return immediately if in warmup | |||||
{ | |||||
LOCK(cs_rpcWarmup); | |||||
if (fRPCInWarmup) { | |||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | |||||
deadalnix: This is duplicated from somewhere. It would deserve to be merged. | |||||
jasonbcoxAuthorUnsubmitted Not Done Inline ActionsI plan on removing it from CRPCTable::execute() and removed all callsites to execute() except for RPCServer::ExecuteCommand(). That enables me to clean up the duplicate. However, this will need to be a separate diff. I can consolidate them into a standalone function if you like. jasonbcox: I plan on removing it from CRPCTable::execute() and removed all callsites to execute() except… | |||||
} | |||||
} | |||||
// TODO Only call tableRPC.execute() if no context-sensitive RPC command | |||||
// exists | |||||
deadalnixUnsubmitted Not Done Inline ActionsThe RPC server should probably be agnostic to the type of commands it runs. deadalnix: The RPC server should probably be agnostic to the type of commands it runs. | |||||
jasonbcoxAuthorUnsubmitted Not Done Inline ActionsIt will be once I migrate these calls. This is a just a note to anyone working on this code until that change is made. jasonbcox: It will be once I migrate these calls. This is a just a note to anyone working on this code… | |||||
// Check if context-free RPC method is valid and execute it | |||||
return tableRPC.execute(config, request); | |||||
} | |||||
static struct CRPCSignals { | static struct CRPCSignals { | ||||
boost::signals2::signal<void()> Started; | boost::signals2::signal<void()> Started; | ||||
boost::signals2::signal<void()> Stopped; | boost::signals2::signal<void()> Stopped; | ||||
boost::signals2::signal<void(const ContextFreeRPCCommand &)> PreCommand; | boost::signals2::signal<void(const ContextFreeRPCCommand &)> PreCommand; | ||||
boost::signals2::signal<void(const ContextFreeRPCCommand &)> PostCommand; | boost::signals2::signal<void(const ContextFreeRPCCommand &)> PostCommand; | ||||
} g_rpcSignals; | } g_rpcSignals; | ||||
void RPCServerSignals::OnStarted(std::function<void()> slot) { | void RPCServerSignals::OnStarted(std::function<void()> slot) { | ||||
▲ Show 20 Lines • Show All 349 Lines • ▼ Show 20 Lines | |||||
bool RPCIsInWarmup(std::string *outStatus) { | bool RPCIsInWarmup(std::string *outStatus) { | ||||
LOCK(cs_rpcWarmup); | LOCK(cs_rpcWarmup); | ||||
if (outStatus) { | if (outStatus) { | ||||
*outStatus = rpcWarmupStatus; | *outStatus = rpcWarmupStatus; | ||||
} | } | ||||
return fRPCInWarmup; | return fRPCInWarmup; | ||||
} | } | ||||
static UniValue JSONRPCExecOne(Config &config, JSONRPCRequest jreq, | static UniValue JSONRPCExecOne(Config &config, RPCServer &rpcServer, | ||||
const UniValue &req) { | JSONRPCRequest jreq, const UniValue &req) { | ||||
UniValue rpc_result(UniValue::VOBJ); | UniValue rpc_result(UniValue::VOBJ); | ||||
try { | try { | ||||
jreq.parse(req); | jreq.parse(req); | ||||
UniValue result = tableRPC.execute(config, jreq); | UniValue result = rpcServer.ExecuteCommand(config, jreq); | ||||
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); | rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); | ||||
} catch (const UniValue &objError) { | } catch (const UniValue &objError) { | ||||
rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); | rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
rpc_result = JSONRPCReplyObj( | rpc_result = JSONRPCReplyObj( | ||||
NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); | NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); | ||||
} | } | ||||
return rpc_result; | return rpc_result; | ||||
} | } | ||||
std::string JSONRPCExecBatch(Config &config, const JSONRPCRequest &jreq, | std::string JSONRPCExecBatch(Config &config, RPCServer &rpcServer, | ||||
const UniValue &vReq) { | const JSONRPCRequest &jreq, const UniValue &vReq) { | ||||
UniValue ret(UniValue::VARR); | UniValue ret(UniValue::VARR); | ||||
for (size_t i = 0; i < vReq.size(); i++) { | for (size_t i = 0; i < vReq.size(); i++) { | ||||
ret.push_back(JSONRPCExecOne(config, jreq, vReq[i])); | ret.push_back(JSONRPCExecOne(config, rpcServer, jreq, vReq[i])); | ||||
} | } | ||||
return ret.write() + "\n"; | return ret.write() + "\n"; | ||||
} | } | ||||
/** | /** | ||||
* Process named arguments into a vector of positional arguments, based on the | * Process named arguments into a vector of positional arguments, based on the | ||||
* passed-in specification for the RPC call's arguments. | * passed-in specification for the RPC call's arguments. | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | UniValue CRPCTable::execute(Config &config, | ||||
// Return immediately if in warmup | // Return immediately if in warmup | ||||
{ | { | ||||
LOCK(cs_rpcWarmup); | LOCK(cs_rpcWarmup); | ||||
if (fRPCInWarmup) { | if (fRPCInWarmup) { | ||||
throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); | ||||
} | } | ||||
} | } | ||||
// Find method | // Check if legacy RPC method is valid. | ||||
// See RPCServer::ExecuteCommand for context-sensitive RPC commands. | |||||
deadalnixUnsubmitted Done Inline ActionsAll RPCCommand should look the same from the perspective of the server. See Liskov's substitution principle. deadalnix: All RPCCommand should look the same from the perspective of the server. See Liskov's… | |||||
jasonbcoxAuthorUnsubmitted Done Inline ActionsPerhaps this comment is much less valid now that I've added the TODO. Similarly, I expect this to go away once the migration is complete. I'll remove this comment entirely for now since it's both redundant and will be confusing if failed to be removed. jasonbcox: Perhaps this comment is much less valid now that I've added the TODO. Similarly, I expect this… | |||||
jasonbcoxAuthorUnsubmitted Done Inline ActionsOn second thought, this should stay because it points readers to the correct portion of code until context-free commands are fully migrated. jasonbcox: On second thought, this should stay because it points readers to the correct portion of code… | |||||
const ContextFreeRPCCommand *pcmd = tableRPC[request.strMethod]; | const ContextFreeRPCCommand *pcmd = tableRPC[request.strMethod]; | ||||
if (!pcmd) { | if (!pcmd) { | ||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); | throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); | ||||
} | } | ||||
g_rpcSignals.PreCommand(*pcmd); | g_rpcSignals.PreCommand(*pcmd); | ||||
try { | try { | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |
This is duplicated from somewhere. It would deserve to be merged.