Add PropertyStream

This commit is contained in:
Vinnie Falco
2013-10-06 11:07:25 -07:00
parent b9e0208aee
commit 1ae3328642
24 changed files with 839 additions and 157 deletions

View File

@@ -1621,6 +1621,7 @@
<ClInclude Include="..\..\src\ripple\http\impl\ServerImpl.h" />
<ClInclude Include="..\..\src\ripple\http\impl\Types.h" />
<ClInclude Include="..\..\src\ripple\http\ripple_http.h" />
<ClInclude Include="..\..\src\ripple\json\api\JsonPropertyStreamSink.h" />
<ClInclude Include="..\..\src\ripple\json\api\json_config.h" />
<ClInclude Include="..\..\src\ripple\json\api\json_features.h" />
<ClInclude Include="..\..\src\ripple\json\api\json_forwards.h" />

View File

@@ -2214,6 +2214,9 @@
<ClInclude Include="..\..\src\ripple\peerfinder\impl\CachedEndpoint.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\json\api\JsonPropertyStreamSink.h">
<Filter>[1] Ripple\json\api</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">

View File

@@ -184,6 +184,7 @@
<ClInclude Include="..\..\beast\utility\Error.h" />
<ClInclude Include="..\..\beast\utility\Journal.h" />
<ClInclude Include="..\..\beast\utility\LeakChecked.h" />
<ClInclude Include="..\..\beast\utility\PropertyStream.h" />
<ClInclude Include="..\..\beast\utility\StaticObject.h" />
<ClInclude Include="..\..\beast\Version.h" />
<ClInclude Include="..\..\config\BeastConfig.h" />
@@ -569,6 +570,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\utility\impl\PropertyStream.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\utility\impl\StaticObject.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>

View File

@@ -1245,6 +1245,9 @@
<ClInclude Include="..\..\beast\Boost.h">
<Filter>beast</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\utility\PropertyStream.h">
<Filter>beast\utility</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
@@ -1793,6 +1796,9 @@
<ClCompile Include="..\..\beast\boost\Boost.cpp">
<Filter>beast\boost</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\utility\impl\PropertyStream.cpp">
<Filter>beast\utility\impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\TODO.txt">

View File

@@ -25,6 +25,7 @@
#include "utility/Error.h"
#include "utility/Journal.h"
#include "utility/LeakChecked.h"
#include "utility/PropertyStream.h"
#include "utility/StaticObject.h"
#endif

View File

