aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc/server.cpp')
-rw-r--r--src/rpc/server.cpp93
1 files changed, 78 insertions, 15 deletions
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index e7e047334e..2ed74547b9 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Copyright (c) 2009-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -31,11 +31,39 @@ static RPCTimerInterface* timerInterface = nullptr;
/* Map of name to timer. */
static std::map<std::string, std::unique_ptr<RPCTimerBase> > deadlineTimers;
+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.end(), {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;
boost::signals2::signal<void ()> Stopped;
- boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
} g_rpcSignals;
void RPCServer::OnStarted(std::function<void ()> slot)
@@ -203,10 +231,12 @@ UniValue help(const JSONRPCRequest& jsonRequest)
"\nList all commands, or get help for a specified command.\n",
{
{"command", RPCArg::Type::STR, /* opt */ true, /* default_val */ "all commands", "The command to get help on"},
- }}
- .ToString() +
- "\nResult:\n"
+ },
+ RPCResult{
"\"text\" (string) The help text\n"
+ },
+ RPCExamples{""},
+ }.ToString()
);
std::string strCommand;
@@ -226,8 +256,11 @@ UniValue stop(const JSONRPCRequest& jsonRequest)
if (jsonRequest.fHelp || jsonRequest.params.size() > 1)
throw std::runtime_error(
RPCHelpMan{"stop",
- "\nStop Bitcoin server.", {}}
- .ToString());
+ "\nStop Bitcoin server.",
+ {},
+ RPCResults{},
+ RPCExamples{""},
+ }.ToString());
// Event loop will exit after current HTTP requests have been handled, so
// this reply will get back to the client.
StartShutdown();
@@ -242,23 +275,54 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest)
if (jsonRequest.fHelp || jsonRequest.params.size() > 0)
throw std::runtime_error(
RPCHelpMan{"uptime",
- "\nReturns the total uptime of the server.\n", {}}
- .ToString() +
- "\nResult:\n"
+ "\nReturns the total uptime of the server.\n",
+ {},
+ RPCResult{
"ttt (numeric) The number of seconds that the server has been running\n"
- "\nExamples:\n"
- + HelpExampleCli("uptime", "")
+ },
+ RPCExamples{
+ HelpExampleCli("uptime", "")
+ HelpExampleRpc("uptime", "")
- );
+ },
+ }.ToString());
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"} },
{ "control", "stop", &stop, {"wait"} },
{ "control", "uptime", &uptime, {} },
@@ -483,10 +547,9 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
- g_rpcSignals.PreCommand(*pcmd);
-
try
{
+ RPCCommandExecution execution(request.strMethod);
// Execute, convert arguments to array if necessary
if (request.params.isObject()) {
return pcmd->actor(transformNamedArguments(request, pcmd->argNames));