Skip to content

Commit

Permalink
Performance counter modifications:
Browse files Browse the repository at this point in the history
  * Create and display counters to track:
    1) Pending transaction limit overruns.
    2) Total peer disconnections.
    3) Peers disconnections due to resource consumption.
  * Render 64 bit integers in Json.
  * Convert state_accounting counters in server_info to 64 bit integers.
  * Avoid a potential double-free in Json library.
  • Loading branch information
mtrippled committed Dec 20, 2017
1 parent b986447 commit e24689b
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 4 deletions.
8 changes: 6 additions & 2 deletions src/ripple/app/misc/NetworkOPs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class NetworkOPsImp final
{
struct Counters
{
std::uint32_t transitions = 0;
std::uint64_t transitions = 0;
std::chrono::microseconds dur = std::chrono::microseconds (0);
};

Expand Down Expand Up @@ -2367,6 +2367,10 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)

info[jss::state_accounting] = accounting_.json();
info[jss::uptime] = UptimeTimer::getInstance ().getElapsedSeconds ();
info[jss::jq_trans_overflow] = app_.overlay().getJqTransOverflow();
info[jss::peer_disconnects] = app_.overlay().getPeerDisconnect();
info[jss::peer_disconnects_resources] =
app_.overlay().getPeerDisconnectCharges();

return info;
}
Expand Down Expand Up @@ -3365,7 +3369,7 @@ Json::Value NetworkOPsImp::StateAccounting::json() const
ret[states_[i]] = Json::objectValue;
auto& state = ret[states_[i]];
state[jss::transitions] = counters[i].transitions;
state[jss::duration_us] = std::to_string (counters[i].dur.count());
state[jss::duration_us] = counters[i].dur.count();
}

return ret;
Expand Down
21 changes: 20 additions & 1 deletion src/ripple/json/impl/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,24 @@ Value::Value ( UInt value )
value_.uint_ = value;
}

Value::Value ( std::int64_t value )
: type_ ( stringValue )
, allocated_ ( true )
{
std::string str(std::to_string(value));
value_.string_ = valueAllocator ()->duplicateStringValue (
str.c_str (), str.size() );
}

Value::Value ( std::uint64_t value )
: type_ ( stringValue )
, allocated_ ( true )
{
std::string str(std::to_string(value));
value_.string_ = valueAllocator ()->duplicateStringValue (
str.c_str (), str.size() );
}

Value::Value ( double value )
: type_ ( realValue )
{
Expand Down Expand Up @@ -344,7 +362,8 @@ Value::~Value ()

case arrayValue:
case objectValue:
delete value_.map_;
if (value_.map_)
delete value_.map_;
break;

default:
Expand Down
8 changes: 7 additions & 1 deletion src/ripple/json/json_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <map>
#include <string>
#include <vector>
#include <cstdint>

/** \brief JSON (JavaScript Object Notation).
*/
Expand Down Expand Up @@ -214,6 +215,11 @@ class Value
Value ( ValueType type = nullValue );
Value ( Int value );
Value ( UInt value );
// Convert 64bit integers to string. Json integers overflow between 32
// and 64 bits: some large integers cannot be expressed as
// a Json integer therefore.
Value ( std::int64_t value );
Value ( std::uint64_t value );
Value ( double value );
Value ( const char* value );
Value ( const char* beginValue, const char* endValue );
Expand Down Expand Up @@ -385,7 +391,7 @@ class Value
double real_;
bool bool_;
char* string_;
ObjectValues* map_;
ObjectValues* map_ {nullptr};
} value_;
ValueType type_ : 8;
int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
Expand Down
12 changes: 12 additions & 0 deletions src/ripple/overlay/Overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ class Overlay
std::size_t
selectPeers (PeerSet& set, std::size_t limit, std::function<
bool(std::shared_ptr<Peer> const&)> score) = 0;

/** Increment and retrieve counter for transaction job queue overflows. */
virtual void incJqTransOverflow() = 0;
virtual std::uint64_t getJqTransOverflow() const = 0;

