mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge #14982: rpc: Add getrpcinfo command
a0ac15459a0df598e1ee1fd36a3899a129cecaeb doc: Add getrpcinfo release notes (João Barbosa) 251a91c1bf245b3674c2612149382a0f1e18dc98 qa: Add tests for getrpcinfo (João Barbosa) d0730f5ce475e5a84da7c61fe79bcd6ed24d693e rpc: Add getrpcinfo command (João Barbosa) 068a8fc05f8dbec198bdc3fe46f955d8a5255303 rpc: Track active commands (João Barbosa) bf4383277d6761cc5b7a91975752c08df829af72 rpc: Remove unused PreCommand signal (João Barbosa) Pull request description: The new `getrpcinfo` command exposes details of the RPC interface. The details can be configuration properties or runtime values/stats. This can be particular useful to coordinate concurrent functional tests (see #14958 from where this was extracted). Tree-SHA512: 7292cb6087f4c429973d991aa2b53ffa1327d5a213df7d6ba5fc69b01b2e1a411f6d1609fed9234896293317dab05f65064da48b8f2b4a998eba532591d31882
This commit is contained in:
parent
744ebbed3a
commit
e54d4af104
5
doc/release-notes-14982.md
Normal file
5
doc/release-notes-14982.md
Normal file
@ -0,0 +1,5 @@
|
||||
New RPCs
|
||||
--------
|
||||
|
||||
- The RPC `getrpcinfo` returns runtime details of the RPC server. At the moment
|
||||
it returns the active commands and the corresponding execution time.
|
@ -35,6 +35,35 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
|
||||
// Any commands submitted by this user will have their commands filtered based on the mapPlatformRestrictions
|
||||
static const std::string defaultPlatformUser = "platform-user";
|
||||
|
||||
struct RPCCommandExecutionInfo
|
||||
{
|
||||
std::string method;
|
||||
int64_t start;
|
||||
};
|
||||
|
||||
struct RPCServerInfo
|
||||
{
|
||||
Mutex mutex;
|
||||
std::list<RPCCommandExecutionInfo> active_commands GUARDED_BY(mutex);
|
||||
};
|
||||
|
||||
static RPCServerInfo g_rpc_server_info;
|
||||
|
||||
struct RPCCommandExecution
|
||||
{
|
||||
std::list<RPCCommandExecutionInfo>::iterator it;
|
||||
explicit RPCCommandExecution(const std::string& method)
|
||||
{
|
||||
LOCK(g_rpc_server_info.mutex);
|
||||
it = g_rpc_server_info.active_commands.insert(g_rpc_server_info.active_commands.cend(), {method, GetTimeMicros()});
|
||||
}
|
||||
~RPCCommandExecution()
|
||||
{
|
||||
LOCK(g_rpc_server_info.mutex);
|
||||
g_rpc_server_info.active_commands.erase(it);
|
||||
}
|
||||
};
|
||||
|
||||
static struct CRPCSignals
|
||||
{
|
||||
boost::signals2::signal<void ()> Started;
|
||||
@ -191,11 +220,40 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest)
|
||||
return GetTime() - GetStartupTime();
|
||||
}
|
||||
|
||||
static UniValue getrpcinfo(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() > 0) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"getrpcinfo",
|
||||
"\nReturns details of the RPC server.\n",
|
||||
{},
|
||||
RPCResults{},
|
||||
RPCExamples{""},
|
||||
}.ToString()
|
||||
);
|
||||
}
|
||||
|
||||
LOCK(g_rpc_server_info.mutex);
|
||||
UniValue active_commands(UniValue::VARR);
|
||||
for (const RPCCommandExecutionInfo& info : g_rpc_server_info.active_commands) {
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
entry.pushKV("method", info.method);
|
||||
entry.pushKV("duration", GetTimeMicros() - info.start);
|
||||
active_commands.push_back(entry);
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("active_commands", active_commands);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const CRPCCommand vRPCCommands[] =
|
||||
{ // category name actor (function) argNames
|
||||
// --------------------- ------------------------ ----------------------- ----------
|
||||
/* Overall control/query calls */
|
||||
{ "control", "getrpcinfo", &getrpcinfo, {} },
|
||||
{ "control", "help", &help, {"command","subcommand"} },
|
||||
{ "control", "stop", &stop, {"wait"} },
|
||||
{ "control", "uptime", &uptime, {} },
|
||||
@ -495,6 +553,7 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req
|
||||
|
||||
try
|
||||
{
|
||||
RPCCommandExecution execution(request.strMethod);
|
||||
// Execute, convert arguments to array if necessary
|
||||
if (request.params.isObject()) {
|
||||
return command.actor(transformNamedArguments(request, command.argNames), result, last_handler);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal
|
||||
from test_framework.util import assert_equal, assert_greater_than_or_equal
|
||||
|
||||
def expect_http_status(expected_http_status, expected_rpc_code,
|
||||
fcn, *args):
|
||||
@ -22,6 +22,16 @@ class RPCInterfaceTest(BitcoinTestFramework):
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def test_getrpcinfo(self):
|
||||
self.log.info("Testing getrpcinfo...")
|
||||
|
||||
info = self.nodes[0].getrpcinfo()
|
||||
assert_equal(len(info['active_commands']), 1)
|
||||
|
||||
command = info['active_commands'][0]
|
||||
assert_equal(command['method'], 'getrpcinfo')
|
||||
assert_greater_than_or_equal(command['duration'], 0)
|
||||
|
||||
def test_batch_request(self):
|
||||
self.log.info("Testing basic JSON-RPC batch request...")
|
||||
|
||||
@ -55,6 +65,7 @@ class RPCInterfaceTest(BitcoinTestFramework):
|
||||
expect_http_status(500, -8, self.nodes[0].getblockhash, 42)
|
||||
|
||||
def run_test(self):
|
||||
self.test_getrpcinfo()
|
||||
self.test_batch_request()
|
||||
self.test_http_status_codes()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user