@@ -0,0 +1,263 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_UTILITY_PROPERTYSTREAM_H_INCLUDED
#define BEAST_UTILITY_PROPERTYSTREAM_H_INCLUDED
#include "../CStdInt.h"
#include "../Uncopyable.h"
#include "../intrusive/List.h"
#include "../threads/SharedData.h"
#include <string>
namespace beast {
/** An output stream to procedurally generate an abstract property tree. */
class PropertyStream
{
private:
class Proxy;
public:
class ScopedArray;
class ScopedObject;
class Source;
private:
class Item : public List <Item>::Node
{
public:
explicit Item (Source* source);
Source& source() const;
Source* operator-> () const;
Source& operator* () const;
private:
Source* m_source;
};
public:
//--------------------------------------------------------------------------
class Sink : Uncopyable
{
public:
// Object output
//
// Default implementations convert to string
// Json doesn't support 64 bit so we convert these to string
// if they are outside the range of the corresponding 32 bit int
virtual void begin_object (std::string const& key) = 0;
virtual void end_object () = 0;
template <typename Value>
void lexical_write (std::string const &key, Value value)
{
std::stringstream ss;
ss << value;
write (key, ss.str());
}
virtual void write (std::string const& key, int32 value);
virtual void write (std::string const& key, uint32 value);
virtual void write (std::string const& key, int64 value);
virtual void write (std::string const& key, uint64 value);
virtual void write (std::string const& key, std::string const& value) = 0;
// Array output
//
virtual void begin_array (std::string const& key) = 0;
virtual void end_array () = 0;
template <typename Value>
void lexical_write (Value value)
{
std::stringstream ss;
ss << value;
write (ss.str());
}
virtual void write ( int32 value);
virtual void write (uint32 value);
virtual void write ( int64 value);
virtual void write (uint64 value);
virtual void write (std::string const& value) = 0;
};
//--------------------------------------------------------------------------
PropertyStream ();
PropertyStream (Sink& sink);
PropertyStream (PropertyStream const& other);
PropertyStream& operator= (PropertyStream const& other);
/** Object output.
*/
/** @{ */
void begin_object (std::string const& key) const;
void end_object () const;
template <typename Value>
void write (std::string const& key, Value value) const
{
m_sink->write (key, value);
}
template <typename Key, typename Value>
void write (Key key, Value value) const
{
std::stringstream ss;
ss << key;
write (ss.str(), value);
}
Proxy operator[] (std::string const& key) const;
template <typename Key>
Proxy operator[] (Key key) const;
/** @} */
/** Array output.
*/
/** @{ */
void begin_array (std::string const& key) const;
void end_array () const;
template <typename Value>
void append (Value value) const
{ m_sink->write (value); }
template <typename Value>
PropertyStream const& operator<< (Value value) const
{ append (value); return &this; }
/** @} */
private:
static Sink& nullSink();
Sink* m_sink;
};
//------------------------------------------------------------------------------
class PropertyStream::Proxy
{
private:
PropertyStream m_stream;
std::string m_key;
public:
Proxy (PropertyStream stream, std::string const& key);
template <typename Value>
Proxy& operator= (Value value)
{ m_stream.write (m_key, value); return *this; }
};
//------------------------------------------------------------------------------
template <typename Key>
PropertyStream::Proxy PropertyStream::operator[] (Key key) const
{
std::stringstream ss;
ss << key;
return operator[] (ss.str());
}
//------------------------------------------------------------------------------
class PropertyStream::ScopedObject
{
private:
PropertyStream m_stream;
public:
ScopedObject (std::string const& key, PropertyStream stream);
~ScopedObject ();
};
//------------------------------------------------------------------------------
class PropertyStream::ScopedArray
{
private:
PropertyStream m_stream;
public:
ScopedArray (std::string const& key, PropertyStream stream);
~ScopedArray ();
};
//------------------------------------------------------------------------------
/** Subclasses can be called to write to a stream and have children. */
class PropertyStream::Source : public Uncopyable
{
private:
struct State
{
explicit State (Source* source)
: item (source)
, parent (nullptr)
{ }
Item item;
Source* parent;
List <Item> children;
};
typedef SharedData <State> SharedState;
std::string const m_name;
SharedState m_state;
void remove (SharedState::Access& state, SharedState::Access& childState);
void removeAll (SharedState::Access& state);
public:
explicit Source (std::string const& name);
~Source ();
/** Add a child source. */
void add (Source& source);
/** Add a child source by pointer.
This returns the passed source so it can be conveniently chained
in ctor-initializer lists.
*/
template <class Derived>
Derived* add (Derived* child)
{
add (*static_cast <Source*>(child));
return child;
}
/** Remove a child source. */
void remove (Source& child);
/** Remove all child sources. */
void removeAll ();
void write (PropertyStream stream, bool includeChildren);
void write (std::string const& path, PropertyStream stream);
virtual void onWrite (PropertyStream) { }
};
//------------------------------------------------------------------------------
}
#endif

View File

@@ -28,3 +28,4 @@
#include "impl/Journal.cpp"
#include "impl/LeakChecked.cpp"
#include "impl/StaticObject.cpp"
#include "impl/PropertyStream.cpp"

View File

