Implement Stoppable for LoadManager

This commit is contained in:
Vinnie Falco
2013-09-28 17:40:46 -07:00
parent 58a8a97177
commit 00a714d14d
16 changed files with 424 additions and 451 deletions

View File

@@ -908,7 +908,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple_core\functional\LoadFeeTrack.cpp"> <ClCompile Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -1764,11 +1764,11 @@
<ClInclude Include="..\..\src\ripple_core\functional\LoadType.h" /> <ClInclude Include="..\..\src\ripple_core\functional\LoadType.h" />
<ClInclude Include="..\..\src\ripple_core\functional\Config.h" /> <ClInclude Include="..\..\src\ripple_core\functional\Config.h" />
<ClInclude Include="..\..\src\ripple_core\functional\ConfigSections.h" /> <ClInclude Include="..\..\src\ripple_core\functional\ConfigSections.h" />
<ClInclude Include="..\..\src\ripple_core\functional\ILoadFeeTrack.h" /> <ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h" />
<ClInclude Include="..\..\src\ripple_core\functional\Job.h" /> <ClInclude Include="..\..\src\ripple_core\functional\Job.h" />
<ClInclude Include="..\..\src\ripple_core\functional\JobQueue.h" /> <ClInclude Include="..\..\src\ripple_core\functional\JobQueue.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadEvent.h" /> <ClInclude Include="..\..\src\ripple_core\functional\LoadEvent.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h" /> <ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.h" />
<ClInclude Include="..\..\src\ripple_core\functional\LoadMonitor.h" /> <ClInclude Include="..\..\src\ripple_core\functional\LoadMonitor.h" />
<ClInclude Include="..\..\src\ripple_core\nodestore\api\Backend.h" /> <ClInclude Include="..\..\src\ripple_core\nodestore\api\Backend.h" />
<ClInclude Include="..\..\src\ripple_core\nodestore\api\Database.h" /> <ClInclude Include="..\..\src\ripple_core\nodestore\api\Database.h" />

View File

@@ -270,9 +270,6 @@
<ClCompile Include="..\..\src\ripple_core\functional\LoadEvent.cpp"> <ClCompile Include="..\..\src\ripple_core\functional\LoadEvent.cpp">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple_core\functional\LoadFeeTrack.cpp">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_core\functional\LoadMonitor.cpp"> <ClCompile Include="..\..\src\ripple_core\functional\LoadMonitor.cpp">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClCompile> </ClCompile>
@@ -1059,6 +1056,9 @@
<ClCompile Include="..\..\src\ripple\validators\impl\Utilities.cpp"> <ClCompile Include="..\..\src\ripple\validators\impl\Utilities.cpp">
<Filter>[1] Ripple\validators\impl</Filter> <Filter>[1] Ripple\validators\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.cpp">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h"> <ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
@@ -1100,9 +1100,6 @@
<ClInclude Include="..\..\src\ripple_basics\utility\UptimeTimer.h"> <ClInclude Include="..\..\src\ripple_basics\utility\UptimeTimer.h">
<Filter>[2] Old Ripple\ripple_basics\utility</Filter> <Filter>[2] Old Ripple\ripple_basics\utility</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\ILoadFeeTrack.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\Job.h"> <ClInclude Include="..\..\src\ripple_core\functional\Job.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude> </ClInclude>
@@ -1112,9 +1109,6 @@
<ClInclude Include="..\..\src\ripple_core\functional\LoadEvent.h"> <ClInclude Include="..\..\src\ripple_core\functional\LoadEvent.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadMonitor.h"> <ClInclude Include="..\..\src\ripple_core\functional\LoadMonitor.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude> </ClInclude>
@@ -2115,6 +2109,12 @@
<ClInclude Include="..\..\src\ripple\validators\impl\AgedHistory.h"> <ClInclude Include="..\..\src\ripple\validators\impl\AgedHistory.h">
<Filter>[1] Ripple\validators\impl</Filter> <Filter>[1] Ripple\validators\impl</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto"> <CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">

View File

@@ -131,10 +131,6 @@ David Features:
- Rename "fullBelow" to something like haveAllDescendants or haveAllChildren. - Rename "fullBelow" to something like haveAllDescendants or haveAllChildren.
- Remove dependence on JobQueue, LoadFeeTrack, and NetworkOPs from LoadManager
by providing an observer (beast::ListenerList or Listeners). This way
LoadManager does not need stopThread() function.
- Rewrite Sustain to use Beast and work on Windows as well - Rewrite Sustain to use Beast and work on Windows as well
* Do not enable watchdog process if a debugger is attached * Do not enable watchdog process if a debugger is attached

View File

@@ -171,7 +171,7 @@
// is being written. // is being written.
// //
#ifndef RIPPLE_USE_NEW_VALIDATORS #ifndef RIPPLE_USE_NEW_VALIDATORS
#define RIPPLE_USE_NEW_VALIDATORS 1 #define RIPPLE_USE_NEW_VALIDATORS 0
#endif #endif
// Turning this on makes the Application object get destroyed, // Turning this on makes the Application object get destroyed,

View File

