diff --git a/include/maxscale/response_stat.hh b/include/maxscale/response_stat.hh index d4c437c60..90be34ed0 100644 --- a/include/maxscale/response_stat.hh +++ b/include/maxscale/response_stat.hh @@ -16,33 +16,42 @@ #include #include +/** This could arguably be a utility, but is written specifically for rwsplit + * so it stays here at least for now. + */ namespace maxscale { /** - * Query response time average for a backend. Uses median of N samples to filter noise, - * then uses those medians to calculate the average response time. + * Query response statistics. Uses median of N samples to filter noise, then + * uses those medians to calculate the average response time. + * The class makes an average of the durations between calls to query_started() + * and query_ended(). Once the stats are good, sync_time_reached(int max) returns true, + * based on the average containing at least max samples (or medians), or the time + * sync_duration (constructor arg) has passed since the last reset(). */ class ResponseStat { public: /* - * @param num_filter_samples - collect num samples, use median (digital filter) - * @param sync_duration - this much time between synchronize to server stats. + * @param num_filter_samples - collect num samples, use median + * @param num_synch_medians - this many medians before the average should be synced, or + * @param sync_duration - this much time between syncs. */ - ResponseStat(int num_filter_samples = 9, - maxbase::Duration sync_duration = std::chrono::milliseconds(250)); + ResponseStat(int num_filter_samples = 5, + int num_synch_medians = 500, + maxbase::Duration sync_duration = std::chrono::seconds(5)); void query_started(); - void query_ended(); // ok to call without a query_started - bool make_valid(); // make valid even if there are only filter_samples + void query_ended();// ok to call without a query_started + bool make_valid(); // make valid even if there are too few filter_samples bool is_valid() const; int num_samples() const; maxbase::Duration average() const; - bool sync_time_reached(); // is it time to apply the average to the server? + bool sync_time_reached(); // is it time to apply the average? void reset(); - private: const int m_num_filter_samples; + const int m_num_synch_medians; const maxbase::Duration m_sync_duration; int m_sample_count; std::vector m_samples; // N sampels from which median is used diff --git a/server/core/response_stat.cc b/server/core/response_stat.cc index f090cab66..a198da64d 100644 --- a/server/core/response_stat.cc +++ b/server/core/response_stat.cc @@ -17,8 +17,10 @@ namespace maxscale { ResponseStat::ResponseStat(int num_filter_samples, + int num_synch_medians, maxbase::Duration sync_duration) : m_num_filter_samples {num_filter_samples} + , m_num_synch_medians{num_synch_medians} , m_sync_duration{sync_duration} , m_sample_count{0} , m_samples(num_filter_samples) @@ -37,7 +39,7 @@ void ResponseStat::query_ended() { if (m_last_start == maxbase::TimePoint()) { - // m_last_start is defaulted. Ignore, avoids extra logic at call sites. + // m_last_start is defaulted. Ignore, avoids extra logic in call sites. return; } m_samples[m_sample_count] = maxbase::Clock::now() - m_last_start; @@ -56,11 +58,9 @@ bool ResponseStat::make_valid() { if (!m_average.num_samples() && m_sample_count) { - std::sort(m_samples.begin(), m_samples.begin() + m_sample_count); maxbase::Duration new_sample = m_samples[m_sample_count / 2]; m_average.add(std::chrono::duration(new_sample).count()); m_sample_count = 0; - m_last_start = maxbase::TimePoint(); } return is_valid(); @@ -84,7 +84,8 @@ maxbase::Duration ResponseStat::average() const bool ResponseStat::sync_time_reached() { auto now = maxbase::Clock::now(); - bool reached = m_next_sync < now; + bool reached = m_next_sync < now + || m_average.num_samples() >= m_num_synch_medians; if (reached) { diff --git a/server/modules/monitor/mariadbmon/cluster_manipulation.cc b/server/modules/monitor/mariadbmon/cluster_manipulation.cc index 5fed0e285..1a36eb694 100644 --- a/server/modules/monitor/mariadbmon/cluster_manipulation.cc +++ b/server/modules/monitor/mariadbmon/cluster_manipulation.cc @@ -865,7 +865,7 @@ bool MariaDBMonitor::failover_perform(ClusterOperation& op) wait_cluster_stabilization_ex(op, redirected_slaves); MXS_DEBUG("Failover: slave replication confirmation took %.1f seconds with " "%.1f seconds to spare.", - timer.lap(), op.time_remaining.secs()); + timer.lap().secs(), op.time_remaining.secs()); } } return rval;