@@ -0,0 +1,341 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../PropertyStream.h"
#include <limits>
namespace beast {
PropertyStream::Item::Item (Source* source)
: m_source (source)
{
}
PropertyStream::Source& PropertyStream::Item::source() const
{
return *m_source;
}
PropertyStream::Source* PropertyStream::Item::operator-> () const
{
return &source();
}
PropertyStream::Source& PropertyStream::Item::operator* () const
{
return source();
}
//------------------------------------------------------------------------------
void PropertyStream::Sink::write (std::string const& key, int32 value)
{
lexical_write (key, value);
}
void PropertyStream::Sink::write (std::string const& key, uint32 value)
{
lexical_write (key, value);
}
void PropertyStream::Sink::write (std::string const& key, int64 value)
{
if (value <= std::numeric_limits <int32>::max() &&
value >= std::numeric_limits <int32>::min())
{
write (key, int32(value));
}
else
{
lexical_write (key, value);
}
}
void PropertyStream::Sink::write (std::string const& key, uint64 value)
{
if (value <= std::numeric_limits <uint32>::max() &&
value >= std::numeric_limits <uint32>::min())
{
write (key, uint32(value));
}
else
{
lexical_write (key, value);
}
}
void PropertyStream::Sink::write (int32 value)
{
lexical_write (value);
}
void PropertyStream::Sink::write (uint32 value)
{
lexical_write (value);
}
void PropertyStream::Sink::write (int64 value)
{
if (value <= std::numeric_limits <int32>::max() &&
value >= std::numeric_limits <int32>::min())
{
write (int32(value));
}
else
{
lexical_write (value);
}
}
void PropertyStream::Sink::write (uint64 value)
{
if (value <= std::numeric_limits <uint32>::max() &&
value >= std::numeric_limits <uint32>::min())
{
write (uint32(value));
}
else
{
lexical_write (value);
}
}
//------------------------------------------------------------------------------
PropertyStream::Proxy::Proxy (PropertyStream stream, std::string const& key)
: m_stream (stream)
, m_key (key)
{
}
//------------------------------------------------------------------------------
PropertyStream::ScopedObject::ScopedObject (std::string const& key, PropertyStream stream)
: m_stream (stream)
{
m_stream.begin_object (key);
}
PropertyStream::ScopedObject::~ScopedObject ()
{
m_stream.end_object ();
}
//------------------------------------------------------------------------------
PropertyStream::Source::Source (std::string const& name)
: m_name (name)
, m_state (this)
{
}
PropertyStream::Source::~Source ()
{
SharedState::Access state (m_state);
if (state->parent != nullptr)
state->parent->remove (*this);
removeAll (state);
}
void PropertyStream::Source::remove (
SharedState::Access& state, SharedState::Access& childState)
{
bassert (childState->parent == this);
state->children.erase (
state->children.iterator_to (
childState->item));
childState->parent = nullptr;
}
void PropertyStream::Source::removeAll (SharedState::Access& state)
{
for (List <Item>::iterator iter (state->children.begin());
iter != state->children.end();)
{
SharedState::Access childState ((*iter)->m_state);
remove (state, childState);
}
}
void PropertyStream::Source::add (Source& source)
{
SharedState::Access state (m_state);
SharedState::Access childState (source.m_state);
bassert (childState->parent == nullptr);
state->children.push_back (childState->item);
childState->parent = this;
}
void PropertyStream::Source::remove (Source& child)
{
SharedState::Access state (m_state);
SharedState::Access childState (child.m_state);
remove (state, childState);
}
void PropertyStream::Source::removeAll ()
{
SharedState::Access state (m_state);
removeAll (state);
}
void PropertyStream::Source::write (PropertyStream stream, bool includeChildren)
{
ScopedObject child (m_name, stream);
onWrite (stream);
if (includeChildren)
{
SharedState::Access state (m_state);
for (List <Item>::iterator iter (state->children.begin());
iter != state->children.end(); ++iter)
{
(*iter)->write (stream, true);
}
}
}
void PropertyStream::Source::write (std::string const& path, PropertyStream stream)
{
struct Parser
{
Parser (std::string const& path)
: m_first (path.begin())
, m_last (path.end())
{
}
std::string next ()
{
std::string::const_iterator pos (
std::find (m_first, m_last, '.'));
std::string const s (m_first, pos);
if (pos != m_last)
m_first = pos + 1;
else
m_first = pos;
return s;
}
std::string::const_iterator m_first;
std::string::const_iterator m_last;
};
//-----------------------------------------
if (path.empty ())
{
write (stream, true);
return;
}
Parser p (path);
Source* source (this);
if (p.next() != source->m_name)
return;
for (;;)
{
std::string const s (p.next());
if (s.empty())
{
source->write (stream, false);
break;
}
else if (s == "*")
{
source->write (stream, true);
break;
}
else
{
SharedState::Access state (source->m_state);
for (List <Item>::iterator iter (state->children.begin());;)
{
if (iter->source().m_name == s)
{
source = &iter->source();
break;
}
if (++iter == state->children.end())
return;
}
}
}
}
//------------------------------------------------------------------------------
PropertyStream::PropertyStream ()
: m_sink (&nullSink())
{
}
PropertyStream::PropertyStream (Sink& sink)
: m_sink (&sink)
{
}
PropertyStream::PropertyStream (PropertyStream const& other)
: m_sink (other.m_sink)
{
}
PropertyStream& PropertyStream::operator= (PropertyStream const& other)
{
m_sink = other.m_sink;
return *this;
}
PropertyStream::Proxy PropertyStream::operator[] (std::string const& key) const
{
return Proxy (*this, key);
}
void PropertyStream::begin_object (std::string const& key) const
{
m_sink->begin_object (key);
}
void PropertyStream::end_object () const
{
m_sink->end_object ();
}
PropertyStream::Sink& PropertyStream::nullSink()
{
struct NullSink : Sink
{
void begin_object (std::string const&) { }
void end_object () { }
void write (std::string const&, std::string const&) { }
void begin_array (std::string const&) { }
void end_array () { }
void write (std::string const&) { }
};
static NullSink sink;
return sink;
}
}