@@ -17,7 +17,6 @@
*/ */
//============================================================================== //==============================================================================
#ifndef RIPPLE_VALIDATORS_LOGIC_H_INCLUDED #ifndef RIPPLE_VALIDATORS_LOGIC_H_INCLUDED
#define RIPPLE_VALIDATORS_LOGIC_H_INCLUDED #define RIPPLE_VALIDATORS_LOGIC_H_INCLUDED
@@ -36,7 +35,7 @@ enum
// We check Source expirations on this time interval // We check Source expirations on this time interval
,checkEverySeconds = 60 * 60 ,checkEverySeconds = 60 * 60
#else #else
secondsBetweenFetches = 5 * 60 secondsBetweenFetches = 59
,checkEverySeconds = 60 ,checkEverySeconds = 60
#endif #endif

View File

@@ -124,7 +124,7 @@ public:
, m_store (m_journal) , m_store (m_journal)
, m_logic (m_store, m_journal) , m_logic (m_store, m_journal)
, m_checkTimer (this) , m_checkTimer (this)
, m_checkSources (true) , m_checkSources (false)
{ {
#if BEAST_MSVC #if BEAST_MSVC
if (beast_isRunningUnderDebugger()) if (beast_isRunningUnderDebugger())
@@ -147,26 +147,35 @@ public:
void onPrepare (Journal journal) void onPrepare (Journal journal)
{ {
journal.info << "Preparing Validators"; journal.info << "Preparing";
addRPCHandlers(); addRPCHandlers();
} }
void onStart (Journal journal) void onStart (Journal journal)
{ {
journal.info << "Starting Validators"; journal.info << "Starting";
// Do this late so the sources have a chance to be added.
m_queue.dispatch (bind (&ManagerImp::setCheckSources, this));
startThread(); startThread();
} }
void onStop (Journal journal) void onStop (Journal journal)
{ {
journal.info << "Stopping Validators"; journal.info << "Stopping";
if (this->Thread::isThreadRunning()) if (this->Thread::isThreadRunning())
{
m_journal.debug << "Signaling thread exit";
m_queue.dispatch (bind (&Thread::signalThreadShouldExit, this)); m_queue.dispatch (bind (&Thread::signalThreadShouldExit, this));
}
else else
{
m_journal.debug << "Thread was never started";
stopped(); stopped();
}
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -269,12 +278,12 @@ public:
void init () void init ()
{ {
m_journal.trace << "Initializing"; m_journal.debug << "Initializing";
File const file (File::getSpecialLocation ( File const file (File::getSpecialLocation (
File::userDocumentsDirectory).getChildFile ("validators.sqlite")); File::userDocumentsDirectory).getChildFile ("validators.sqlite"));
m_journal.trace << "Opening database at '" << file.getFullPathName() << "'"; m_journal.debug << "Opening database at '" << file.getFullPathName() << "'";
Error error (m_store.open (file)); Error error (m_store.open (file));
@@ -294,13 +303,14 @@ public:
{ {
if (timer == m_checkTimer) if (timer == m_checkTimer)
{ {
m_journal.trace << "Check timer signaled"; m_journal.debug << "Check timer expired";
m_queue.dispatch (bind (&ManagerImp::setCheckSources, this)); m_queue.dispatch (bind (&ManagerImp::setCheckSources, this));
} }
} }
void setCheckSources () void setCheckSources ()
{ {
m_journal.debug << "Checking sources";
m_checkSources = true; m_checkSources = true;
} }
@@ -308,18 +318,16 @@ public:
{ {
if (m_checkSources) if (m_checkSources)
{ {
m_journal.trace << "Checking sources";
if (m_logic.fetch_one () == 0) if (m_logic.fetch_one () == 0)
{ {
m_journal.trace << "Finished checking sources"; m_journal.debug << "All sources checked";
// Made it through the list without interruption! // Made it through the list without interruption!
// Clear the flag and set the deadline timer again. // Clear the flag and set the deadline timer again.
// //
m_checkSources = false; m_checkSources = false;
m_journal.trace << "Next check timer expires in " << m_journal.debug << "Next check timer expires in " <<
RelativeTime::seconds (checkEverySeconds); RelativeTime::seconds (checkEverySeconds);
m_checkTimer.setExpiration (checkEverySeconds); m_checkTimer.setExpiration (checkEverySeconds);

View File

@@ -40,6 +40,8 @@ class RPCServiceManagerLog;
template <> char const* LogPartition::getPartitionName <RPCServiceManagerLog> () { return "RPCServiceManager"; } template <> char const* LogPartition::getPartitionName <RPCServiceManagerLog> () { return "RPCServiceManager"; }
class HTTPServerLog; class HTTPServerLog;
template <> char const* LogPartition::getPartitionName <HTTPServerLog> () { return "RPCServer"; } template <> char const* LogPartition::getPartitionName <HTTPServerLog> () { return "RPCServer"; }
class LoadManagerLog;
template <> char const* LogPartition::getPartitionName <LoadManagerLog> () { return "LoadManager"; }
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -124,7 +126,7 @@ public:
, mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS)) , mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS))
, mFeeTrack (ILoadFeeTrack::New ()) , mFeeTrack (LoadFeeTrack::New (LogJournal::get <LoadManagerLog> ()))
, mHashRouter (IHashRouter::New (IHashRouter::getDefaultHoldTime ())) , mHashRouter (IHashRouter::New (IHashRouter::getDefaultHoldTime ()))
@@ -132,7 +134,7 @@ public:
, mProofOfWorkFactory (ProofOfWorkFactory::New ()) , mProofOfWorkFactory (ProofOfWorkFactory::New ())
, m_loadManager (LoadManager::New ()) , m_loadManager (LoadManager::New (*this, LogJournal::get <LoadManagerLog> ()))
, mPeerFinder (PeerFinder::New (*this)) , mPeerFinder (PeerFinder::New (*this))
@@ -145,8 +147,6 @@ public:
// VFALCO TODO remove these once the call is thread safe. // VFALCO TODO remove these once the call is thread safe.
HashMaps::getInstance ().initializeNonce <size_t> (); HashMaps::getInstance ().initializeNonce <size_t> ();
initValidatorsConfig ();
} }
~ApplicationImp () ~ApplicationImp ()
@@ -163,28 +163,6 @@ public:
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Initialize the Validators object with Config information.
void initValidatorsConfig ()
{
{
std::vector <std::string> const& strings (getConfig().validators);
if (! strings.empty ())
m_validators->addStrings ("rippled.cfg", strings);
}
if (! getConfig().getValidatorsURL().empty())
{
m_validators->addURL (getConfig().getValidatorsURL());
}
if (getConfig().getValidatorsFile() != File::nonexistent ())
{
m_validators->addFile (getConfig().getValidatorsFile());
}
}
//--------------------------------------------------------------------------
RPC::Manager& getRPCServiceManager() RPC::Manager& getRPCServiceManager()
{ {
return *m_rpcServiceManager; return *m_rpcServiceManager;
@@ -270,7 +248,7 @@ public:
return *mFeatures; return *mFeatures;
} }
ILoadFeeTrack& getFeeTrack () LoadFeeTrack& getFeeTrack ()
{ {
return *mFeeTrack; return *mFeeTrack;
} }
@@ -388,10 +366,6 @@ public:
// VFALCO NOTE: 0 means use heuristics to determine the thread count. // VFALCO NOTE: 0 means use heuristics to determine the thread count.
m_jobQueue->setThreadCount (0, getConfig ().RUN_STANDALONE); m_jobQueue->setThreadCount (0, getConfig ().RUN_STANDALONE);
m_sweepTimer.setExpiration (10);
m_loadManager->start ();
#if ! BEAST_WIN32 #if ! BEAST_WIN32
#ifdef SIGINT #ifdef SIGINT
@@ -643,15 +617,53 @@ public:
} }
} }
//--------------------------------------------------------------------------
// Initialize the Validators object with Config information.
void prepareValidators ()
{
{
std::vector <std::string> const& strings (getConfig().validators);
if (! strings.empty ())
m_validators->addStrings ("rippled.cfg", strings);
}
if (! getConfig().getValidatorsURL().empty())
{
m_validators->addURL (getConfig().getValidatorsURL());
}
if (getConfig().getValidatorsFile() != File::nonexistent ())
{
m_validators->addFile (getConfig().getValidatorsFile());
}
}
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// //
// Stoppable // Stoppable
//
void onPrepare (Journal)
{
prepareValidators ();
}
void onStart (Journal journal)
{
journal.debug << "Application starting";
m_sweepTimer.setExpiration (10);
}
// Called to indicate shutdown. // Called to indicate shutdown.
void onStop (Journal) void onStop (Journal journal)
{ {
journal.debug << "Application stopping";
m_sweepTimer.cancel(); m_sweepTimer.cancel();
// VFALCO TODO get rid of this flag
mShutdown = true; mShutdown = true;
mValidations->flush (); mValidations->flush ();
@@ -717,7 +729,7 @@ public:
// eliminate LoadManager's dependency inversions. // eliminate LoadManager's dependency inversions.
// //
// This deletes the object and therefore, stops the thread. // This deletes the object and therefore, stops the thread.
m_loadManager = nullptr; //m_loadManager = nullptr;
m_journal.info << "Done."; m_journal.info << "Done.";
@@ -844,7 +856,7 @@ private:
ScopedPointer <Validators::Manager> m_validators; ScopedPointer <Validators::Manager> m_validators;
ScopedPointer <IFeatures> mFeatures; ScopedPointer <IFeatures> mFeatures;
ScopedPointer <IFeeVote> mFeeVote; ScopedPointer <IFeeVote> mFeeVote;
ScopedPointer <ILoadFeeTrack> mFeeTrack; ScopedPointer <LoadFeeTrack> mFeeTrack;
ScopedPointer <IHashRouter> mHashRouter; ScopedPointer <IHashRouter> mHashRouter;
ScopedPointer <Validations> mValidations; ScopedPointer <Validations> mValidations;
ScopedPointer <ProofOfWorkFactory> mProofOfWorkFactory; ScopedPointer <ProofOfWorkFactory> mProofOfWorkFactory;

View File

@@ -29,7 +29,7 @@ namespace RPC { class Manager; }
class IFeatures; class IFeatures;
class IFeeVote; class IFeeVote;
class IHashRouter; class IHashRouter;
class ILoadFeeTrack; class LoadFeeTrack;
class Peers; class Peers;
class UniqueNodeList; class UniqueNodeList;
class JobQueue; class JobQueue;
@@ -98,7 +98,7 @@ public:
virtual IFeatures& getFeatureTable () = 0; virtual IFeatures& getFeatureTable () = 0;
virtual IFeeVote& getFeeVote () = 0; virtual IFeeVote& getFeeVote () = 0;
virtual IHashRouter& getHashRouter () = 0; virtual IHashRouter& getHashRouter () = 0;
virtual ILoadFeeTrack& getFeeTrack () = 0; virtual LoadFeeTrack& getFeeTrack () = 0;
virtual LoadManager& getLoadManager () = 0; virtual LoadManager& getLoadManager () = 0;
virtual Peers& getPeers () = 0; virtual Peers& getPeers () = 0;
virtual ProofOfWorkFactory& getProofOfWorkFactory () = 0; virtual ProofOfWorkFactory& getProofOfWorkFactory () = 0;

View File

@@ -17,16 +17,11 @@
*/ */
//============================================================================== //==============================================================================
SETUP_LOG (LoadManager)
//------------------------------------------------------------------------------
class LoadManagerImp class LoadManagerImp
: public LoadManager : public LoadManager
, public Thread , public Thread
{ {
private: public:
/* Entry mapping utilization to cost. /* Entry mapping utilization to cost.
The cost is expressed as a unitless relative quantity. These The cost is expressed as a unitless relative quantity. These
@@ -72,11 +67,33 @@ private:
int m_resourceFlags; int m_resourceFlags;
}; };
public: //--------------------------------------------------------------------------
LoadManagerImp ()
: Thread ("loadmgr") Journal m_journal;
typedef RippleMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
LockType mLock;
BlackList<UptimeTimerAdapter> mBlackList;
int mCreditRate; // credits gained/lost per second
int mCreditLimit; // the most credits a source can have
int mDebitWarn; // when a source drops below this, we warn
int mDebitLimit; // when a source drops below this, we cut it off (should be negative)
bool mArmed;
int mDeadLock; // Detect server deadlocks
std::vector <Cost> mCosts;
//--------------------------------------------------------------------------
LoadManagerImp (Stoppable& parent, Journal journal)
: LoadManager (parent)
, Thread ("loadmgr")
, m_journal (journal)
, mLock (this, "LoadManagerImp", __FILE__, __LINE__) , mLock (this, "LoadManagerImp", __FILE__, __LINE__)
, m_logThread ("loadmgr_log")
, mCreditRate (100) , mCreditRate (100)
, mCreditLimit (500) , mCreditLimit (500)
, mDebitWarn (-500) , mDebitWarn (-500)
@@ -85,8 +102,6 @@ public:
, mDeadLock (0) , mDeadLock (0)
, mCosts (LT_MAX) , mCosts (LT_MAX)
{ {
m_logThread.start ();
/** Flags indicating the type of load. /** Flags indicating the type of load.
Utilization may include any combination of: Utilization may include any combination of:
@@ -128,7 +143,6 @@ public:
UptimeTimer::getInstance ().beginManualUpdates (); UptimeTimer::getInstance ().beginManualUpdates ();
} }
private:
~LoadManagerImp () ~LoadManagerImp ()
{ {
UptimeTimer::getInstance ().endManualUpdates (); UptimeTimer::getInstance ().endManualUpdates ();
@@ -136,11 +150,36 @@ private:
stopThread (); stopThread ();
} }
void start () //--------------------------------------------------------------------------
//
// Stoppable
//
void onPrepare (Journal)
{ {
startThread();
} }
void onStart (Journal journal)
{
journal.debug << "Starting";
startThread ();
}
void onStop (Journal journal)
{
if (isThreadRunning ())
{
journal.debug << "Stopping";
stopThread (0);
}
else
{
stopped ();
}
}
//--------------------------------------------------------------------------
void canonicalize (LoadSource& source, int now) const void canonicalize (LoadSource& source, int now) const
{ {
if (source.mLastUpdate != now) if (source.mLastUpdate != now)
@@ -240,17 +279,17 @@ private:
void logWarning (const std::string& source) const void logWarning (const std::string& source) const
{ {
if (source.empty ()) if (source.empty ())
WriteLog (lsDEBUG, LoadManager) << "Load warning from empty source"; m_journal.debug << "Load warning from empty source";
else else
WriteLog (lsINFO, LoadManager) << "Load warning: " << source; m_journal.info << "Load warning: " << source;
} }
void logDisconnect (const std::string& source) const void logDisconnect (const std::string& source) const
{ {
if (source.empty ()) if (source.empty ())
WriteLog (lsINFO, LoadManager) << "Disconnect for empty source"; m_journal.info << "Disconnect for empty source";
else else
WriteLog (lsWARNING, LoadManager) << "Disconnect for: " << source; m_journal.warning << "Disconnect for: " << source;
} }
Json::Value getBlackList (int threshold) Json::Value getBlackList (int threshold)
@@ -282,9 +321,9 @@ private:
mArmed = true; mArmed = true;
} }
static void logDeadlock (int dlTime) void logDeadlock (int dlTime)
{ {
WriteLog (lsWARNING, LoadManager) << "Server stalled for " << dlTime << " seconds."; m_journal.warning << "Server stalled for " << dlTime << " seconds.";
#if RIPPLE_TRACK_MUTEXES #if RIPPLE_TRACK_MUTEXES
StringArray report; StringArray report;
@@ -298,59 +337,6 @@ private:
#endif #endif
} }
private:
// VFALCO TODO These used to be public but are apparently not used. Find out why.
/*
int getCreditRate () const
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mCreditRate;
}
int getCreditLimit () const
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mCreditLimit;
}
int getDebitWarn () const
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mDebitWarn;
}
int getDebitLimit () const
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mDebitLimit;
}
void setCreditRate (int r)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mCreditRate = r;
}
void setCreditLimit (int r)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mCreditLimit = r;
}
void setDebitWarn (int r)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mDebitWarn = r;
}
void setDebitLimit (int r)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mDebitLimit = r;
}
*/
private:
void addCost (const Cost& c) void addCost (const Cost& c)
{ {
mCosts [static_cast <int> (c.getLoadType ())] = c; mCosts [static_cast <int> (c.getLoadType ())] = c;
@@ -393,9 +379,7 @@ private:
// Report the deadlocked condition every 10 seconds // Report the deadlocked condition every 10 seconds
if ((timeSpentDeadlocked % reportingIntervalSeconds) == 0) if ((timeSpentDeadlocked % reportingIntervalSeconds) == 0)
{ {
// VFALCO TODO Replace this with a dedicated thread with call queue. logDeadlock (timeSpentDeadlocked);
//
m_logThread.call (&logDeadlock, timeSpentDeadlocked);
} }
// If we go over 500 seconds spent deadlocked, it means that the // If we go over 500 seconds spent deadlocked, it means that the
@@ -413,7 +397,7 @@ private:
// Another option is using an observer pattern to invert the dependency. // Another option is using an observer pattern to invert the dependency.
if (getApp().getJobQueue ().isOverloaded ()) if (getApp().getJobQueue ().isOverloaded ())
{ {
WriteLog (lsINFO, LoadManager) << getApp().getJobQueue ().getJson (0); m_journal.info << getApp().getJobQueue ().getJson (0);
change = getApp().getFeeTrack ().raiseLocalFee (); change = getApp().getFeeTrack ().raiseLocalFee ();
} }
else else
@@ -432,7 +416,7 @@ private:
if ((when.is_negative ()) || (when.total_seconds () > 1)) if ((when.is_negative ()) || (when.total_seconds () > 1))
{ {
WriteLog (lsWARNING, LoadManager) << "time jump"; m_journal.warning << "time jump";
t = boost::posix_time::microsec_clock::universal_time (); t = boost::posix_time::microsec_clock::universal_time ();
} }
else else
@@ -441,32 +425,18 @@ private:
} }
} }
} }
private:
typedef RippleMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
LockType mLock;
beast::ThreadWithCallQueue m_logThread;
BlackList<UptimeTimerAdapter> mBlackList;
int mCreditRate; // credits gained/lost per second
int mCreditLimit; // the most credits a source can have
int mDebitWarn; // when a source drops below this, we warn
int mDebitLimit; // when a source drops below this, we cut it off (should be negative)
bool mArmed;
int mDeadLock; // Detect server deadlocks
std::vector <Cost> mCosts;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
LoadManager* LoadManager::New () LoadManager::LoadManager (Stoppable& parent)
: Stoppable ("LoadManager", parent)
{ {
ScopedPointer <LoadManager> object (new LoadManagerImp); }
return object.release ();
//------------------------------------------------------------------------------
LoadManager* LoadManager::New (Stoppable& parent, Journal journal)
{
return new LoadManagerImp (parent, journal);
} }

View File

@@ -34,17 +34,18 @@
@see LoadSource, LoadType @see LoadSource, LoadType
*/ */
class LoadManager class LoadManager : public Stoppable
{ {
protected:
explicit LoadManager (Stoppable& parent);
public: public:
/** Create a new manager. /** Create a new manager.
The manager thread begins running immediately.
@note The thresholds for warnings and punishments are in @note The thresholds for warnings and punishments are in
the ctor-initializer the ctor-initializer
*/ */
static LoadManager* New (); static LoadManager* New (Stoppable& parent, Journal journal);
/** Destroy the manager. /** Destroy the manager.
@@ -52,15 +53,6 @@ public:
*/ */
virtual ~LoadManager () { } virtual ~LoadManager () { }
/** Start the associated thread.
This is here to prevent the deadlock detector from activating during
a lengthy program initialization.
*/
// VFALCO TODO Simplify the two stage initialization to one stage (construction).
// NOTE In stand-alone mode the load manager thread isn't started
virtual void start () = 0;
/** Turn on deadlock detection. /** Turn on deadlock detection.
The deadlock detector begins in a disabled state. After this function The deadlock detector begins in a disabled state. After this function

View File

@@ -1,67 +0,0 @@
//------------------------------------------------------------------------------
/*
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_ILOADFEETRACK_H_INCLUDED
#define RIPPLE_ILOADFEETRACK_H_INCLUDED
/** Manages the current fee schedule.
The "base" fee is the cost to send a reference transaction under no load,
expressed in millionths of one XRP.
The "load" fee is how much the local server currently charges to send a
reference transaction. This fee fluctuates based on the load of the
server.
*/
// VFALCO TODO Rename "load" to "current".
class ILoadFeeTrack
{
public:
/** Create a new tracker.
*/
static ILoadFeeTrack* New ();
virtual ~ILoadFeeTrack () { }
// Scale from fee units to millionths of a ripple
virtual uint64 scaleFeeBase (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits) = 0;
// Scale using load as well as base rate
virtual uint64 scaleFeeLoad (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin) = 0;
virtual void setRemoteFee (uint32) = 0;
virtual uint32 getRemoteFee () = 0;
virtual uint32 getLocalFee () = 0;
virtual uint32 getClusterFee () = 0;
virtual uint32 getLoadBase () = 0;
virtual uint32 getLoadFactor () = 0;
virtual Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits) = 0;
virtual void setClusterFee (uint32) = 0;
virtual bool raiseLocalFee () = 0;
virtual bool lowerLocalFee () = 0;
virtual bool isLoadedLocal () = 0;
virtual bool isLoadedCluster () = 0;
};
#endif

View File

@@ -17,217 +17,50 @@
*/ */
//============================================================================== //==============================================================================
#ifndef RIPPLE_LOADFEETRACK_H_INCLUDED #ifndef RIPPLE_LOADFEETRACK_H_INCLUDED
#define RIPPLE_LOADFEETRACK_H_INCLUDED #define RIPPLE_LOADFEETRACK_H_INCLUDED
// PRIVATE HEADER /** Manages the current fee schedule.
class LoadManager;
class LoadFeeTrack : public ILoadFeeTrack The "base" fee is the cost to send a reference transaction under no load,
expressed in millionths of one XRP.
The "load" fee is how much the local server currently charges to send a
reference transaction. This fee fluctuates based on the load of the
server.
*/
// VFALCO TODO Rename "load" to "current".
class LoadFeeTrack
{ {
public: public:
LoadFeeTrack () /** Create a new tracker.
: mLock (this, "LoadFeeTrack", __FILE__, __LINE__) */
, mLocalTxnLoadFee (lftNormalFee) static LoadFeeTrack* New (Journal journal);
, mRemoteTxnLoadFee (lftNormalFee)
, mClusterTxnLoadFee (lftNormalFee)
, raiseCount (0)
{
}
// Scale using load as well as base rate virtual ~LoadFeeTrack () { }
uint64 scaleFeeLoad (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin)
{
static uint64 midrange (0x00000000FFFFFFFF);
bool big = (fee > midrange);
if (big) // big fee, divide first to avoid overflow
fee /= baseFee;
else // normal fee, multiply first for accuracy
fee *= referenceFeeUnits;
uint32 feeFactor = std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee);
// Let admins pay the normal fee until the local load exceeds four times the remote
uint32 uRemFee = std::max(mRemoteTxnLoadFee, mClusterTxnLoadFee);
if (bAdmin && (feeFactor > uRemFee) && (feeFactor < (4 * uRemFee)))
feeFactor = uRemFee;
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
fee = mulDiv (fee, feeFactor, lftNormalFee);
}
if (big) // Fee was big to start, must now multiply
fee *= referenceFeeUnits;
else // Fee was small to start, mst now divide
fee /= baseFee;
return fee;
}
// Scale from fee units to millionths of a ripple // Scale from fee units to millionths of a ripple
uint64 scaleFeeBase (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits) virtual uint64 scaleFeeBase (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits) = 0;
{
return mulDiv (fee, referenceFeeUnits, baseFee);
}
uint32 getRemoteFee () // Scale using load as well as base rate
{ virtual uint64 scaleFeeLoad (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin) = 0;
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mRemoteTxnLoadFee;
}
uint32 getLocalFee () virtual void setRemoteFee (uint32) = 0;
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mLocalTxnLoadFee;
}
uint32 getLoadBase () virtual uint32 getRemoteFee () = 0;
{ virtual uint32 getLocalFee () = 0;
return lftNormalFee; virtual uint32 getClusterFee () = 0;
}
uint32 getLoadFactor () virtual uint32 getLoadBase () = 0;
{ virtual uint32 getLoadFactor () = 0;
ScopedLockType sl (mLock, __FILE__, __LINE__);
return std::max(mClusterTxnLoadFee, std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee));
}
void setClusterFee (uint32 fee) virtual Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits) = 0;
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mClusterTxnLoadFee = fee;
}
uint32 getClusterFee () virtual void setClusterFee (uint32) = 0;
{ virtual bool raiseLocalFee () = 0;
ScopedLockType sl (mLock, __FILE__, __LINE__); virtual bool lowerLocalFee () = 0;
return mClusterTxnLoadFee; virtual bool isLoadedLocal () = 0;
} virtual bool isLoadedCluster () = 0;
bool isLoadedLocal ()
{
// VFALCO TODO This could be replaced with a SharedData and
// using a read/write lock instead of a critical section.
//
// NOTE This applies to all the locking in this class.
//
//
ScopedLockType sl (mLock, __FILE__, __LINE__);
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee);
}
bool isLoadedCluster ()
{
// VFALCO TODO This could be replaced with a SharedData and
// using a read/write lock instead of a critical section.
//
// NOTE This applies to all the locking in this class.
//
//
ScopedLockType sl (mLock, __FILE__, __LINE__);
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee) || (mClusterTxnLoadFee != lftNormalFee);
}
void setRemoteFee (uint32 f)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mRemoteTxnLoadFee = f;
}
bool raiseLocalFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
if (++raiseCount < 2)
return false;
uint32 origFee = mLocalTxnLoadFee;
if (mLocalTxnLoadFee < mRemoteTxnLoadFee) // make sure this fee takes effect
mLocalTxnLoadFee = mRemoteTxnLoadFee;
mLocalTxnLoadFee += (mLocalTxnLoadFee / lftFeeIncFraction); // increment by 1/16th
if (mLocalTxnLoadFee > lftFeeMax)
mLocalTxnLoadFee = lftFeeMax;
if (origFee == mLocalTxnLoadFee)
return false;
WriteLog (lsDEBUG, LoadManager) << "Local load fee raised from " << origFee << " to " << mLocalTxnLoadFee;
return true;
}
bool lowerLocalFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
uint32 origFee = mLocalTxnLoadFee;
raiseCount = 0;
mLocalTxnLoadFee -= (mLocalTxnLoadFee / lftFeeDecFraction ); // reduce by 1/4
if (mLocalTxnLoadFee < lftNormalFee)
mLocalTxnLoadFee = lftNormalFee;
if (origFee == mLocalTxnLoadFee)
return false;
WriteLog (lsDEBUG, LoadManager) << "Local load fee lowered from " << origFee << " to " << mLocalTxnLoadFee;
return true;
}
Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits)
{
Json::Value j (Json::objectValue);
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
// base_fee = The cost to send a "reference" transaction under no load, in millionths of a Ripple
j["base_fee"] = Json::Value::UInt (baseFee);
// load_fee = The cost to send a "reference" transaction now, in millionths of a Ripple
j["load_fee"] = Json::Value::UInt (
mulDiv (baseFee, std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee), lftNormalFee));
}
return j;
}
private:
// VFALCO TODO Move this function to some "math utilities" file
// compute (value)*(mul)/(div) - avoid overflow but keep precision
uint64 mulDiv (uint64 value, uint32 mul, uint64 div)
{
// VFALCO TODO replace with beast::literal64bitUnsigned ()
//
static uint64 boundary = (0x00000000FFFFFFFF);
if (value > boundary) // Large value, avoid overflow
return (value / div) * mul;
else // Normal value, preserve accuracy
return (value * mul) / div;
}
private:
static const int lftNormalFee = 256; // 256 is the minimum/normal load factor
static const int lftFeeIncFraction = 4; // increase fee by 1/4
static const int lftFeeDecFraction = 4; // decrease fee by 1/4
static const int lftFeeMax = lftNormalFee * 1000000;
typedef RippleMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
LockType mLock;
uint32 mLocalTxnLoadFee; // Scale factor, lftNormalFee = normal fee
uint32 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee
uint32 mClusterTxnLoadFee; // Scale factor, lftNormalFee = normal fee
int raiseCount;
}; };
#endif #endif

