Cache RenderPlan

This commit is contained in:
2025-09-03 10:53:11 -04:00
parent 8763daca8e
commit 721f814785

View File

@@ -351,9 +351,6 @@ struct Metric {
static_assert(std::is_trivially_destructible_v<Histogram::State>); static_assert(std::is_trivially_destructible_v<Histogram::State>);
static std::mutex mutex; static std::mutex mutex;
// Use to invalidate the render plan cache
static uint64_t registration_version;
// Global arena allocator for metric families and persistent global state // Global arena allocator for metric families and persistent global state
static ArenaAllocator &get_global_arena() { static ArenaAllocator &get_global_arena() {
static auto *global_arena = static auto *global_arena =
@@ -746,11 +743,17 @@ struct Metric {
ArenaAllocator arena; ArenaAllocator arena;
ArenaVector<std::string_view> static_text{&arena}; ArenaVector<std::string_view> static_text{&arena};
ArenaVector<RenderInstruction> instructions{&arena}; ArenaVector<RenderInstruction> instructions{&arena};
uint64_t registration_version;
}; };
// Use to invalidate the render plan cache
static uint64_t registration_version;
static std::unique_ptr<RenderPlan> cached_plan;
// Phase 1: Compile phase - generate static text and instructions // Phase 1: Compile phase - generate static text and instructions
static RenderPlan compile_render_plan() { static std::unique_ptr<RenderPlan> compile_render_plan() {
RenderPlan plan; RenderPlan plan;
plan.registration_version = registration_version;
Metric::LabelSets label_sets = Metric::build_label_sets(plan.arena); Metric::LabelSets label_sets = Metric::build_label_sets(plan.arena);
@@ -890,7 +893,7 @@ struct Metric {
// Callback instructions and static text // Callback instructions and static text
for (const auto &[labels_key, callback] : family->callbacks) { for (const auto &[labels_key, callback] : family->callbacks) {
plan.instructions.push_back(CallCounterCallback{&callback}); plan.instructions.push_back(CallGaugeCallback{&callback});
plan.static_text.push_back(format( plan.static_text.push_back(format(
plan.arena, "%.*s\n%.*s%.*s ", static_cast<int>(help_line.size()), plan.arena, "%.*s\n%.*s%.*s ", static_cast<int>(help_line.size()),
help_line.data(), static_cast<int>(name.length()), name.data(), help_line.data(), static_cast<int>(name.length()), name.data(),
@@ -965,7 +968,7 @@ struct Metric {
} }
} }
return plan; return std::make_unique<RenderPlan>(std::move(plan));
} }
// Phase 2: Execute phase - run instructions and generate dynamic text // Phase 2: Execute phase - run instructions and generate dynamic text
@@ -1540,15 +1543,18 @@ std::span<std::string_view> render(ArenaAllocator &arena) {
std::unique_lock<std::mutex> _{Metric::mutex}; std::unique_lock<std::mutex> _{Metric::mutex};
// Phase 1: Compile - generate static text and instructions // Phase 1: Compile - generate static text and instructions
Metric::RenderPlan plan = Metric::compile_render_plan(); if (!Metric::cached_plan || Metric::cached_plan->registration_version !=
Metric::registration_version) {
Metric::cached_plan = Metric::compile_render_plan();
}
// Phase 2: Execute - run instructions and generate dynamic text // Phase 2: Execute - run instructions and generate dynamic text
ArenaVector<std::string_view> dynamic_text = ArenaVector<std::string_view> dynamic_text =
Metric::execute_render_plan(arena, plan.instructions); Metric::execute_render_plan(arena, Metric::cached_plan->instructions);
// Phase 3: Present - interleave static and dynamic text // Phase 3: Present - interleave static and dynamic text
ArenaVector<std::string_view> output = ArenaVector<std::string_view> output = Metric::present_render_output(
Metric::present_render_output(arena, plan.static_text, dynamic_text); arena, Metric::cached_plan->static_text, dynamic_text);
return output; return output;
} }
@@ -1607,6 +1613,7 @@ void Family<Gauge>::register_callback(
// Static member definitions // Static member definitions
std::mutex Metric::mutex; std::mutex Metric::mutex;
uint64_t Metric::registration_version; uint64_t Metric::registration_version;
std::unique_ptr<Metric::RenderPlan> Metric::cached_plan;
thread_local Metric::ThreadInit Metric::thread_init; thread_local Metric::ThreadInit Metric::thread_init;
void reset_metrics_for_testing() { void reset_metrics_for_testing() {