View File

@@ -0,0 +1,97 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_JSONPROPERTYSTREAMSINK_H_INCLUDED
#define RIPPLE_JSONPROPERTYSTREAMSINK_H_INCLUDED
#include "beast/beast/utility/PropertyStream.h"
//#include "json_value.h" // ??
namespace ripple {
using namespace beast;
/** A PropertyStream::Sink which produces a Json::Value. */
class JsonPropertyStreamSink : public PropertyStream::Sink
{
public:
explicit JsonPropertyStreamSink (Json::Value& root)
{
m_stack.push_back (&root);
}
void begin_object (std::string const& key)
{
m_stack.push_back (&((*m_stack.back())[key] = Json::objectValue));
}
void end_object ()
{
m_stack.pop_back ();
}
void write (std::string const& key, int32 v)
{
(*m_stack.back())[key] = v;
}
void write (std::string const& key, uint32 v)
{
(*m_stack.back())[key] = v;
}
void write (std::string const& key, std::string const& v)
{
(*m_stack.back())[key] = v;
}
void begin_array (std::string const& key)
{
m_stack.push_back (&((*m_stack.back())[key] = Json::arrayValue));
}
void end_array ()
{
m_stack.pop_back ();
}
void write (int32 v)
{
m_stack.back()->append (v);
}
void write (uint32 v)
{
m_stack.back()->append (v);
}
void write (std::string const& v)
{
m_stack.back()->append (v);
}
private:
Json::Value m_value;
std::vector <Json::Value*> m_stack;
};
}
#endif

View File

@@ -17,7 +17,6 @@
*/
//==============================================================================
#ifndef RIPPLE_JSON_H_INCLUDED
#define RIPPLE_JSON_H_INCLUDED
@@ -46,4 +45,6 @@
#include "api/json_reader.h"
#include "api/json_writer.h"
#include "api/JsonPropertyStreamSink.h"
#endif

View File

