traeak commented on code in PR #13843:
URL: https://github.com/apache/trafficserver/pull/13843#discussion_r4287059734
##########
plugins/stats_over_http/stats_over_http.cc:
##########
@@ -1039,32 +885,104 @@ prometheus_v2_out_stats(stats_state *my_state)
APPEND_STAT_PROMETHEUS_NUMERIC("current_time_epoch_ms", "%" PRIu64,
ms_since_epoch());
}
-static void
-stats_process_write(TSCont contp, TSEvent event, stats_state *my_state)
+static std::shared_ptr<const cached_body>
+generate_body(stats_state *my_state)
{
- if (event == TS_EVENT_VCONN_WRITE_READY) {
- if (my_state->body_written == 0) {
- my_state->body_written = 1;
- switch (my_state->output_format) {
- case output_format_t::JSON_OUTPUT:
- json_out_stats(my_state);
- break;
- case output_format_t::CSV_OUTPUT:
- csv_out_stats(my_state);
- break;
- case output_format_t::PROMETHEUS_OUTPUT:
- prometheus_out_stats(my_state);
- break;
- case output_format_t::PROMETHEUS_V2_OUTPUT:
- prometheus_v2_out_stats(my_state);
- break;
- }
+ auto entry = std::make_shared<cached_body>();
+ entry->generated = std::chrono::steady_clock::now();
+
+ switch (my_state->output_format) {
+ case output_format_t::CSV_OUTPUT:
+ csv_out_stats(my_state);
+ break;
+ case output_format_t::PROMETHEUS_OUTPUT:
+ prometheus_out_stats(my_state);
+ break;
+ case output_format_t::PROMETHEUS_V2_OUTPUT:
+ prometheus_v2_out_stats(my_state);
+ break;
+ default:
+ json_out_stats(my_state);
+ break;
+ }
+
+ bool compressed = false;
+
+ switch (my_state->encoding) {
+ case encoding_format_t::GZIP:
+ compressed = gzip_compress(my_state->body, entry->body, GZIP_MODE);
+ break;
+ case encoding_format_t::DEFLATE:
+ compressed = gzip_compress(my_state->body, entry->body, DEFLATE_MODE);
+ break;
+#if HAVE_BROTLI_ENCODE_H
+ case encoding_format_t::BR:
+ compressed = br_compress(my_state->body, entry->body);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ if (compressed) {
+ entry->encoding = my_state->encoding;
+ } else {
+ entry->encoding = encoding_format_t::NONE;
+ entry->body = std::move(my_state->body);
+ }
+ my_state->body.clear();
+ my_state->prometheus_v2_families.clear();
+ my_state->prometheus_v2_family_order.clear();
+
+ return entry;
+}
+
+// Return a fresh cached body if there is one. When it is stale, one request
regenerates it while concurrent requests are
+// served the stale copy, provided it is less than twice the TTL old. Older
copies are not served; those requests regenerate.
+static std::shared_ptr<const cached_body>
+get_body(stats_state *my_state)
+{
+ if (cache_ttl.count() <= 0) {
+ return generate_body(my_state);
+ }
+
+ auto &slot =
body_cache[static_cast<size_t>(my_state->output_format)][static_cast<size_t>(my_state->encoding)];
+ bool owner = false;
+
+ {
+ std::lock_guard lock(body_cache_mutex);
- if (my_state->encoding != encoding_format_t::NONE) {
- compress_out_stats(my_state);
+ if (slot.entry) {
+ auto age = std::chrono::steady_clock::now() - slot.entry->generated;
+
+ if (age < cache_ttl || (slot.refreshing && age < 2 * cache_ttl)) {
+ return slot.entry;
}
- TSVIONBytesSet(my_state->write_vio, my_state->output_bytes);
}
+ if (!slot.refreshing) {
+ slot.refreshing = true;
+ owner = true;
+ }
+ }
Review Comment:
this is no worse than the default mode of the plugin and is very unlikely to
happen. the amount of code including needintg an exclusive lock is not worth
it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]