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 needing a blocking 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]

Reply via email to