@@ -24,7 +24,9 @@ namespace ripple {
namespace PeerFinder {
/** Maintains a set of IP addresses used for getting into the network. */
class Manager : public Stoppable
class Manager
: public Stoppable
, public PropertyStream::Source
{
protected:
explicit Manager (Stoppable& parent);

View File

@@ -290,6 +290,23 @@ public:
m_queue.dispatch (bind (&Thread::signalThreadShouldExit, this));
}
//--------------------------------------------------------------------------
//
// PropertyStream
//
void onWrite (PropertyStream stream)
{
stream ["peers"] = m_logic.m_slots.peerCount;
stream ["in"] = m_logic.m_slots.inboundCount;
stream ["out"] = m_logic.m_slots.outboundCount;
stream ["out_desired"] = m_logic.m_slots.outDesired;
stream ["in_avail"] = m_logic.m_slots.inboundSlots;
stream ["in_max"] = m_logic.m_slots.inboundSlotsMaximum;
stream ["minutes"] = m_logic.m_slots.uptimeMinutes();
stream ["round"] = m_logic.m_slots.roundUpwards();
}
//--------------------------------------------------------------------------
void onDeadlineTimer (DeadlineTimer& timer)
@@ -358,7 +375,8 @@ public:
//------------------------------------------------------------------------------
Manager::Manager (Stoppable& parent)
: Stoppable ("PeerFinder", parent)
: PropertyStream::Source ("peerfinder")
, Stoppable ("PeerFinder", parent)
{
}

View File

@@ -63,7 +63,7 @@ void Slots::update (Config const& config)
void Slots::addPeer (Config const& config, bool inbound)
{
if (peerCount == 0)
startTime = Time::getCurrentTime();
startTime = RelativeTime::fromStartup();
++peerCount;
if (inbound)
@@ -83,15 +83,15 @@ void Slots::dropPeer (Config const& config, bool inbound)
--outboundCount;
if (peerCount == 0)
startTime = Time (0);
startTime = RelativeTime(0);
update (config);
}
uint32 Slots::uptimeMinutes () const
{
if (startTime.isNotNull())
return (Time::getCurrentTime()-startTime).inMinutes();
if (startTime.isNotZero())
return (RelativeTime::fromStartup()-startTime).inMinutes();
return 0;
}

View File

@@ -31,10 +31,9 @@ public:
void update (Config const& config);
void addPeer (Config const& config, bool inbound);
void dropPeer (Config const& config, bool inbound);
uint32 uptimeMinutes () const;
// Most recent time when we went from 0 to 1 peers
Time startTime;
RelativeTime startTime;
// Current total of connected peers that have HELLOed
int peerCount;
@@ -54,6 +53,16 @@ public:
// The maximum number of incoming slots (calculated)
int inboundSlotsMaximum;
// Returns the uptime in minutes
// Uptime is measured from the last we transitioned from not
// being connected to the network, to being connected.
//
uint32 uptimeMinutes () const;
// Returns `true` if we round fractional slot availability upwards
bool roundUpwards () const
{ return m_roundUpwards; }
private:
bool m_roundUpwards;
};

View File

@@ -28,14 +28,17 @@ namespace Validators {
the list of chosen validators is critical to the health of the network.
All operations are performed asynchronously on an internal thread.
*/
class Manager : public RPC::Service
class Manager : public PropertyStream::Source
{
protected:
Manager();
public:
/** Create a new Manager object.
@param parent The parent Stoppable.
@param journal Where to send log output.
*/
static Manager* New (Stoppable& parent, Journal journal);
static Manager* New (Stoppable& stoppableParent, Journal journal);
/** Destroy the object.
Any pending source fetch operations are aborted. This will block
@@ -59,7 +62,7 @@ public:
virtual void addStrings (String name,
StringArray const& stringArray) = 0;
virtual void addFile (File const& file) = 0;
virtual void addStaticSource (Source* source) = 0;
virtual void addStaticSource (Validators::Source* source) = 0;
/** @} */
/** Add a live source of validators from a trusted URL.
@@ -76,7 +79,7 @@ public:
Thread safety:
Can be called from any thread.
*/
virtual void addSource (Source* source) = 0;
virtual void addSource (Validators::Source* source) = 0;
//--------------------------------------------------------------------------

View File

@@ -406,72 +406,6 @@ public:
return n;
}
//----------------------------------------------------------------------
//
// RPC Handlers
//
// Return the current ChosenList as JSON
Json::Value rpcPrint (Json::Value const& args, int cpuPercent)
{
Json::Value results (Json::objectValue);
Json::Value entries (Json::arrayValue);
{
results ["cpu"] = cpuPercent;
results ["count"] = int(m_validators.size());
for (ValidatorTable::const_iterator iter (m_validators.begin());
iter != m_validators.end(); ++iter)
{
Validator const& v (iter->second);
Json::Value entry (Json::objectValue);
Count const count (v.count ());
entry ["public"] = iter->first.to_string();
entry ["received"] = int(count.received);
entry ["expected"] = int(count.expected);
entry ["closed"] = int(count.closed);
entry ["percent"] = count.percent();
entries.append (entry);
}
}
results ["validators"] = entries;
return results;
}
// Returns the list of sources
Json::Value rpcSources (Json::Value const& arg)
{
Json::Value results (Json::objectValue);
Json::Value entries (Json::arrayValue);
for (SourceTable::const_iterator iter (m_sources.begin());
iter != m_sources.end(); ++iter)
{
Json::Value entry (Json::objectValue);
SourceDesc const& desc (*iter);
entry ["name"] = desc.source->name();
entry ["param"] = desc.source->createParam();
Json::Value results (Json::arrayValue);
for (int i = 0; i < desc.results.list.size(); ++i)
{
Json::Value info (Json::objectValue);
info ["key"] = "publicKey";
info ["label"] = desc.results.list[i].label;
results.append (info);
}
entry ["results"] = results;
entries.append (entry);
}
results ["sources"] = entries;
return results;
}
//----------------------------------------------------------------------
//
// Ripple interface

View File

@@ -167,42 +167,6 @@ public:
stopThread ();
}
//--------------------------------------------------------------------------
//
// RPC::Service
//
Json::Value rpcPrint (Json::Value const& args)
{
int const cpuPercent (std::ceil (m_queue.getUtilizaton() * 100));
return m_logic.rpcPrint (args, cpuPercent);
}
Json::Value rpcRebuild (Json::Value const& args)
{
m_queue.dispatch (bind (&Logic::buildChosen, &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));
}
//--------------------------------------------------------------------------
//
// Manager
@@ -234,7 +198,7 @@ public:
addStaticSource (SourceFile::New (file));
}
void addStaticSource (Source* source)
void addStaticSource (Validators::Source* source)
{
#if RIPPLE_USE_VALIDATORS
m_queue.dispatch (bind (&Logic::addStatic, &m_logic, source));
@@ -248,7 +212,7 @@ public:
addSource (SourceURL::New (url));
}
void addSource (Source* source)
void addSource (Validators::Source* source)
{
#if RIPPLE_USE_VALIDATORS
m_queue.dispatch (bind (&Logic::add, &m_logic, source));
@@ -286,8 +250,6 @@ public:
{
#if RIPPLE_USE_VALIDATORS
m_journal.info << "Validators preparing";
addRPCHandlers();
#endif
}
@@ -402,6 +364,11 @@ public:
//------------------------------------------------------------------------------
Manager::Manager ()
: PropertyStream::Source ("validators")
{
}
Validators::Manager* Validators::Manager::New (Stoppable& parent, Journal journal)
{
return new Validators::ManagerImp (parent, journal);

View File

@@ -117,8 +117,8 @@ public:
, m_txQueue (TxQueue::New ())
, m_validators (Validators::Manager::New (
*this, LogJournal::get <ValidatorsLog> ()))
, m_validators (add (Validators::Manager::New (
*this, LogJournal::get <ValidatorsLog> ())))
, mFeatures (IFeatures::New (2 * 7 * 24 * 60 * 60, 200)) // two weeks, 200/256
@@ -472,7 +472,7 @@ public:
// the creation of the peer SSL context and Peers object into
// the conditional.
//
m_peers = Peers::New (m_mainIoPool, m_mainIoPool, m_peerSSLContext->get ());
m_peers = add (Peers::New (m_mainIoPool, m_mainIoPool, m_peerSSLContext->get ()));
// If we're not in standalone mode,
// prepare ourselves for networking
@@ -642,8 +642,6 @@ public:
void onPrepare ()
{
m_rpcServiceManager->add (*m_validators);
prepareValidators ();
}
@@ -670,7 +668,15 @@ public:
stopped ();
}
//------------------------------------------------------------------------------
//
// PropertyStream
//
void onWrite (PropertyStream stream)
{
}
//------------------------------------------------------------------------------
void run ()
@@ -1201,6 +1207,11 @@ ApplicationImp* ApplicationImp::s_instance;
//------------------------------------------------------------------------------
Application::Application ()
: PropertyStream::Source ("app")
{
}
Application* Application::New ()
{
return new ApplicationImp;

View File

@@ -49,7 +49,7 @@ class DatabaseCon;
typedef TaggedCacheType <uint256, Blob , UptimeTimerAdapter> NodeCache;
typedef TaggedCacheType <uint256, SerializedLedgerEntry, UptimeTimerAdapter> SLECache;
class Application
class Application : public PropertyStream::Source
{
public:
/* VFALCO NOTE
@@ -68,24 +68,11 @@ public:
virtual LockType& getMasterLock () = 0;
public:
struct State
{
// Stuff in here is accessed concurrently and requires a Access
};
typedef SharedData <State> SharedState;
SharedState& getSharedState () noexcept { return m_sharedState; }
SharedState const& getSharedState () const noexcept { return m_sharedState; }
private:
SharedState m_sharedState;
public:
static Application* New ();
Application ();
virtual ~Application () { }
virtual boost::asio::io_service& getIOService () = 0;

View File

@@ -91,8 +91,8 @@ public:
boost::asio::io_service& io_service,
boost::asio::ssl::context& ssl_context)
: Stoppable ("Peers", parent)
, m_peerFinder (PeerFinder::Manager::New (
*this, *this, LogJournal::get <PeerFinderLog> ()))
, m_peerFinder (add (PeerFinder::Manager::New (
*this, *this, LogJournal::get <PeerFinderLog> ())))
, m_io_service (io_service)
, m_ssl_context (ssl_context)
, mPeerLock (this, "PeersImp", __FILE__, __LINE__)
@@ -223,6 +223,15 @@ public:
stopped();
}
//--------------------------------------------------------------------------
//
// PropertyStream
//
void onWrite (PropertyStream stream)
{
}
//--------------------------------------------------------------------------
PeerFinder::Manager& getPeerFinder()
@@ -1078,6 +1087,11 @@ void PeersImp::scanRefresh ()
//------------------------------------------------------------------------------
Peers::Peers ()
: PropertyStream::Source ("peers")
{
}
Peers* Peers::New (Stoppable& parent,
boost::asio::io_service& io_service,
boost::asio::ssl::context& ssl_context)

View File

@@ -25,13 +25,15 @@ class Manager;
}
/** Manages the set of connected peers. */
class Peers
class Peers : public PropertyStream::Source
{
public:
static Peers* New (Stoppable& parent,
boost::asio::io_service& io_service,
boost::asio::ssl::context& context);
Peers ();
virtual ~Peers () { }
virtual PeerFinder::Manager& getPeerFinder() = 0;

View File

@@ -810,6 +810,24 @@ Json::Value RPCHandler::doPing (Json::Value, LoadType* loadType, Application::Sc
return Json::Value (Json::objectValue);
}
Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
{
masterLockHolder.unlock ();
Json::Value result (Json::objectValue);
JsonPropertyStreamSink sink (result);
if (params.isObject() && params["params"].isArray() && params["params"][0u].isString ())
{
getApp().write (params["params"][0u].asString(), sink);
}
else
{
getApp().write (sink, true);
}
return result;
}
// profile offers <pass_a> <account_a> <currency_offer_a> <account_b> <currency_offer_b> <count> [submit]
// profile 0:offers 1:pass_a 2:account_a 3:currency_offer_a 4:account_b 5:currency_offer_b 6:<count> 7:[submit]
// issuer is the offering account
@@ -3822,12 +3840,13 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{ "ledger_header", &RPCHandler::doLedgerHeader, false, optCurrent },
{ "log_level", &RPCHandler::doLogLevel, true, optNone },
{ "logrotate", &RPCHandler::doLogRotate, true, optNone },
// { "nickname_info", &RPCHandler::doNicknameInfo, false, optCurrent },
// { "nickname_info", &RPCHandler::doNicknameInfo, false, optCurrent },
{ "owner_info", &RPCHandler::doOwnerInfo, false, optCurrent },
{ "peers", &RPCHandler::doPeers, true, optNone },
{ "path_find", &RPCHandler::doPathFind, false, optCurrent },
{ "ping", &RPCHandler::doPing, false, optNone },
// { "profile", &RPCHandler::doProfile, false, optCurrent },
{ "print", &RPCHandler::doPrint, true, optNone },
// { "profile", &RPCHandler::doProfile, false, optCurrent },
{ "proof_create", &RPCHandler::doProofCreate, true, optNone },
{ "proof_solve", &RPCHandler::doProofSolve, true, optNone },
{ "proof_verify", &RPCHandler::doProofVerify, true, optNone },
@@ -3842,7 +3861,6 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{ "transaction_entry", &RPCHandler::doTransactionEntry, false, optCurrent },
{ "tx", &RPCHandler::doTx, false, optNetwork },
{ "tx_history", &RPCHandler::doTxHistory, false, optNone },
{ "unl_add", &RPCHandler::doUnlAdd, true, optNone },
{ "unl_delete", &RPCHandler::doUnlDelete, true, optNone },
{ "unl_list", &RPCHandler::doUnlList, true, optNone },
@@ -3850,10 +3868,8 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{ "unl_network", &RPCHandler::doUnlNetwork, true, optNone },
{ "unl_reset", &RPCHandler::doUnlReset, true, optNone },
{ "unl_score", &RPCHandler::doUnlScore, true, optNone },
{ "validation_create", &RPCHandler::doValidationCreate, true, optNone },
{ "validation_seed", &RPCHandler::doValidationSeed, true, optNone },
{ "wallet_accounts", &RPCHandler::doWalletAccounts, false, optCurrent },
{ "wallet_propose", &RPCHandler::doWalletPropose, true, optNone },
{ "wallet_seed", &RPCHandler::doWalletSeed, true, optNone },

View File

@@ -122,6 +122,7 @@ private:
Json::Value doPathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPeers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPing (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProfile (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProofCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
Json::Value doProofSolve (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);

View File

@@ -857,6 +857,7 @@ public:
{ "owner_info", &RPCParser::parseAccountItems, 1, 2 },
{ "peers", &RPCParser::parseAsIs, 0, 0 },
{ "ping", &RPCParser::parseAsIs, 0, 0 },
{ "print", &RPCParser::parseAsIs, 0, 1 },
// { "profile", &RPCParser::parseProfile, 1, 9 },
{ "proof_create", &RPCParser::parseProofCreate, 0, 2 },
{ "proof_solve", &RPCParser::parseProofSolve, 1, 1 },
@@ -873,7 +874,6 @@ public:
{ "tx", &RPCParser::parseTx, 1, 2 },
{ "tx_account", &RPCParser::parseTxAccount, 1, 7 },
{ "tx_history", &RPCParser::parseTxHistory, 1, 1 },
{ "unl_add", &RPCParser::parseUnlAdd, 1, 2 },
{ "unl_delete", &RPCParser::parseUnlDelete, 1, 1 },
{ "unl_list", &RPCParser::parseAsIs, 0, 0 },
@@ -881,14 +881,11 @@ public:
{ "unl_network", &RPCParser::parseAsIs, 0, 0 },
{ "unl_reset", &RPCParser::parseAsIs, 0, 0 },
{ "unl_score", &RPCParser::parseAsIs, 0, 0 },
{ "validation_create", &RPCParser::parseValidationCreate, 0, 1 },
{ "validation_seed", &RPCParser::parseValidationSeed, 0, 1 },
{ "wallet_accounts", &RPCParser::parseWalletAccounts, 1, 1 },
{ "wallet_propose", &RPCParser::parseWalletPropose, 0, 1 },
{ "wallet_seed", &RPCParser::parseWalletSeed, 0, 1 },
{ "internal", &RPCParser::parseInternal, 1, -1 },
#if ENABLE_INSECURE