mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Tidy up Resource::Manager (RIPD-362):
* Style improvements * More documentation
This commit is contained in:
committed by
Vinnie Falco
parent
28898031f0
commit
5869902f2c
@@ -36,43 +36,31 @@ Consumer::Consumer (Consumer const& other)
|
||||
: m_logic (other.m_logic)
|
||||
, m_entry (nullptr)
|
||||
{
|
||||
if (m_logic != nullptr)
|
||||
if (m_logic && other.m_entry)
|
||||
{
|
||||
if (other.m_entry != nullptr)
|
||||
{
|
||||
m_entry = other.m_entry;
|
||||
m_logic->acquire (*m_entry);
|
||||
}
|
||||
m_entry = other.m_entry;
|
||||
m_logic->acquire (*m_entry);
|
||||
}
|
||||
}
|
||||
|
||||
Consumer::~Consumer()
|
||||
{
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
m_logic->release (*m_entry);
|
||||
}
|
||||
if (m_logic && m_entry)
|
||||
m_logic->release (*m_entry);
|
||||
}
|
||||
|
||||
Consumer& Consumer::operator= (Consumer const& other)
|
||||
{
|
||||
// remove old ref
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
m_logic->release (*m_entry);
|
||||
}
|
||||
if (m_logic && m_entry)
|
||||
m_logic->release (*m_entry);
|
||||
|
||||
m_logic = other.m_logic;
|
||||
m_entry = other.m_entry;
|
||||
|
||||
|
||||
// add new ref
|
||||
if (m_logic != nullptr)
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
m_logic->acquire (*m_entry);
|
||||
}
|
||||
if (m_logic && m_entry)
|
||||
m_logic->acquire (*m_entry);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -87,7 +75,7 @@ std::string Consumer::to_string () const
|
||||
|
||||
bool Consumer::admin () const
|
||||
{
|
||||
if (m_entry != nullptr)
|
||||
if (m_entry)
|
||||
return m_entry->admin();
|
||||
|
||||
return false;
|
||||
@@ -101,7 +89,11 @@ void Consumer::elevate (std::string const& name)
|
||||
|
||||
Disposition Consumer::disposition() const
|
||||
{
|
||||
return ok;
|
||||
Disposition d = ok;
|
||||
if (m_logic && m_entry)
|
||||
d = m_logic->charge(*m_entry, Charge(0));
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
Disposition Consumer::charge (Charge const& what)
|
||||
|
||||
@@ -28,15 +28,15 @@ typedef beast::abstract_clock <std::chrono::seconds> clock_type;
|
||||
// An entry in the table
|
||||
struct Entry : public beast::List <Entry>::Node
|
||||
{
|
||||
// No default constructor
|
||||
Entry () = delete;
|
||||
|
||||
// Each Entry needs to know what time it is constructed
|
||||
/**
|
||||
@param now Construction time of Entry.
|
||||
*/
|
||||
explicit Entry(clock_type::time_point const now)
|
||||
: refcount (0)
|
||||
, local_balance (now)
|
||||
, remote_balance (0)
|
||||
, disposition (ok)
|
||||
, lastWarningTime (0)
|
||||
, whenExpires (0)
|
||||
{
|
||||
@@ -87,9 +87,6 @@ struct Entry : public beast::List <Entry>::Node
|
||||
// Normalized balance contribution from imports
|
||||
int remote_balance;
|
||||
|
||||
// Disposition
|
||||
Disposition disposition;
|
||||
|
||||
// Time of the last warning
|
||||
clock_type::rep lastWarningTime;
|
||||
|
||||
|
||||
@@ -30,10 +30,9 @@ struct Key
|
||||
beast::IP::Endpoint address;
|
||||
std::string name;
|
||||
|
||||
// No default constructor
|
||||
Key () = delete;
|
||||
|
||||
// Convenience constructors
|
||||
// Constructor for Inbound and Outbound (non-Admin) keys
|
||||
Key (Kind k, beast::IP::Endpoint const& addr)
|
||||
: kind(k)
|
||||
, address(addr)
|
||||
@@ -42,6 +41,7 @@ struct Key
|
||||
assert(kind != kindAdmin);
|
||||
}
|
||||
|
||||
// Constructor for Admin keys
|
||||
Key (Kind k, const std::string& n)
|
||||
: kind(k)
|
||||
, address()
|
||||
|
||||
@@ -113,16 +113,19 @@ public:
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (std::piecewise_construct,
|
||||
std::make_tuple(kindInbound, address.at_port (0)), // Key
|
||||
std::make_tuple(m_clock.now()))); // Entry
|
||||
std::make_tuple (kindInbound, address.at_port (0)), // Key
|
||||
std::make_tuple (m_clock.now()))); // Entry
|
||||
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
if (entry->refcount == 1)
|
||||
{
|
||||
if (! result.second)
|
||||
{
|
||||
state->inactive.erase (
|
||||
state->inactive.iterator_to (*entry));
|
||||
}
|
||||
state->inbound.push_back (*entry);
|
||||
}
|
||||
}
|
||||
@@ -144,8 +147,9 @@ public:
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (std::piecewise_construct,
|
||||
std::make_tuple(kindOutbound, address), // Key
|
||||
std::make_tuple(m_clock.now()))); // Entry
|
||||
std::make_tuple (kindOutbound, address), // Key
|
||||
std::make_tuple (m_clock.now()))); // Entry
|
||||
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
@@ -172,8 +176,9 @@ public:
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (std::piecewise_construct,
|
||||
std::make_tuple(kindAdmin, name),
|
||||
std::make_tuple(m_clock.now())));
|
||||
std::make_tuple (kindAdmin, name), // Key
|
||||
std::make_tuple (m_clock.now()))); // Entry
|
||||
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
@@ -203,8 +208,9 @@ public:
|
||||
SharedState::Access state (m_state);
|
||||
std::pair <Table::iterator, bool> result (
|
||||
state->table.emplace (std::piecewise_construct,
|
||||
std::make_tuple(kindAdmin, name),
|
||||
std::make_tuple(m_clock.now())));
|
||||
std::make_tuple (kindAdmin, name), // Key
|
||||
std::make_tuple (m_clock.now()))); // Entry
|
||||
|
||||
entry = &result.first->second;
|
||||
entry->key = &result.first->first;
|
||||
++entry->refcount;
|
||||
@@ -234,41 +240,38 @@ public:
|
||||
Json::Value ret (Json::objectValue);
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
for (EntryIntrusiveList::iterator iter (state->inbound.begin());
|
||||
iter != state->inbound.end(); ++iter)
|
||||
for (auto& inboundEntry : state->inbound)
|
||||
{
|
||||
int localBalance = iter->local_balance.value (now);
|
||||
if ((localBalance + iter->remote_balance) >= threshold)
|
||||
int localBalance = inboundEntry.local_balance.value (now);
|
||||
if ((localBalance + inboundEntry.remote_balance) >= threshold)
|
||||
{
|
||||
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
|
||||
Json::Value& entry = (ret[inboundEntry.to_string()] = Json::objectValue);
|
||||
entry["local"] = localBalance;
|
||||
entry["remote"] = iter->remote_balance;
|
||||
entry["remote"] = inboundEntry.remote_balance;
|
||||
entry["type"] = "outbound";
|
||||
}
|
||||
|
||||
}
|
||||
for (EntryIntrusiveList::iterator iter (state->outbound.begin());
|
||||
iter != state->outbound.end(); ++iter)
|
||||
for (auto& outboundEntry : state->outbound)
|
||||
{
|
||||
int localBalance = iter->local_balance.value (now);
|
||||
if ((localBalance + iter->remote_balance) >= threshold)
|
||||
int localBalance = outboundEntry.local_balance.value (now);
|
||||
if ((localBalance + outboundEntry.remote_balance) >= threshold)
|
||||
{
|
||||
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
|
||||
Json::Value& entry = (ret[outboundEntry.to_string()] = Json::objectValue);
|
||||
entry["local"] = localBalance;
|
||||
entry["remote"] = iter->remote_balance;
|
||||
entry["remote"] = outboundEntry.remote_balance;
|
||||
entry["type"] = "outbound";
|
||||
}
|
||||
|
||||
}
|
||||
for (EntryIntrusiveList::iterator iter (state->admin.begin());
|
||||
iter != state->admin.end(); ++iter)
|
||||
for (auto& adminEntry : state->admin)
|
||||
{
|
||||
int localBalance = iter->local_balance.value (now);
|
||||
if ((localBalance + iter->remote_balance) >= threshold)
|
||||
int localBalance = adminEntry.local_balance.value (now);
|
||||
if ((localBalance + adminEntry.remote_balance) >= threshold)
|
||||
{
|
||||
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
|
||||
Json::Value& entry = (ret[adminEntry.to_string()] = Json::objectValue);
|
||||
entry["local"] = localBalance;
|
||||
entry["remote"] = iter->remote_balance;
|
||||
entry["remote"] = adminEntry.remote_balance;
|
||||
entry["type"] = "admin";
|
||||
}
|
||||
|
||||
@@ -286,14 +289,13 @@ public:
|
||||
|
||||
gossip.items.reserve (state->inbound.size());
|
||||
|
||||
for (EntryIntrusiveList::iterator iter (state->inbound.begin());
|
||||
iter != state->inbound.end(); ++iter)
|
||||
for (auto& inboundEntry : state->inbound)
|
||||
{
|
||||
Gossip::Item item;
|
||||
item.balance = iter->local_balance.value (now);
|
||||
item.balance = inboundEntry.local_balance.value (now);
|
||||
if (item.balance >= minimumGossipBalance)
|
||||
{
|
||||
item.address = iter->key->address;
|
||||
item.address = inboundEntry.key->address;
|
||||
gossip.items.push_back (item);
|
||||
}
|
||||
}
|
||||
@@ -311,7 +313,7 @@ public:
|
||||
std::pair <Imports::iterator, bool> result (
|
||||
state->import_table.emplace (std::piecewise_construct,
|
||||
std::make_tuple(origin), // Key
|
||||
std::make_tuple(m_clock.elapsed()))); // Import
|
||||
std::make_tuple(m_clock.elapsed()))); // Import
|
||||
|
||||
if (result.second)
|
||||
{
|
||||
@@ -319,12 +321,12 @@ public:
|
||||
Import& next (result.first->second);
|
||||
next.whenExpires = elapsed + gossipExpirationSeconds;
|
||||
next.items.reserve (gossip.items.size());
|
||||
for (std::vector <Gossip::Item>::const_iterator iter (gossip.items.begin());
|
||||
iter != gossip.items.end(); ++iter)
|
||||
|
||||
for (auto const& gossipItem : gossip.items)
|
||||
{
|
||||
Import::Item item;
|
||||
item.balance = iter->balance;
|
||||
item.consumer = newInboundEndpoint (iter->address);
|
||||
item.balance = gossipItem.balance;
|
||||
item.consumer = newInboundEndpoint (gossipItem.address);
|
||||
item.consumer.entry().remote_balance += item.balance;
|
||||
next.items.push_back (item);
|
||||
}
|
||||
@@ -337,21 +339,19 @@ public:
|
||||
Import next;
|
||||
next.whenExpires = elapsed + gossipExpirationSeconds;
|
||||
next.items.reserve (gossip.items.size());
|
||||
for (std::vector <Gossip::Item>::const_iterator iter (gossip.items.begin());
|
||||
iter != gossip.items.end(); ++iter)
|
||||
for (auto const& gossipItem : gossip.items)
|
||||
{
|
||||
Import::Item item;
|
||||
item.balance = iter->balance;
|
||||
item.consumer = newInboundEndpoint (iter->address);
|
||||
item.balance = gossipItem.balance;
|
||||
item.consumer = newInboundEndpoint (gossipItem.address);
|
||||
item.consumer.entry().remote_balance += item.balance;
|
||||
next.items.push_back (item);
|
||||
}
|
||||
|
||||
Import& prev (result.first->second);
|
||||
for (std::vector <Import::Item>::iterator iter (prev.items.begin());
|
||||
iter != prev.items.end(); ++iter)
|
||||
for (auto& item : prev.items)
|
||||
{
|
||||
iter->consumer.entry().remote_balance -= iter->balance;
|
||||
item.consumer.entry().remote_balance -= item.balance;
|
||||
}
|
||||
|
||||
std::swap (next, prev);
|
||||
@@ -377,8 +377,7 @@ public:
|
||||
|
||||
clock_type::rep const elapsed (m_clock.elapsed());
|
||||
|
||||
for (EntryIntrusiveList::iterator iter (
|
||||
state->inactive.begin()); iter != state->inactive.end();)
|
||||
for (auto iter (state->inactive.begin()); iter != state->inactive.end();)
|
||||
{
|
||||
if (iter->whenExpires <= elapsed)
|
||||
{
|
||||
@@ -400,7 +399,7 @@ public:
|
||||
Import& import (iter->second);
|
||||
if (iter->second.whenExpires <= elapsed)
|
||||
{
|
||||
for (std::vector <Import::Item>::iterator item_iter (import.items.begin());
|
||||
for (auto item_iter (import.items.begin());
|
||||
item_iter != import.items.end(); ++item_iter)
|
||||
{
|
||||
item_iter->consumer.entry().remote_balance -= item_iter->balance;
|
||||
@@ -506,13 +505,21 @@ public:
|
||||
{
|
||||
bool drop (false);
|
||||
clock_type::time_point const now (m_clock.now());
|
||||
if (entry.balance (now) >= dropThreshold)
|
||||
int const balance (entry.balance (now));
|
||||
if (balance >= dropThreshold)
|
||||
{
|
||||
m_journal.warning <<
|
||||
"Consumer entry " << entry <<
|
||||
" dropped with balance " << balance <<
|
||||
" at or above drop threshold " << dropThreshold;
|
||||
|
||||
// Adding feeDrop at this point keeps the dropped connection
|
||||
// from re-connecting for at least a little while after it is
|
||||
// dropped.
|
||||
charge (entry, feeDrop, state);
|
||||
++m_stats.drop;
|
||||
drop = true;
|
||||
}
|
||||
if (drop)
|
||||
++m_stats.drop;
|
||||
return drop;
|
||||
}
|
||||
|
||||
@@ -572,16 +579,15 @@ public:
|
||||
beast::PropertyStream::Set& items,
|
||||
EntryIntrusiveList& list)
|
||||
{
|
||||
for (EntryIntrusiveList::iterator iter (list.begin());
|
||||
iter != list.end(); ++iter)
|
||||
for (auto& entry : list)
|
||||
{
|
||||
beast::PropertyStream::Map item (items);
|
||||
if (iter->refcount != 0)
|
||||
item ["count"] = iter->refcount;
|
||||
item ["name"] = iter->to_string();
|
||||
item ["balance"] = iter->balance(now);
|
||||
if (iter->remote_balance != 0)
|
||||
item ["remote_balance"] = iter->remote_balance;
|
||||
if (entry.refcount != 0)
|
||||
item ["count"] = entry.refcount;
|
||||
item ["name"] = entry.to_string();
|
||||
item ["balance"] = entry.balance(now);
|
||||
if (entry.remote_balance != 0)
|
||||
item ["remote_balance"] = entry.remote_balance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,12 +87,13 @@ public:
|
||||
Charge const fee (dropThreshold + 1);
|
||||
beast::IP::Endpoint const addr (
|
||||
beast::IP::Endpoint::from_string ("207.127.82.2"));
|
||||
|
||||
|
||||
{
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
|
||||
// Create load until we get a warning
|
||||
for (std::size_t n (maxLoopCount); true; --n)
|
||||
std::size_t n (maxLoopCount);
|
||||
while (--n > 0)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
@@ -109,7 +110,7 @@ public:
|
||||
}
|
||||
|
||||
// Create load until we get dropped
|
||||
for (std::size_t n (maxLoopCount); true; --n)
|
||||
while (--n > 0)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
@@ -119,34 +120,49 @@ public:
|
||||
|
||||
if (c.charge (fee) == drop)
|
||||
{
|
||||
pass ();
|
||||
// Disconnect abusive Consumer
|
||||
expect (c.disconnect ());
|
||||
break;
|
||||
}
|
||||
++logic.clock ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Make sure the consumer is on the blacklist for a while.
|
||||
{
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
expect (c.disconnect ());
|
||||
}
|
||||
|
||||
for (std::size_t n (maxLoopCount); true; --n)
|
||||
{
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
if (n == 0)
|
||||
logic.periodicActivity();
|
||||
if (c.disposition () != drop)
|
||||
{
|
||||
fail ("Loop count exceeded without expiring black list");
|
||||
fail ("Dropped consumer not put on blacklist");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (c.disposition() != drop)
|
||||
// Makes sure the Consumer is eventually removed from blacklist
|
||||
bool readmitted = false;
|
||||
{
|
||||
// Give Consumer time to become readmitted. Should never
|
||||
// exceed expiration time.
|
||||
std::size_t n (secondsUntilExpiration + 1);
|
||||
while (--n > 0)
|
||||
{
|
||||
pass ();
|
||||
break;
|
||||
++logic.clock ();
|
||||
logic.periodicActivity();
|
||||
Consumer c (logic.newInboundEndpoint (addr));
|
||||
if (c.disposition () != drop)
|
||||
{
|
||||
readmitted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (readmitted == false)
|
||||
{
|
||||
fail ("Dropped Consumer left on blacklist too long");
|
||||
return;
|
||||
}
|
||||
pass();
|
||||
}
|
||||
|
||||
void testImports (beast::Journal j)
|
||||
|
||||
Reference in New Issue
Block a user