Refactor nano::rate_observer. This change removes the internal class stat_counter and introduces a simple name->function() rate tracking interface. (#4146)
This commit is contained in:
parent
cbb0126e6a
commit
59b9c38f1e
2 changed files with 49 additions and 67 deletions
|
|
@ -3,58 +3,38 @@
|
|||
#include <nano/test_common/rate_observer.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
/*
|
||||
* rate_observer::counter
|
||||
*/
|
||||
|
||||
std::pair<uint64_t, std::chrono::milliseconds> nano::test::rate_observer::counter::observe ()
|
||||
nano::test::rate_observer::counter::counter (std::string name_a, std::function<value_t ()> count_a) :
|
||||
name{ std::move (name_a) },
|
||||
count{ std::move (count_a) }
|
||||
{
|
||||
}
|
||||
|
||||
nano::test::rate_observer::counter::observation nano::test::rate_observer::counter::observe ()
|
||||
{
|
||||
auto now = std::chrono::system_clock::now ();
|
||||
auto total = count ();
|
||||
if (last_observation.time_since_epoch ().count () > 0)
|
||||
{
|
||||
auto time_delta = std::chrono::duration_cast<std::chrono::milliseconds> (now - last_observation);
|
||||
last_observation = now;
|
||||
return { count (), time_delta };
|
||||
auto delta = total - last_count;
|
||||
last_count = total;
|
||||
return { total, delta, time_delta };
|
||||
}
|
||||
else
|
||||
{
|
||||
last_observation = now;
|
||||
return { 0, std::chrono::milliseconds{ 0 } };
|
||||
last_count = total;
|
||||
return { 0, 0, std::chrono::milliseconds{ 0 } };
|
||||
}
|
||||
}
|
||||
|
||||
nano::test::rate_observer::stat_counter::stat_counter (nano::stats & stats_a, nano::stat::type type_a, nano::stat::detail detail_a, nano::stat::dir dir_a) :
|
||||
stats{ stats_a },
|
||||
type{ type_a },
|
||||
detail{ detail_a },
|
||||
dir{ dir_a }
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* rate_observer::stat_counter
|
||||
*/
|
||||
|
||||
uint64_t nano::test::rate_observer::stat_counter::count ()
|
||||
{
|
||||
uint64_t cnt = stats.count (type, detail, dir);
|
||||
uint64_t delta = cnt - last_count;
|
||||
last_count = cnt;
|
||||
return delta;
|
||||
}
|
||||
|
||||
std::string nano::test::rate_observer::stat_counter::name ()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << nano::to_string (type) << "::" << nano::to_string (detail) << "::" << nano::to_string (dir);
|
||||
return ss.str ();
|
||||
}
|
||||
|
||||
/*
|
||||
* rate_observer
|
||||
*/
|
||||
|
||||
nano::test::rate_observer::~rate_observer ()
|
||||
{
|
||||
if (!stopped.exchange (true))
|
||||
|
|
@ -89,16 +69,25 @@ void nano::test::rate_observer::print_once ()
|
|||
const auto observation = counter->observe ();
|
||||
|
||||
// Convert delta milliseconds to seconds (double precision) and then divide the counter delta to get rate per second
|
||||
auto per_sec = observation.first / (observation.second.count () / 1000.0);
|
||||
auto per_sec = observation.delta / (observation.time_delta.count () / 1000.0);
|
||||
|
||||
std::cout << "rate of '" << counter->name () << "': "
|
||||
std::cout << "rate of '" << counter->name << "': "
|
||||
<< std::setw (12) << std::setprecision (2) << std::fixed << per_sec << " /s"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void nano::test::rate_observer::observe (std::string name, std::function<int64_t ()> observe)
|
||||
{
|
||||
auto counter_instance = std::make_shared<counter> (name, observe);
|
||||
counters.push_back (counter_instance);
|
||||
}
|
||||
|
||||
void nano::test::rate_observer::observe (nano::node & node, nano::stat::type type, nano::stat::detail detail, nano::stat::dir dir)
|
||||
{
|
||||
auto counter = std::make_shared<stat_counter> (node.stats, type, detail, dir);
|
||||
counters.push_back (counter);
|
||||
auto name = std::string{ nano::to_string (type) } + "::" + std::string{ nano::to_string (detail) } + "::" + std::string{ nano::to_string (dir) };
|
||||
|
||||
observe (name, [&node, type, detail, dir] () {
|
||||
return node.stats.count (type, detail, dir);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,42 +15,34 @@ class rate_observer
|
|||
{
|
||||
public:
|
||||
/*
|
||||
* Base class used as a base to build counters
|
||||
* Used as a base to build counters
|
||||
*/
|
||||
class counter
|
||||
class counter final
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Calculate count and time delta since last call
|
||||
*/
|
||||
std::pair<uint64_t, std::chrono::milliseconds> observe ();
|
||||
using value_t = int64_t;
|
||||
|
||||
virtual uint64_t count () = 0;
|
||||
virtual std::string name () = 0;
|
||||
struct observation
|
||||
{
|
||||
value_t total;
|
||||
value_t delta;
|
||||
std::chrono::milliseconds time_delta;
|
||||
};
|
||||
|
||||
public:
|
||||
/*
|
||||
* Calculate value total, value delta and time delta since last call
|
||||
*/
|
||||
observation observe ();
|
||||
|
||||
explicit counter (std::string name, std::function<value_t ()> count);
|
||||
|
||||
const std::string name;
|
||||
const std::function<value_t ()> count;
|
||||
|
||||
private:
|
||||
std::chrono::system_clock::time_point last_observation{};
|
||||
};
|
||||
|
||||
/*
|
||||
* Counter that uses node stat container to provide info about rate
|
||||
*/
|
||||
class stat_counter final : public counter
|
||||
{
|
||||
public:
|
||||
stat_counter (nano::stats & stats, nano::stat::type type, nano::stat::detail detail, nano::stat::dir dir);
|
||||
|
||||
uint64_t count () override;
|
||||
std::string name () override;
|
||||
|
||||
private:
|
||||
const nano::stat::type type;
|
||||
const nano::stat::detail detail;
|
||||
const nano::stat::dir dir;
|
||||
|
||||
uint64_t last_count{ 0 };
|
||||
|
||||
nano::stats & stats;
|
||||
value_t last_count{ 0 };
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -62,6 +54,7 @@ public:
|
|||
*/
|
||||
void background_print (std::chrono::seconds interval);
|
||||
|
||||
void observe (std::string name, std::function<int64_t ()> count);
|
||||
/*
|
||||
* Starts observing a particular node stat from stat container
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue