mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15: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:
@@ -238,7 +238,7 @@ public:
|
|||||||
std::weak_ptr<Peer> const& wPeer,
|
std::weak_ptr<Peer> const& wPeer,
|
||||||
std::shared_ptr<protocol::TMGetObjectByHash> const& request,
|
std::shared_ptr<protocol::TMGetObjectByHash> const& request,
|
||||||
uint256 haveLedgerHash,
|
uint256 haveLedgerHash,
|
||||||
std::uint32_t uUptime);
|
UptimeClock::time_point uptime);
|
||||||
|
|
||||||
std::size_t getFetchPackCacheSize () const;
|
std::size_t getFetchPackCacheSize () const;
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#include <ripple/basics/contract.h>
|
#include <ripple/basics/contract.h>
|
||||||
#include <ripple/basics/Log.h>
|
#include <ripple/basics/Log.h>
|
||||||
#include <ripple/basics/TaggedCache.h>
|
#include <ripple/basics/TaggedCache.h>
|
||||||
#include <ripple/basics/UptimeTimer.h>
|
#include <ripple/basics/UptimeClock.h>
|
||||||
#include <ripple/core/TimeKeeper.h>
|
#include <ripple/core/TimeKeeper.h>
|
||||||
#include <ripple/nodestore/DatabaseShard.h>
|
#include <ripple/nodestore/DatabaseShard.h>
|
||||||
#include <ripple/overlay/Overlay.h>
|
#include <ripple/overlay/Overlay.h>
|
||||||
@@ -1792,9 +1792,9 @@ LedgerMaster::makeFetchPack (
|
|||||||
std::weak_ptr<Peer> const& wPeer,
|
std::weak_ptr<Peer> const& wPeer,
|
||||||
std::shared_ptr<protocol::TMGetObjectByHash> const& request,
|
std::shared_ptr<protocol::TMGetObjectByHash> const& request,
|
||||||
uint256 haveLedgerHash,
|
uint256 haveLedgerHash,
|
||||||
std::uint32_t uUptime)
|
UptimeClock::time_point uptime)
|
||||||
{
|
{
|
||||||
if (UptimeTimer::getInstance ().getElapsedSeconds () > (uUptime + 1))
|
if (UptimeClock::now() > uptime + 1s)
|
||||||
{
|
{
|
||||||
JLOG(m_journal.info()) << "Fetch pack request got stale";
|
JLOG(m_journal.info()) << "Fetch pack request got stale";
|
||||||
return;
|
return;
|
||||||
@@ -1916,7 +1916,7 @@ LedgerMaster::makeFetchPack (
|
|||||||
wantLedger = getLedgerByHash (haveLedger->info().parentHash);
|
wantLedger = getLedgerByHash (haveLedger->info().parentHash);
|
||||||
}
|
}
|
||||||
while (wantLedger &&
|
while (wantLedger &&
|
||||||
UptimeTimer::getInstance ().getElapsedSeconds () <= uUptime + 1);
|
UptimeClock::now() <= uptime + 1s);
|
||||||
|
|
||||||
JLOG(m_journal.info())
|
JLOG(m_journal.info())
|
||||||
<< "Built fetch pack with " << reply.objects ().size () << " nodes";
|
<< "Built fetch pack with " << reply.objects ().size () << " nodes";
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include <ripple/app/main/Application.h>
|
#include <ripple/app/main/Application.h>
|
||||||
#include <ripple/app/misc/LoadFeeTrack.h>
|
#include <ripple/app/misc/LoadFeeTrack.h>
|
||||||
#include <ripple/app/misc/NetworkOPs.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/json/to_string.h>
|
||||||
#include <ripple/beast/core/CurrentThreadName.h>
|
#include <ripple/beast/core/CurrentThreadName.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -35,18 +35,16 @@ LoadManager::LoadManager (
|
|||||||
: Stoppable ("LoadManager", parent)
|
: Stoppable ("LoadManager", parent)
|
||||||
, app_ (app)
|
, app_ (app)
|
||||||
, journal_ (journal)
|
, journal_ (journal)
|
||||||
, deadLock_ (0)
|
, deadLock_ ()
|
||||||
, armed_ (false)
|
, armed_ (false)
|
||||||
, stop_ (false)
|
, stop_ (false)
|
||||||
{
|
{
|
||||||
UptimeTimer::getInstance ().beginManualUpdates ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadManager::~LoadManager ()
|
LoadManager::~LoadManager ()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UptimeTimer::getInstance ().endManualUpdates ();
|
|
||||||
onStop ();
|
onStop ();
|
||||||
}
|
}
|
||||||
catch (std::exception const& ex)
|
catch (std::exception const& ex)
|
||||||
@@ -67,9 +65,7 @@ void LoadManager::activateDeadlockDetector ()
|
|||||||
|
|
||||||
void LoadManager::resetDeadlockDetector ()
|
void LoadManager::resetDeadlockDetector ()
|
||||||
{
|
{
|
||||||
auto const elapsedSeconds =
|
auto const elapsedSeconds = UptimeClock::now();
|
||||||
UptimeTimer::getInstance ().getElapsedSeconds ();
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> sl (mutex_);
|
std::lock_guard<std::mutex> sl (mutex_);
|
||||||
deadLock_ = elapsedSeconds;
|
deadLock_ = elapsedSeconds;
|
||||||
}
|
}
|
||||||
@@ -108,24 +104,14 @@ void LoadManager::run ()
|
|||||||
{
|
{
|
||||||
beast::setCurrentThreadName ("LoadManager");
|
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();
|
auto t = clock_type::now();
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
|
|
||||||
while (! (stop || isStopping ()))
|
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.
|
// Copy out shared data under a lock. Use copies outside lock.
|
||||||
std::unique_lock<std::mutex> sl (mutex_);
|
std::unique_lock<std::mutex> sl (mutex_);
|
||||||
auto const deadLock = deadLock_;
|
auto const deadLock = deadLock_;
|
||||||
@@ -134,29 +120,24 @@ void LoadManager::run ()
|
|||||||
sl.unlock();
|
sl.unlock();
|
||||||
|
|
||||||
// Measure the amount of time we have been deadlocked, in seconds.
|
// Measure the amount of time we have been deadlocked, in seconds.
|
||||||
//
|
auto const timeSpentDeadlocked = UptimeClock::now() - deadLock;
|
||||||
// VFALCO NOTE deadLock_ is a canary for detecting the condition.
|
|
||||||
int const timeSpentDeadlocked =
|
|
||||||
UptimeTimer::getInstance ().getElapsedSeconds () - deadLock;
|
|
||||||
|
|
||||||
// VFALCO NOTE I think that "armed" refers to the deadlock detector.
|
auto const reportingIntervalSeconds = 10s;
|
||||||
//
|
|
||||||
int const reportingIntervalSeconds = 10;
|
|
||||||
if (armed && (timeSpentDeadlocked >= reportingIntervalSeconds))
|
if (armed && (timeSpentDeadlocked >= reportingIntervalSeconds))
|
||||||
{
|
{
|
||||||
// Report the deadlocked condition every 10 seconds
|
// Report the deadlocked condition every 10 seconds
|
||||||
if ((timeSpentDeadlocked % reportingIntervalSeconds) == 0)
|
if ((timeSpentDeadlocked % reportingIntervalSeconds) == 0s)
|
||||||
{
|
{
|
||||||
JLOG(journal_.warn())
|
JLOG(journal_.warn())
|
||||||
<< "Server stalled for "
|
<< "Server stalled for "
|
||||||
<< timeSpentDeadlocked << " seconds.";
|
<< timeSpentDeadlocked.count() << " seconds.";
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we go over 500 seconds spent deadlocked, it means that
|
// If we go over 500 seconds spent deadlocked, it means that
|
||||||
// the deadlock resolution code has failed, which qualifies
|
// the deadlock resolution code has failed, which qualifies
|
||||||
// as undefined behavior.
|
// as undefined behavior.
|
||||||
//
|
//
|
||||||
assert (timeSpentDeadlocked < 500);
|
assert (timeSpentDeadlocked < 500s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,18 +159,17 @@ void LoadManager::run ()
|
|||||||
app_.getOPs ().reportFeeChange ();
|
app_.getOPs ().reportFeeChange ();
|
||||||
}
|
}
|
||||||
|
|
||||||
t += std::chrono::seconds (1);
|
t += 1s;
|
||||||
auto const duration = t - clock_type::now();
|
auto const duration = t - clock_type::now();
|
||||||
|
|
||||||
if ((duration < std::chrono::seconds (0)) ||
|
if ((duration < 0s) || (duration > 1s))
|
||||||
(duration > std::chrono::seconds (1)))
|
|
||||||
{
|
{
|
||||||
JLOG(journal_.warn()) << "time jump";
|
JLOG(journal_.warn()) << "time jump";
|
||||||
t = clock_type::now();
|
t = clock_type::now();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
alertable_sleep_for(duration);
|
alertable_sleep_until(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +182,7 @@ std::unique_ptr<LoadManager>
|
|||||||
make_LoadManager (Application& app,
|
make_LoadManager (Application& app,
|
||||||
Stoppable& parent, beast::Journal journal)
|
Stoppable& parent, beast::Journal journal)
|
||||||
{
|
{
|
||||||
return std::make_unique<LoadManager>(app, parent, journal);
|
return std::unique_ptr<LoadManager>{new LoadManager{app, parent, journal}};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -42,16 +42,6 @@ class Application;
|
|||||||
*/
|
*/
|
||||||
class LoadManager : public Stoppable
|
class LoadManager : public Stoppable
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
// It would be better if the LoadManager constructor could be private
|
|
||||||
// with std::make_unique as a friend. But Visual Studio can't currently
|
|
||||||
// swallow the following friend declaration (Microsoft (R) C/C++
|
|
||||||
// Optimizing Compiler Version 19.00.23026 for x64). So we make the
|
|
||||||
// constructor public.
|
|
||||||
// template<class T, class... Args>
|
|
||||||
// friend std::unique_ptr<T> std::make_unique (Args&&... args);
|
|
||||||
|
|
||||||
// Should only be constructible by std::make_unique.
|
|
||||||
LoadManager (Application& app, Stoppable& parent, beast::Journal journal);
|
LoadManager (Application& app, Stoppable& parent, beast::Journal journal);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -105,9 +95,13 @@ private:
|
|||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
std::mutex mutex_; // Guards deadLock_, armed_, and stop_.
|
std::mutex mutex_; // Guards deadLock_, armed_, and stop_.
|
||||||
|
|
||||||
int deadLock_; // Detect server deadlocks.
|
UptimeClock::time_point deadLock_; // Detect server deadlocks.
|
||||||
bool armed_;
|
bool armed_;
|
||||||
bool stop_;
|
bool stop_;
|
||||||
|
|
||||||
|
friend
|
||||||
|
std::unique_ptr<LoadManager>
|
||||||
|
make_LoadManager(Application& app, Stoppable& parent, beast::Journal journal);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<LoadManager>
|
std::unique_ptr<LoadManager>
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
#include <ripple/app/tx/apply.h>
|
#include <ripple/app/tx/apply.h>
|
||||||
#include <ripple/basics/mulDiv.h>
|
#include <ripple/basics/mulDiv.h>
|
||||||
#include <ripple/basics/PerfLog.h>
|
#include <ripple/basics/PerfLog.h>
|
||||||
#include <ripple/basics/UptimeTimer.h>
|
#include <ripple/basics/UptimeClock.h>
|
||||||
#include <ripple/core/ConfigSections.h>
|
#include <ripple/core/ConfigSections.h>
|
||||||
#include <ripple/crypto/csprng.h>
|
#include <ripple/crypto/csprng.h>
|
||||||
#include <ripple/crypto/RFC1751.h>
|
#include <ripple/crypto/RFC1751.h>
|
||||||
@@ -2335,7 +2335,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
info[jss::state_accounting] = accounting_.json();
|
info[jss::state_accounting] = accounting_.json();
|
||||||
info[jss::uptime] = UptimeTimer::getInstance ().getElapsedSeconds ();
|
info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
|
||||||
info[jss::jq_trans_overflow] = std::to_string(
|
info[jss::jq_trans_overflow] = std::to_string(
|
||||||
app_.overlay().getJqTransOverflow());
|
app_.overlay().getJqTransOverflow());
|
||||||
info[jss::peer_disconnects] = std::to_string(
|
info[jss::peer_disconnects] = std::to_string(
|
||||||
|
|||||||
@@ -20,39 +20,47 @@
|
|||||||
#ifndef RIPPLE_BASICS_UPTIMETIMER_H_INCLUDED
|
#ifndef RIPPLE_BASICS_UPTIMETIMER_H_INCLUDED
|
||||||
#define RIPPLE_BASICS_UPTIMETIMER_H_INCLUDED
|
#define RIPPLE_BASICS_UPTIMETIMER_H_INCLUDED
|
||||||
|
|
||||||
#include <ctime>
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <ratio>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
/** Tracks program uptime.
|
/** Tracks program uptime to seconds precision.
|
||||||
|
|
||||||
The timer can be switched to a manual system of updating, to reduce
|
The timer caches the current time as a performance optimization.
|
||||||
system calls. (?)
|
This allows clients to query the current time thousands of times
|
||||||
|
per second.
|
||||||
*/
|
*/
|
||||||
// VFALCO TODO determine if the non-manual timing is actually needed
|
|
||||||
class UptimeTimer
|
class UptimeClock
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
UptimeTimer ();
|
|
||||||
~UptimeTimer ();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int getElapsedSeconds () const;
|
using rep = int;
|
||||||
|
using period = std::ratio<1>;
|
||||||
|
using duration = std::chrono::duration<rep, period>;
|
||||||
|
using time_point = std::chrono::time_point<UptimeClock>;
|
||||||
|
static constexpr bool is_steady = std::chrono::system_clock::is_steady;
|
||||||
|
|
||||||
void beginManualUpdates ();
|
explicit UptimeClock() = default;
|
||||||
void endManualUpdates ();
|
|
||||||
|
|
||||||
void incrementElapsedTime ();
|
static time_point now(); // seconds since rippled program start
|
||||||
|
|
||||||
static UptimeTimer& getInstance ();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// VFALCO DEPRECATED, Use a memory barrier instead of forcing a cache line
|
static std::atomic<rep> now_;
|
||||||
int volatile m_elapsedTime;
|
static std::atomic<bool> stop_;
|
||||||
|
|
||||||
time_t m_startTime;
|
struct update_thread
|
||||||
|
: private std::thread
|
||||||
|
{
|
||||||
|
~update_thread();
|
||||||
|
update_thread(update_thread&&) = default;
|
||||||
|
|
||||||
bool m_isUpdatingManually;
|
using std::thread::thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
static update_thread start_clock();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
73
src/ripple/basics/impl/UptimeClock.cpp
Normal file
73
src/ripple/basics/impl/UptimeClock.cpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <ripple/basics/UptimeClock.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
std::atomic<UptimeClock::rep> UptimeClock::now_{0}; // seconds since start
|
||||||
|
std::atomic<bool> UptimeClock::stop_{false}; // stop update thread
|
||||||
|
|
||||||
|
// On rippled shutdown, cancel and wait for the update thread
|
||||||
|
UptimeClock::update_thread::~update_thread()
|
||||||
|
{
|
||||||
|
if (joinable())
|
||||||
|
{
|
||||||
|
stop_ = true;
|
||||||
|
// This join() may take up to a 1s, but happens only
|
||||||
|
// once at rippled shutdown.
|
||||||
|
join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launch the update thread
|
||||||
|
UptimeClock::update_thread
|
||||||
|
UptimeClock::start_clock()
|
||||||
|
{
|
||||||
|
return update_thread{[]
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
|
// Wake up every second and update now_
|
||||||
|
auto next = system_clock::now() + 1s;
|
||||||
|
while (!stop_)
|
||||||
|
{
|
||||||
|
this_thread::sleep_until(next);
|
||||||
|
next += 1s;
|
||||||
|
++now_;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// This actually measures time since first use, instead of since rippled start.
|
||||||
|
// However the difference between these two epochs is a small fraction of a second
|
||||||
|
// and unimportant.
|
||||||
|
|
||||||
|
UptimeClock::time_point
|
||||||
|
UptimeClock::now()
|
||||||
|
{
|
||||||
|
// start the update thread on first use
|
||||||
|
static const auto init = start_clock();
|
||||||
|
|
||||||
|
// Return the number of seconds since rippled start
|
||||||
|
return time_point{duration{now_}};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // ripple
|
||||||
@@ -1,82 +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.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#include <ripple/basics/UptimeTimer.h>
|
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
namespace ripple {
|
|
||||||
|
|
||||||
UptimeTimer::UptimeTimer ()
|
|
||||||
: m_elapsedTime (0)
|
|
||||||
, m_startTime (::time (0))
|
|
||||||
, m_isUpdatingManually (false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
UptimeTimer::~UptimeTimer ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int UptimeTimer::getElapsedSeconds () const
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (m_isUpdatingManually)
|
|
||||||
{
|
|
||||||
std::atomic_thread_fence (std::memory_order_seq_cst);
|
|
||||||
result = m_elapsedTime;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// VFALCO TODO use time_t instead of int return
|
|
||||||
result = static_cast <int> (::time (0) - m_startTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UptimeTimer::beginManualUpdates ()
|
|
||||||
{
|
|
||||||
//assert (!m_isUpdatingManually);
|
|
||||||
|
|
||||||
m_isUpdatingManually = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UptimeTimer::endManualUpdates ()
|
|
||||||
{
|
|
||||||
//assert (m_isUpdatingManually);
|
|
||||||
|
|
||||||
m_isUpdatingManually = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UptimeTimer::incrementElapsedTime ()
|
|
||||||
{
|
|
||||||
//assert (m_isUpdatingManually);
|
|
||||||
++m_elapsedTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
UptimeTimer& UptimeTimer::getInstance ()
|
|
||||||
{
|
|
||||||
static UptimeTimer instance;
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // ripple
|
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#ifndef RIPPLE_CORE_LOADMONITOR_H_INCLUDED
|
#ifndef RIPPLE_CORE_LOADMONITOR_H_INCLUDED
|
||||||
#define RIPPLE_CORE_LOADMONITOR_H_INCLUDED
|
#define RIPPLE_CORE_LOADMONITOR_H_INCLUDED
|
||||||
|
|
||||||
|
#include <ripple/basics/UptimeClock.h>
|
||||||
#include <ripple/core/LoadEvent.h>
|
#include <ripple/core/LoadEvent.h>
|
||||||
#include <ripple/beast/utility/Journal.h>
|
#include <ripple/beast/utility/Journal.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@@ -73,7 +74,7 @@ private:
|
|||||||
std::chrono::milliseconds mLatencyMSPeak;
|
std::chrono::milliseconds mLatencyMSPeak;
|
||||||
std::chrono::milliseconds mTargetLatencyAvg;
|
std::chrono::milliseconds mTargetLatencyAvg;
|
||||||
std::chrono::milliseconds mTargetLatencyPk;
|
std::chrono::milliseconds mTargetLatencyPk;
|
||||||
int mLastUpdate;
|
UptimeClock::time_point mLastUpdate;
|
||||||
beast::Journal j_;
|
beast::Journal j_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -226,10 +226,9 @@ public:
|
|||||||
|
|
||||||
@return `true` if we are stopping
|
@return `true` if we are stopping
|
||||||
*/
|
*/
|
||||||
template <class Rep, class Period>
|
|
||||||
bool
|
bool
|
||||||
alertable_sleep_for(
|
alertable_sleep_until(
|
||||||
std::chrono::duration<Rep, Period> const& d);
|
std::chrono::system_clock::time_point const& t);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Called by derived classes to indicate that the stoppable has stopped. */
|
/** Called by derived classes to indicate that the stoppable has stopped. */
|
||||||
@@ -373,10 +372,9 @@ public:
|
|||||||
|
|
||||||
@return `true` if we are stopping
|
@return `true` if we are stopping
|
||||||
*/
|
*/
|
||||||
template <class Rep, class Period>
|
|
||||||
bool
|
bool
|
||||||
alertable_sleep_for(
|
alertable_sleep_until(
|
||||||
std::chrono::duration<Rep, Period> const& d);
|
std::chrono::system_clock::time_point const& t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Notify a root stoppable and children to stop, without waiting.
|
/* Notify a root stoppable and children to stop, without waiting.
|
||||||
@@ -407,23 +405,23 @@ JobCounter& Stoppable::jobCounter ()
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template <class Rep, class Period>
|
inline
|
||||||
bool
|
bool
|
||||||
RootStoppable::alertable_sleep_for(
|
RootStoppable::alertable_sleep_until(
|
||||||
std::chrono::duration<Rep, Period> const& d)
|
std::chrono::system_clock::time_point const& t)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_);
|
std::unique_lock<std::mutex> lock(m_);
|
||||||
if (m_calledStop)
|
if (m_calledStop)
|
||||||
return true;
|
return true;
|
||||||
return c_.wait_for(lock, d, [this]{return m_calledStop.load();});
|
return c_.wait_until(lock, t, [this]{return m_calledStop.load();});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Rep, class Period>
|
inline
|
||||||
bool
|
bool
|
||||||
Stoppable::alertable_sleep_for(
|
Stoppable::alertable_sleep_until(
|
||||||
std::chrono::duration<Rep, Period> const& d)
|
std::chrono::system_clock::time_point const& t)
|
||||||
{
|
{
|
||||||
return m_root.alertable_sleep_for(d);
|
return m_root.alertable_sleep_until(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include <ripple/basics/Log.h>
|
#include <ripple/basics/Log.h>
|
||||||
#include <ripple/basics/UptimeTimer.h>
|
#include <ripple/basics/UptimeClock.h>
|
||||||
#include <ripple/basics/date.h>
|
#include <ripple/basics/date.h>
|
||||||
#include <ripple/core/LoadMonitor.h>
|
#include <ripple/core/LoadMonitor.h>
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ LoadMonitor::LoadMonitor (beast::Journal j)
|
|||||||
, mLatencyMSPeak (0)
|
, mLatencyMSPeak (0)
|
||||||
, mTargetLatencyAvg (0)
|
, mTargetLatencyAvg (0)
|
||||||
, mTargetLatencyPk (0)
|
, mTargetLatencyPk (0)
|
||||||
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
|
, mLastUpdate (UptimeClock::now())
|
||||||
, j_ (j)
|
, j_ (j)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -66,12 +66,12 @@ LoadMonitor::LoadMonitor (beast::Journal j)
|
|||||||
void LoadMonitor::update ()
|
void LoadMonitor::update ()
|
||||||
{
|
{
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
|
auto now = UptimeClock::now();
|
||||||
if (now == mLastUpdate) // current
|
if (now == mLastUpdate) // current
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// VFALCO TODO Why 8?
|
// VFALCO TODO Why 8?
|
||||||
if ((now < mLastUpdate) || (now > (mLastUpdate + 8)))
|
if ((now < mLastUpdate) || (now > (mLastUpdate + 8s)))
|
||||||
{
|
{
|
||||||
// way out of date
|
// way out of date
|
||||||
mCounts = 0;
|
mCounts = 0;
|
||||||
@@ -93,7 +93,7 @@ void LoadMonitor::update ()
|
|||||||
*/
|
*/
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
++mLastUpdate;
|
mLastUpdate += 1s;
|
||||||
mCounts -= ((mCounts + 3) / 4);
|
mCounts -= ((mCounts + 3) / 4);
|
||||||
mLatencyEvents -= ((mLatencyEvents + 3) / 4);
|
mLatencyEvents -= ((mLatencyEvents + 3) / 4);
|
||||||
mLatencyMSAvg -= (mLatencyMSAvg / 4);
|
mLatencyMSAvg -= (mLatencyMSAvg / 4);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <ripple/app/misc/ValidatorList.h>
|
#include <ripple/app/misc/ValidatorList.h>
|
||||||
#include <ripple/app/tx/apply.h>
|
#include <ripple/app/tx/apply.h>
|
||||||
#include <ripple/basics/random.h>
|
#include <ripple/basics/random.h>
|
||||||
#include <ripple/basics/UptimeTimer.h>
|
#include <ripple/basics/UptimeClock.h>
|
||||||
#include <ripple/beast/core/LexicalCast.h>
|
#include <ripple/beast/core/LexicalCast.h>
|
||||||
#include <ripple/beast/core/SemanticVersion.h>
|
#include <ripple/beast/core/SemanticVersion.h>
|
||||||
#include <ripple/nodestore/DatabaseShard.h>
|
#include <ripple/nodestore/DatabaseShard.h>
|
||||||
@@ -1864,7 +1864,7 @@ PeerImp::doFetchPack (const std::shared_ptr<protocol::TMGetObjectByHash>& packet
|
|||||||
memcpy (hash.begin (), packet->ledgerhash ().data (), 32);
|
memcpy (hash.begin (), packet->ledgerhash ().data (), 32);
|
||||||
|
|
||||||
std::weak_ptr<PeerImp> weak = shared_from_this();
|
std::weak_ptr<PeerImp> weak = shared_from_this();
|
||||||
auto elapsed = UptimeTimer::getInstance().getElapsedSeconds();
|
auto elapsed = UptimeClock::now();
|
||||||
auto const pap = &app_;
|
auto const pap = &app_;
|
||||||
app_.getJobQueue ().addJob (
|
app_.getJobQueue ().addJob (
|
||||||
jtPACK, "MakeFetchPack",
|
jtPACK, "MakeFetchPack",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include <ripple/app/ledger/LedgerMaster.h>
|
#include <ripple/app/ledger/LedgerMaster.h>
|
||||||
#include <ripple/app/main/Application.h>
|
#include <ripple/app/main/Application.h>
|
||||||
#include <ripple/app/misc/NetworkOPs.h>
|
#include <ripple/app/misc/NetworkOPs.h>
|
||||||
#include <ripple/basics/UptimeTimer.h>
|
#include <ripple/basics/UptimeClock.h>
|
||||||
#include <ripple/core/DatabaseCon.h>
|
#include <ripple/core/DatabaseCon.h>
|
||||||
#include <ripple/json/json_value.h>
|
#include <ripple/json/json_value.h>
|
||||||
#include <ripple/ledger/CachedSLEs.h>
|
#include <ripple/ledger/CachedSLEs.h>
|
||||||
@@ -36,10 +36,11 @@
|
|||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
static
|
static
|
||||||
void textTime (
|
void
|
||||||
std::string& text, int& seconds, const char* unitName, int unitVal)
|
textTime(std::string& text, UptimeClock::time_point& seconds,
|
||||||
|
const char* unitName, std::chrono::seconds unitVal)
|
||||||
{
|
{
|
||||||
int i = seconds / unitVal;
|
auto i = seconds.time_since_epoch() / unitVal;
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return;
|
return;
|
||||||
@@ -111,12 +112,12 @@ Json::Value doGetCounts (RPC::Context& context)
|
|||||||
ret[jss::treenode_track_size] = context.app.family().treecache().getTrackSize();
|
ret[jss::treenode_track_size] = context.app.family().treecache().getTrackSize();
|
||||||
|
|
||||||
std::string uptime;
|
std::string uptime;
|
||||||
int s = UptimeTimer::getInstance ().getElapsedSeconds ();
|
auto s = UptimeClock::now();
|
||||||
textTime (uptime, s, "year", 365 * 24 * 60 * 60);
|
textTime (uptime, s, "year", 365 * 24h);
|
||||||
textTime (uptime, s, "day", 24 * 60 * 60);
|
textTime (uptime, s, "day", 24h);
|
||||||
textTime (uptime, s, "hour", 60 * 60);
|
textTime (uptime, s, "hour", 1h);
|
||||||
textTime (uptime, s, "minute", 60);
|
textTime (uptime, s, "minute", 1min);
|
||||||
textTime (uptime, s, "second", 1);
|
textTime (uptime, s, "second", 1s);
|
||||||
ret[jss::uptime] = uptime;
|
ret[jss::uptime] = uptime;
|
||||||
|
|
||||||
ret[jss::node_writes] = context.app.getNodeStore().getStoreCount();
|
ret[jss::node_writes] = context.app.getNodeStore().getStoreCount();
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <ripple/basics/impl/strHex.cpp>
|
#include <ripple/basics/impl/strHex.cpp>
|
||||||
#include <ripple/basics/impl/StringUtilities.cpp>
|
#include <ripple/basics/impl/StringUtilities.cpp>
|
||||||
#include <ripple/basics/impl/Sustain.cpp>
|
#include <ripple/basics/impl/Sustain.cpp>
|
||||||
#include <ripple/basics/impl/UptimeTimer.cpp>
|
#include <ripple/basics/impl/UptimeClock.cpp>
|
||||||
|
|
||||||
#if DOXYGEN
|
#if DOXYGEN
|
||||||
#include <ripple/basics/README.md>
|
#include <ripple/basics/README.md>
|
||||||
|
|||||||
Reference in New Issue
Block a user