Tidy up Resource::Manager (RIPD-362):

* Style improvements
* More documentation
This commit is contained in:
Scott Schurr
2014-07-10 16:30:24 -07:00
committed by Vinnie Falco
parent 28898031f0
commit 5869902f2c
7 changed files with 153 additions and 133 deletions

View File

@@ -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)

View File

@@ -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;

View File

@@ -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()

View File

@@ -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;
}
}

View File

@@ -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)