Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create health_check rpc #3365

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 88 additions & 1 deletion src/ripple/overlay/impl/OverlayImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1073,11 +1073,98 @@ OverlayImpl::processValidatorList(
return true;
}

bool
OverlayImpl::processHealth(http_request_type const& req, Handoff& handoff)
{
if (req.target() != "/health")
return false;
boost::beast::http::response<json_body> msg;
msg.version(req.version());
msg.insert("Server", BuildInfo::getFullVersionString());
msg.insert("Content-Type", "application/json");
msg.insert("Connection", "close");

auto info = getServerInfo();

int last_validated_ledger_age = std::numeric_limits<int>::max();
if (info.isMember("validated_ledger"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all of the sting literals in they pull request are vaguely JSON-like, my inclination is to declare them in jss.h and refer to them from there.

last_validated_ledger_age = info["validated_ledger"]["age"].asInt();
bool amendment_blocked = false;
if (info.isMember("amendment_blocked"))
amendment_blocked = true;
int number_peers = info["peers"].asInt();
std::string server_state = info["server_state"].asString();
auto load_factor = info["load_factor"].asDouble();
Comment on lines +1092 to +1097
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think most of these local variables can be const.


enum { healthy, warning, critical };
int health = healthy;
auto set_health = [&health](int state) {
if (health < state)
health = state;
};

if (last_validated_ledger_age >= 7)
{
msg.body()[jss::info]["validated_ledger"] = last_validated_ledger_age;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to set the ["validated_ledger"] to std::numeric_limits<int>::max() if the server_info does not return a ["validated_ledger"]["age"]. That doesn't feel like the right thing to tell a user.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just use some sort of string here, such as "Server has no validated ledger".

if (last_validated_ledger_age < 20)
set_health(warning);
else
set_health(critical);
}

if (amendment_blocked)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When possible, I'd be inclined to declare the locals inside the scope of the if using if initializers.

{
msg.body()[jss::info]["amendment_blocked"] = true;
set_health(critical);
}

if (number_peers <= 7)
{
msg.body()[jss::info]["peers"] = number_peers;
if (number_peers != 0)
set_health(warning);
else
set_health(critical);
}

if (!(server_state == "full" || server_state == "validating" ||
server_state == "proposing"))
{
msg.body()[jss::info]["server_state"] = server_state;
if (server_state == "syncing" || server_state == "tracking" ||
server_state == "connected")
{
set_health(warning);
}
else
set_health(critical);
}

if (load_factor > 100)
{
msg.body()[jss::info]["load_factor"] = load_factor;
if (load_factor < 1000)
set_health(warning);
else
set_health(critical);
}

if (health != critical)
msg.result(boost::beast::http::status::ok);
else
msg.result(boost::beast::http::status::service_unavailable);

msg.prepare_payload();
handoff.response = std::make_shared<SimpleWriter>(msg);
return true;
}

bool
OverlayImpl::processRequest(http_request_type const& req, Handoff& handoff)
{
// Take advantage of || short-circuiting
return processCrawl(req, handoff) || processValidatorList(req, handoff);
return processCrawl(req, handoff) || processValidatorList(req, handoff) ||
processHealth(req, handoff);
}

Overlay::PeerSequence
Expand Down
8 changes: 8 additions & 0 deletions src/ripple/overlay/impl/OverlayImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,14 @@ class OverlayImpl : public Overlay
bool
processValidatorList(http_request_type const& req, Handoff& handoff);

/** Handles health requests. Health returns information about the
health of the node.

@return true if the request was handled.
*/
bool
processHealth(http_request_type const& req, Handoff& handoff);

/** Handles non-peer protocol requests.

@return true if the request was handled.
Expand Down