View File

@@ -17,10 +17,9 @@
*/ */
//============================================================================== //==============================================================================
LoadFeeTrack* LoadFeeTrack::New (Journal journal)
ILoadFeeTrack* ILoadFeeTrack::New ()
{ {
return new LoadFeeTrack; return new LoadFeeTrackImp (journal);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -35,7 +34,7 @@ public:
void runTest () void runTest ()
{ {
Config d; // get a default configuration object Config d; // get a default configuration object
LoadFeeTrack l; LoadFeeTrackImp l;
beginTestCase ("fee scaling"); beginTestCase ("fee scaling");

View File

@@ -0,0 +1,231 @@
//------------------------------------------------------------------------------
/*
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_LOADFEETRACKIMP_H_INCLUDED
#define RIPPLE_LOADFEETRACKIMP_H_INCLUDED
class LoadFeeTrackImp : public LoadFeeTrack
{
public:
explicit LoadFeeTrackImp (Journal journal = Journal())
: m_journal (journal)
, mLock (this, "LoadFeeTrackImp", __FILE__, __LINE__)
, mLocalTxnLoadFee (lftNormalFee)
, mRemoteTxnLoadFee (lftNormalFee)
, mClusterTxnLoadFee (lftNormalFee)
, raiseCount (0)
{
}
// Scale using load as well as base rate
uint64 scaleFeeLoad (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin)
{
static uint64 midrange (0x00000000FFFFFFFF);
bool big = (fee > midrange);
if (big) // big fee, divide first to avoid overflow
fee /= baseFee;
else // normal fee, multiply first for accuracy
fee *= referenceFeeUnits;
uint32 feeFactor = std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee);
// Let admins pay the normal fee until the local load exceeds four times the remote
uint32 uRemFee = std::max(mRemoteTxnLoadFee, mClusterTxnLoadFee);
if (bAdmin && (feeFactor > uRemFee) && (feeFactor < (4 * uRemFee)))
feeFactor = uRemFee;
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
fee = mulDiv (fee, feeFactor, lftNormalFee);
}
if (big) // Fee was big to start, must now multiply
fee *= referenceFeeUnits;
else // Fee was small to start, mst now divide
fee /= baseFee;
return fee;
}
// Scale from fee units to millionths of a ripple
uint64 scaleFeeBase (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits)
{
return mulDiv (fee, referenceFeeUnits, baseFee);
}
uint32 getRemoteFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mRemoteTxnLoadFee;
}
uint32 getLocalFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mLocalTxnLoadFee;
}
uint32 getLoadBase ()
{
return lftNormalFee;
}
uint32 getLoadFactor ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return std::max(mClusterTxnLoadFee, std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee));
}
void setClusterFee (uint32 fee)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mClusterTxnLoadFee = fee;
}
uint32 getClusterFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
return mClusterTxnLoadFee;
}
bool isLoadedLocal ()
{
// VFALCO TODO This could be replaced with a SharedData and
// using a read/write lock instead of a critical section.
//
// NOTE This applies to all the locking in this class.
//
//
ScopedLockType sl (mLock, __FILE__, __LINE__);
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee);
}
bool isLoadedCluster ()
{
// VFALCO TODO This could be replaced with a SharedData and
// using a read/write lock instead of a critical section.
//
// NOTE This applies to all the locking in this class.
//
//
ScopedLockType sl (mLock, __FILE__, __LINE__);
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee) || (mClusterTxnLoadFee != lftNormalFee);
}
void setRemoteFee (uint32 f)
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
mRemoteTxnLoadFee = f;
}
bool raiseLocalFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
if (++raiseCount < 2)
return false;
uint32 origFee = mLocalTxnLoadFee;
if (mLocalTxnLoadFee < mRemoteTxnLoadFee) // make sure this fee takes effect
mLocalTxnLoadFee = mRemoteTxnLoadFee;
mLocalTxnLoadFee += (mLocalTxnLoadFee / lftFeeIncFraction); // increment by 1/16th
if (mLocalTxnLoadFee > lftFeeMax)
mLocalTxnLoadFee = lftFeeMax;
if (origFee == mLocalTxnLoadFee)
return false;
m_journal.debug << "Local load fee raised from " << origFee << " to " << mLocalTxnLoadFee;
return true;
}
bool lowerLocalFee ()
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
uint32 origFee = mLocalTxnLoadFee;
raiseCount = 0;
mLocalTxnLoadFee -= (mLocalTxnLoadFee / lftFeeDecFraction ); // reduce by 1/4
if (mLocalTxnLoadFee < lftNormalFee)
mLocalTxnLoadFee = lftNormalFee;
if (origFee == mLocalTxnLoadFee)
return false;
m_journal.debug << "Local load fee lowered from " << origFee << " to " << mLocalTxnLoadFee;
return true;
}
Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits)
{
Json::Value j (Json::objectValue);
{
ScopedLockType sl (mLock, __FILE__, __LINE__);
// base_fee = The cost to send a "reference" transaction under no load, in millionths of a Ripple
j["base_fee"] = Json::Value::UInt (baseFee);
// load_fee = The cost to send a "reference" transaction now, in millionths of a Ripple
j["load_fee"] = Json::Value::UInt (
mulDiv (baseFee, std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee), lftNormalFee));
}
return j;
}
private:
// VFALCO TODO Move this function to some "math utilities" file
// compute (value)*(mul)/(div) - avoid overflow but keep precision
uint64 mulDiv (uint64 value, uint32 mul, uint64 div)
{
// VFALCO TODO replace with beast::literal64bitUnsigned ()
//
static uint64 boundary = (0x00000000FFFFFFFF);
if (value > boundary) // Large value, avoid overflow
return (value / div) * mul;
else // Normal value, preserve accuracy
return (value * mul) / div;
}
private:
static const int lftNormalFee = 256; // 256 is the minimum/normal load factor
static const int lftFeeIncFraction = 4; // increase fee by 1/4
static const int lftFeeDecFraction = 4; // decrease fee by 1/4
static const int lftFeeMax = lftNormalFee * 1000000;
Journal m_journal;
typedef RippleMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
LockType mLock;
uint32 mLocalTxnLoadFee; // Scale factor, lftNormalFee = normal fee
uint32 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee
uint32 mClusterTxnLoadFee; // Scale factor, lftNormalFee = normal fee
int raiseCount;
};
#endif

View File

@@ -40,8 +40,8 @@ namespace ripple
{ {
#include "functional/Config.cpp" #include "functional/Config.cpp"
# include "functional/LoadFeeTrack.h" // private # include "functional/LoadFeeTrackImp.h" // private
#include "functional/LoadFeeTrack.cpp" #include "functional/LoadFeeTrackImp.cpp"
#include "functional/Job.cpp" #include "functional/Job.cpp"
#include "functional/JobQueue.cpp" #include "functional/JobQueue.cpp"
#include "functional/LoadEvent.cpp" #include "functional/LoadEvent.cpp"

View File

@@ -36,7 +36,7 @@ namespace ripple
# include "functional/ConfigSections.h" # include "functional/ConfigSections.h"
#include "functional/Config.h" #include "functional/Config.h"
#include "functional/ILoadFeeTrack.h" #include "functional/LoadFeeTrack.h"
# include "functional/LoadEvent.h" # include "functional/LoadEvent.h"
# include "functional/LoadMonitor.h" # include "functional/LoadMonitor.h"
# include "functional/Job.h" # include "functional/Job.h"