mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Replace UptimeTimer with UptimeClock
* UptimeClock is a chrono-compatible seconds-precision clock. * Like UptimeTimer, its purpose is to make it possible for clients to query the uptime thousands of times per second without a significant performance hit. * UptimeClock decouples itself from LoadManager by managing its own once-per-second update loop. * Clients now traffic in chrono time_points and durations instead of int.
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/misc/LoadFeeTrack.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <ripple/basics/UptimeTimer.h>
|
||||
#include <ripple/basics/UptimeClock.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/beast/core/CurrentThreadName.h>
|
||||
#include <memory>
|
||||
@@ -35,18 +35,16 @@ LoadManager::LoadManager (
|
||||
: Stoppable ("LoadManager", parent)
|
||||
, app_ (app)
|
||||
, journal_ (journal)
|
||||
, deadLock_ (0)
|
||||
, deadLock_ ()
|
||||
, armed_ (false)
|
||||
, stop_ (false)
|
||||
{
|
||||
UptimeTimer::getInstance ().beginManualUpdates ();
|
||||
}
|
||||
|
||||
LoadManager::~LoadManager ()
|
||||
{
|
||||
try
|
||||
{
|
||||
UptimeTimer::getInstance ().endManualUpdates ();
|
||||
onStop ();
|
||||
}
|
||||
catch (std::exception const& ex)
|
||||
@@ -67,9 +65,7 @@ void LoadManager::activateDeadlockDetector ()
|
||||
|
||||
void LoadManager::resetDeadlockDetector ()
|
||||
{
|
||||
auto const elapsedSeconds =
|
||||
UptimeTimer::getInstance ().getElapsedSeconds ();
|
||||
|
||||
auto const elapsedSeconds = UptimeClock::now();
|
||||
std::lock_guard<std::mutex> sl (mutex_);
|
||||
deadLock_ = elapsedSeconds;
|
||||
}
|
||||
@@ -108,24 +104,14 @@ void LoadManager::run ()
|
||||
{
|
||||
beast::setCurrentThreadName ("LoadManager");
|
||||
|
||||
using clock_type = std::chrono::steady_clock;
|
||||
using clock_type = std::chrono::system_clock;
|
||||
|
||||
// Initialize the clock to the current time.
|
||||
auto t = clock_type::now();
|
||||
bool stop = false;
|
||||
|
||||
while (! (stop || isStopping ()))
|
||||
{
|
||||
{
|
||||
// VFALCO NOTE I think this is to reduce calls to the operating
|
||||
// system for retrieving the current time.
|
||||
//
|
||||
// TODO Instead of incrementing can't we just retrieve the
|
||||
// current time again?
|
||||
//
|
||||
// Manually update the timer.
|
||||
UptimeTimer::getInstance ().incrementElapsedTime ();
|
||||
|
||||
// Copy out shared data under a lock. Use copies outside lock.
|
||||
std::unique_lock<std::mutex> sl (mutex_);
|
||||
auto const deadLock = deadLock_;
|
||||
@@ -134,29 +120,24 @@ void LoadManager::run ()
|
||||
sl.unlock();
|
||||
|
||||
// Measure the amount of time we have been deadlocked, in seconds.
|
||||
//
|
||||
// VFALCO NOTE deadLock_ is a canary for detecting the condition.
|
||||
int const timeSpentDeadlocked =
|
||||
UptimeTimer::getInstance ().getElapsedSeconds () - deadLock;
|
||||
auto const timeSpentDeadlocked = UptimeClock::now() - deadLock;
|
||||
|
||||
// VFALCO NOTE I think that "armed" refers to the deadlock detector.
|
||||
//
|
||||
int const reportingIntervalSeconds = 10;
|
||||
auto const reportingIntervalSeconds = 10s;
|
||||
if (armed && (timeSpentDeadlocked >= reportingIntervalSeconds))
|
||||
{
|
||||
// Report the deadlocked condition every 10 seconds
|
||||
if ((timeSpentDeadlocked % reportingIntervalSeconds) == 0)
|
||||
if ((timeSpentDeadlocked % reportingIntervalSeconds) == 0s)
|
||||
{
|
||||
JLOG(journal_.warn())
|
||||
<< "Server stalled for "
|
||||
<< timeSpentDeadlocked << " seconds.";
|
||||
<< timeSpentDeadlocked.count() << " seconds.";
|
||||
}
|
||||
|
||||
// If we go over 500 seconds spent deadlocked, it means that
|
||||
// the deadlock resolution code has failed, which qualifies
|
||||
// as undefined behavior.
|
||||
//
|
||||
assert (timeSpentDeadlocked < 500);
|
||||
assert (timeSpentDeadlocked < 500s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,18 +159,17 @@ void LoadManager::run ()
|
||||
app_.getOPs ().reportFeeChange ();
|
||||
}
|
||||
|
||||
t += std::chrono::seconds (1);
|
||||
t += 1s;
|
||||
auto const duration = t - clock_type::now();
|
||||
|
||||
if ((duration < std::chrono::seconds (0)) ||
|
||||
(duration > std::chrono::seconds (1)))
|
||||
if ((duration < 0s) || (duration > 1s))
|
||||
{
|
||||
JLOG(journal_.warn()) << "time jump";
|
||||
t = clock_type::now();
|
||||
}
|
||||
else
|
||||
{
|
||||
alertable_sleep_for(duration);
|
||||
alertable_sleep_until(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +182,7 @@ std::unique_ptr<LoadManager>
|
||||
make_LoadManager (Application& app,
|
||||
Stoppable& parent, beast::Journal journal)
|
||||
{
|
||||
return std::make_unique<LoadManager>(app, parent, journal);
|
||||
return std::unique_ptr<LoadManager>{new LoadManager{app, parent, journal}};
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
Reference in New Issue
Block a user