Client::Client(crimson::net::Messenger& msgr,
WithStats& with_stats,
set_perf_queries_cb_t cb_set,
- get_perf_report_cb_t cb_get)
+ get_perf_report_cb_t cb_get,
+ stats_warning_cb_t stats_warning_cb)
: msgr{msgr},
with_stats{with_stats},
report_timer{[this] {report();}},
set_perf_queries_cb(cb_set),
- get_perf_report_cb(cb_get)
+ get_perf_report_cb(cb_get),
+ stats_warning_cb(std::move(stats_warning_cb))
{}
seastar::future<> Client::start()
LOG_PREFIX(Client::report);
DEBUGDPP("", *this);
_send_report();
+ if (stats_in_flight) {
+ ++stats_skip_count;
+ if (stats_skip_count >= STATS_ABANDON_THRESHOLD) {
+ WARNDPP("pg stats send stuck for {} ticks, abandoning and retrying",
+ *this, stats_skip_count);
+ stats_in_flight = false;
+ } else {
+ WARNDPP("pg stats send still in flight, skipped (count={})",
+ *this, stats_skip_count);
+ if (stats_warning_cb &&
+ stats_skip_count % STATS_WARN_INTERVAL == 0) {
+ stats_warning_cb(stats_skip_count);
+ }
+ return;
+ }
+ }
+ stats_in_flight = true;
+ stats_skip_count = 0;
gates.dispatch_in_background(__func__, *this, [this, FNAME] {
DEBUGDPP("dispatching in background", *this);
return with_stats.get_stats(
).then([this](auto &&pg_stats) {
return send(std::move(pg_stats));
+ }).finally([this] {
+ stats_in_flight = false;
});
});
}
using get_perf_report_cb_t = std::function<seastar::future<MetricPayload> ()>;
using set_perf_queries_cb_t =
std::function<seastar::future<> (const ConfigPayload &)>;
+ using stats_warning_cb_t = std::function<void(uint32_t skips)>;
public:
Client(crimson::net::Messenger& msgr,
WithStats& with_stats,
set_perf_queries_cb_t cb_set,
- get_perf_report_cb_t cb_get);
+ get_perf_report_cb_t cb_get,
+ stats_warning_cb_t stats_warning_cb);
seastar::future<> start();
seastar::future<> stop();
seastar::future<> send(MessageURef msg);
std::vector<DaemonHealthMetric> daemon_health_metrics;
+ bool stats_in_flight = false;
+ uint32_t stats_skip_count = 0;
+ // emit a cluster-log warning every this many skipped reports (~60s)
+ static constexpr uint32_t STATS_WARN_INTERVAL = 12;
+ // abandon a stuck in-flight stats send after this many skips (~5min)
+ static constexpr uint32_t STATS_ABANDON_THRESHOLD = 5 * STATS_WARN_INTERVAL;
+ stats_warning_cb_t stats_warning_cb;
+
void _send_report();
};
mgrc{new crimson::mgr::Client{
*public_msgr,
*this,
+ // one lambda to perf-query them all
[this](const ConfigPayload &config_payload) {
return set_perf_queries(config_payload);
},
+ // one lambda to help _send_report() report them all
[this] {
return get_perf_reports();
+ },
+ // one lambda to log-warn if pg stats report is stuck
+ [this](uint32_t skips) {
+ clog->warn() << fmt::format(
+ "pg stats report stuck for ~{}s, store may be overloaded",
+ skips * 5);
}
}},
store{store},