Add RPCService, call the Manager from RPCServerHandler

This commit is contained in:
Vinnie Falco
2013-09-21 16:57:36 -07:00
parent be1cede458
commit e59293ec92
15 changed files with 474 additions and 46 deletions

View File

@@ -30,6 +30,11 @@ public:
//m_map.reserve (expectedSize);
}
MapType const& map() const
{
return m_map;
}
std::size_t size () const noexcept
{
return m_map.size ();

View File

@@ -33,8 +33,6 @@ enum
class Logic
{
public:
//----------------------------------------------------------------------
// Information associated with each distinguishable validator
//
struct ValidatorInfo
@@ -50,6 +48,20 @@ public:
typedef boost::unordered_map <
PublicKey, ValidatorInfo, PublicKey::HashFunction> MapType;
struct State
{
MapType map;
SourcesType sources;
};
typedef SharedData <State> SharedState;
Store& m_store;
Journal m_journal;
bool m_rebuildChosenList;
ChosenList::Ptr m_chosenList;
SharedState m_state;
//----------------------------------------------------------------------
Logic (Store& store, Journal journal = Journal ())
@@ -77,9 +89,10 @@ public:
Source::Result result (object->fetch (cancelCallback, m_journal));
SharedState::Access state (m_state);
if (result.success)
{
merge (result.list);
merge (result.list, state);
}
else
{
@@ -92,23 +105,22 @@ public:
void add (Source* source)
{
m_journal.info << "Add Source, " << source->name();
SourceDesc& desc (*m_sources.emplace_back ());
SharedState::Access state (m_state);
SourceDesc& desc (*state->sources.emplace_back ());
desc.source = source;
m_store.insert (desc);
}
// Add each entry in the list to the map, incrementing the
// reference count if it already exists, and updating fields.
//
void merge (Array <Source::Info> const& list)
void merge (Array <Source::Info> const& list, SharedState::Access& state)
{
for (std::size_t i = 0; i < list.size (); ++i)
{
Source::Info const& info (list.getReference (i));
std::pair <MapType::iterator, bool> result (
m_map.emplace (info.publicKey, ValidatorInfo ()));
state->map.emplace (info.publicKey, ValidatorInfo ()));
ValidatorInfo& validatorInfo (result.first->second);
++validatorInfo.refCount;
if (result.second)
@@ -122,18 +134,18 @@ public:
// Decrement the reference count of each item in the list
// in the map.
//
void remove (Array <Source::Info> const& list)
void remove (Array <Source::Info> const& list, SharedState::Access& state)
{
for (std::size_t i = 0; i < list.size (); ++i)
{
Source::Info const& info (list.getReference (i));
MapType::iterator iter (m_map.find (info.publicKey));
bassert (iter != m_map.end ());
MapType::iterator iter (state->map.find (info.publicKey));
bassert (iter != state->map.end ());
ValidatorInfo& validatorInfo (iter->second);
if (--validatorInfo.refCount == 0)
{
// Last reference removed
m_map.erase (iter);
state->map.erase (iter);
dirtyChosen ();
}
}
@@ -147,10 +159,11 @@ public:
/** Rebuild the Chosen List. */
void buildChosen ()
{
ChosenList::Ptr list (new ChosenList (m_map.size ()));
SharedState::ConstAccess state (m_state);
ChosenList::Ptr list (new ChosenList (state->map.size ()));
for (MapType::iterator iter = m_map.begin ();
iter != m_map.end (); ++iter)
for (MapType::const_iterator iter = state->map.begin ();
iter != state->map.end (); ++iter)
{
ChosenList::Info info;
list->insert (iter->first, info);
@@ -208,14 +221,16 @@ public:
if (result.success)
{
SharedState::Access state (m_state);
// Add the new source info to the map
merge (result.list);
merge (result.list, state);
// Swap lists
desc.result.swapWith (result);
// Remove the old source info from the map
remove (result.list);
remove (result.list, state);
// See if we need to rebuild
checkChosen ();
@@ -239,10 +254,10 @@ public:
}
/** Expire a source's list of validators. */
void expire (SourceDesc& desc)
void expire (SourceDesc& desc, SharedState::Access& state)
{
// Decrement reference count on each validator
remove (desc.result.list);
remove (desc.result.list, state);
m_store.update (desc);
}
@@ -254,8 +269,10 @@ public:
{
bool interrupted (false);
Time const currentTime (Time::getCurrentTime ());
for (SourcesType::iterator iter = m_sources.begin ();
iter != m_sources.end (); ++iter)
SharedState::Access state (m_state);
for (SourcesType::iterator iter = state->sources.begin ();
iter != state->sources.end (); ++iter)
{
SourceDesc& desc (*iter);
@@ -276,13 +293,54 @@ public:
if (desc.expirationTime.isNotNull () &&
desc.expirationTime <= currentTime)
{
expire (desc);
expire (desc, state);
}
}
return interrupted;
}
//----------------------------------------------------------------------
//
// RPC Handlers
//
// Return the current ChosenList as JSON
Json::Value rpcPrint (Json::Value const& args)
{
Json::Value result;
ChosenList::Ptr list (m_chosenList);
if (! list.empty())
{
Json::Value entries (result["chosen_list"]);
std::size_t i (1);
for (ChosenList::MapType::const_iterator iter (list->map().begin());
iter != list->map().end(); ++iter)
{
ChosenList::MapType::key_type const& key (iter->first);
ChosenList::MapType::mapped_type const& value (iter->second);
entries[i] = i;
++i;
}
}
else
{
result ["chosen_list"] = "empty";
}
return result;
}
// Returns the list of sources
Json::Value rpcSources (Json::Value const& arg)
{
Json::Value result;
Json::Value sources (result ["validators_sources"]);
return result;
}
//----------------------------------------------------------------------
//
// Ripple interface
@@ -293,8 +351,8 @@ public:
void receiveValidation (ReceivedValidation const& rv)
{
#if 0
MapType::iterator iter (m_map.find (rv.signerPublicKeyHash));
if (iter != m_map.end ())
MapType::iterator iter (state->map.find (rv.signerPublicKeyHash));
if (iter != state->map.end ())
{
// Exists
//ValidatorInfo& validatorInfo (iter->value ());
@@ -302,7 +360,7 @@ public:
else
{
// New
//ValidatorInfo& validatorInfo (m_map.insert (rv.signerPublicKeyHash));
//ValidatorInfo& validatorInfo (state->map.insert (rv.signerPublicKeyHash));
}
#endif
}
@@ -317,14 +375,6 @@ public:
//
//
//----------------------------------------------------------------------
private:
Store& m_store;
Journal m_journal;
SourcesType m_sources;
MapType m_map;
bool m_rebuildChosenList;
ChosenList::Ptr m_chosenList;
};
}

View File

@@ -108,6 +108,7 @@ public:
, m_checkTimer (this)
, m_checkSources (true) // true to cause a full scan on start
{
addRPCHandlers();
m_thread.start (this);
}
@@ -126,6 +127,41 @@ public:
m_thread.stop (false);
}
//--------------------------------------------------------------------------
//
// RPCService
//
Json::Value rpcPrint (Json::Value const& args)
{
return m_logic.rpcPrint (args);
}
Json::Value rpcRebuild (Json::Value const& args)
{
m_thread.call (&Logic::dirtyChosen, &m_logic);
Json::Value result;
result ["chosen_list"] = "rebuilding";
return result;
}
Json::Value rpcSources (Json::Value const& args)
{
return m_logic.rpcSources(args);
}
void addRPCHandlers()
{
addRPCHandler ("validators_print", beast::bind (
&ManagerImp::rpcPrint, this, beast::_1));
addRPCHandler ("validators_rebuild", beast::bind (
&ManagerImp::rpcRebuild, this, beast::_1));
addRPCHandler ("validators_sources", beast::bind (
&ManagerImp::rpcSources, this, beast::_1));
}
//--------------------------------------------------------------------------
void addStrings (String name, std::vector <std::string> const& strings)
@@ -267,9 +303,9 @@ private:
//------------------------------------------------------------------------------
Manager* Manager::New (Service& parent, Journal journal)
Validators::Manager* Validators::Manager::New (Service& parent, Journal journal)
{
return new ManagerImp (parent, journal);
return new Validators::ManagerImp (parent, journal);
}
}