/** Increment and retrieve counters for total peer disconnects, and
* disconnects we initiate for excessive resource consumption.
*/
virtual void incPeerDisconnect() = 0;
virtual std::uint64_t getPeerDisconnect() const = 0;
virtual void incPeerDisconnectCharges() = 0;
virtual std::uint64_t getPeerDisconnectCharges() const = 0;
};

struct ScoreHasLedger
Expand Down
39 changes: 39 additions & 0 deletions src/ripple/overlay/impl/OverlayImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class OverlayImpl : public Overlay
Resolver& m_resolver;
std::atomic <Peer::id_t> next_id_;
int timer_count_;
std::atomic <uint64_t> jqTransOverflow_ {0};
std::atomic <uint64_t> peerDisconnects_ {0};
std::atomic <uint64_t> peerDisconnectsCharges_ {0};

//--------------------------------------------------------------------------

Expand Down Expand Up @@ -301,6 +304,42 @@ class OverlayImpl : public Overlay
bool isInbound,
int bytes);

void
incJqTransOverflow() override
{
++jqTransOverflow_;
}

std::uint64_t
getJqTransOverflow() const override
{
return jqTransOverflow_;
}

void
incPeerDisconnect()
{
++peerDisconnects_;
}

std::uint64_t
getPeerDisconnect() const override
{
return peerDisconnects_;
}

void
incPeerDisconnectCharges()
{
++peerDisconnectsCharges_;
}

std::uint64_t
getPeerDisconnectCharges() const override
{
return peerDisconnectsCharges_;
};

private:
std::shared_ptr<Writer>
makeRedirectResponse (PeerFinder::Slot::ptr const& slot,
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/overlay/impl/PeerImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ PeerImp::charge (Resource::Charge const& fee)
usage_.disconnect() && strand_.running_in_this_thread())
{
// Sever the connection
overlay_.incPeerDisconnectCharges();
fail("charge: Resources");
}
}
Expand Down Expand Up @@ -414,6 +415,7 @@ PeerImp::close()
error_code ec;
timer_.cancel(ec);
socket_.close(ec);
overlay_.incPeerDisconnect();
if(m_inbound)
{
JLOG(journal_.debug()) << "Closed";
Expand Down Expand Up @@ -1094,6 +1096,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMTransaction> const& m)
constexpr int max_transactions = 250;
if (app_.getJobQueue().getJobCount(jtTRANSACTION) > max_transactions)
{
overlay_.incJqTransOverflow();
JLOG(p_journal_.info()) << "Transaction queue is full";
}
else if (app_.getLedgerMaster().getValidatedLedgerAge() > 4min)
Expand Down
4 changes: 4 additions & 0 deletions src/ripple/protocol/JsonFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ JSS ( issuer ); // in: RipplePathFind, Subscribe,
// Unsubscribe, BookOffers
// out: paths/Node, STPathSet, STAmount
JSS ( jsonrpc ); // json version
JSS ( jq_trans_overflow ); // JobQueue transaction limit overflow.
JSS ( key ); // out: WalletSeed
JSS ( key_type ); // in/out: WalletPropose, TransactionSign
JSS ( latency ); // out: PeerImp
Expand Down Expand Up @@ -326,6 +327,9 @@ JSS ( peer ); // in: AccountLines
JSS ( peer_authorized ); // out: AccountLines
JSS ( peer_id ); // out: RCLCxPeerPos
JSS ( peers ); // out: InboundLedger, handlers/Peers, Overlay
JSS ( peer_disconnects ); // Severed peer connection counter.
JSS ( peer_disconnects_resources ); // Severed peer connections because of
// excess resource consumption.
JSS ( port ); // in: Connect
JSS ( previous_ledger ); // out: LedgerPropose
JSS ( proof ); // in: BookOffers
Expand Down

0 comments on commit e24689b

Please sign in to comment.