This is an automated email from the ASF dual-hosted git repository.

spetz pushed a commit to branch bench_best_pick_fix
in repository https://gitbox.apache.org/repos/asf/iggy.git

commit 49918aaa7d39936965de3298de254544a881c80a
Author: spetz <[email protected]>
AuthorDate: Tue Apr 21 11:50:10 2026 +0200

    fix(bench): anchor hero display to showcase pick, fix gitref links
---
 .../frontend/src/components/app_content.rs         |   4 +-
 .../frontend/src/components/layout/hero.rs         | 189 +++++++++++++++++----
 .../frontend/src/components/layout/main_content.rs |  30 ++--
 3 files changed, 172 insertions(+), 51 deletions(-)

diff --git a/core/bench/dashboard/frontend/src/components/app_content.rs 
b/core/bench/dashboard/frontend/src/components/app_content.rs
index e3dc1a3c6..beb65d7b5 100644
--- a/core/bench/dashboard/frontend/src/components/app_content.rs
+++ b/core/bench/dashboard/frontend/src/components/app_content.rs
@@ -263,9 +263,9 @@ pub fn app_content() -> Html {
             <TopAppBar show_sidebar_toggle={show_detail} 
show_detail_actions={show_detail} />
             if show_detail {
                 <Sidebar />
-                <MainContent 
selected_gitref={gitref_ctx.state.selected_gitref.clone().unwrap_or_default()} 
/>
+                <MainContent />
             } else {
-                <Hero 
selected_gitref={gitref_ctx.state.selected_gitref.clone().unwrap_or_default()} 
/>
+                <Hero />
             }
         </div>
     }
diff --git a/core/bench/dashboard/frontend/src/components/layout/hero.rs 
b/core/bench/dashboard/frontend/src/components/layout/hero.rs
index a5905d87a..899ccfc85 100644
--- a/core/bench/dashboard/frontend/src/components/layout/hero.rs
+++ b/core/bench/dashboard/frontend/src/components/layout/hero.rs
@@ -19,7 +19,7 @@ use crate::api;
 use crate::components::chart::tail_chart::TailChart;
 use crate::format::format_ms;
 use crate::router::AppRoute;
-use crate::state::benchmark::{latest_sweep, pick_best_from_recent_batch, 
use_benchmark};
+use crate::state::benchmark::{latest_sweep, pick_best_from_recent_batch};
 use bench_dashboard_shared::BenchmarkReportLight;
 use chrono::DateTime;
 use gloo::console::log;
@@ -30,14 +30,11 @@ use yew::platform::spawn_local;
 use yew::prelude::*;
 use yew_router::prelude::{Navigator, use_navigator};
 
-#[derive(Properties, PartialEq)]
-pub struct HeroProps {
-    pub selected_gitref: String,
-}
+#[derive(Properties, PartialEq, Default)]
+pub struct HeroProps;
 
 #[function_component(Hero)]
-pub fn hero(props: &HeroProps) -> Html {
-    let benchmark_ctx = use_benchmark();
+pub fn hero(_props: &HeroProps) -> Html {
     let navigator = use_navigator();
     let (is_dark, _) = use_context::<(bool, Callback<()>)>().expect("Theme 
context not found");
     let recent = use_state(Vec::<BenchmarkReportLight>::new);
@@ -97,17 +94,11 @@ pub fn hero(props: &HeroProps) -> Html {
         return render_hero_loading(is_dark, true);
     }
 
-    let hardware = benchmark_ctx
-        .state
-        .current_hardware
-        .clone()
-        .unwrap_or_default();
-    let sweep_gitref = stats
+    let display = stats
         .showcase
         .as_ref()
-        .and_then(|showcase| showcase.params.gitref.clone())
-        .filter(|gitref| !gitref.is_empty())
-        .or_else(|| Some(props.selected_gitref.clone()).filter(|gitref| 
!gitref.is_empty()));
+        .map(showcase_display)
+        .unwrap_or_default();
 
     let on_view_details = stats.showcase.as_ref().map(|showcase| {
         let uuid = showcase.uuid.to_string();
@@ -135,7 +126,7 @@ pub fn hero(props: &HeroProps) -> Html {
         <div class="hero-v2">
             { render_background_grid() }
             <div class="hero-v2-inner">
-                { render_headline(&stats, &hardware, sweep_gitref.as_deref(), 
&on_browse_click) }
+                { render_headline(&display, &on_browse_click) }
                 { render_stat_cards(&stats) }
                 {
                     match (stats.showcase.as_ref(), on_view_details) {
@@ -256,29 +247,16 @@ fn render_background_grid() -> Html {
     }
 }
 
-fn render_headline(
-    stats: &HeroStats,
-    hardware: &str,
-    gitref: Option<&str>,
-    on_browse_click: &Callback<MouseEvent>,
-) -> Html {
-    let (value, unit, subject) = match &stats.peak_mb_s {
-        Some((throughput, name)) => {
-            let (formatted, unit) = format_throughput_bytes(*throughput);
-            (formatted, unit, name.clone())
-        }
-        None => ("-".to_string(), "MB/s", String::new()),
-    };
-
+fn render_headline(display: &ShowcaseDisplay, on_browse_click: 
&Callback<MouseEvent>) -> Html {
     html! {
         <div class="hero-v2-headline">
             <div class="hero-v2-eyebrow">{"Peak sustained throughput"}</div>
             <h1 class="hero-v2-title">
-                <span class="hero-v2-big">{value}</span>
-                <span class="hero-v2-unit">{unit}</span>
+                <span 
class="hero-v2-big">{display.formatted_value.clone()}</span>
+                <span class="hero-v2-unit">{display.unit}</span>
             </h1>
             <p class="hero-v2-sub">
-                { render_hero_sub(&subject, hardware, gitref) }
+                { render_hero_sub(&display.pretty_name, &display.cpu_name, 
display.gitref.as_deref()) }
             </p>
             <p class="hero-v2-tagline">
                 {"Modern hardware is incredibly capable. "}
@@ -343,7 +321,11 @@ fn render_hero_sub(subject: &str, hardware: &str, gitref: 
Option<&str>) -> Html
 }
 
 fn iggy_gitref_url(gitref: &str) -> String {
-    format!("https://github.com/apache/iggy/tree/{gitref}";)
+    if crate::version::parse_semver_recency(gitref).is_some() {
+        format!("https://github.com/apache/iggy/tree/server-{gitref}";)
+    } else {
+        format!("https://github.com/apache/iggy/tree/{gitref}";)
+    }
 }
 
 fn render_stat_cards(stats: &HeroStats) -> Html {
@@ -515,3 +497,140 @@ fn render_hero_loading(is_dark: bool, is_slow: bool) -> 
Html {
         </div>
     }
 }
+
+/// Every headline field comes from the SAME benchmark that powers the
+/// tail chart and "View details" link. Built through this single helper
+/// so the big number, subject name, CPU, and gitref can never drift to
+/// different benchmarks.
+#[derive(Default, Debug, PartialEq)]
+pub struct ShowcaseDisplay {
+    pub formatted_value: String,
+    pub unit: &'static str,
+    pub pretty_name: String,
+    pub cpu_name: String,
+    pub gitref: Option<String>,
+}
+
+pub fn showcase_display(showcase: &BenchmarkReportLight) -> ShowcaseDisplay {
+    let throughput = showcase
+        .group_metrics
+        .first()
+        .map(|metrics| metrics.summary.total_throughput_megabytes_per_second);
+    let (formatted_value, unit) = match throughput {
+        Some(value) => {
+            let (formatted, unit) = format_throughput_bytes(value);
+            (formatted, unit)
+        }
+        None => ("-".to_string(), "MB/s"),
+    };
+    let cpu_name = showcase.hardware.cpu_name.clone();
+    let gitref = showcase
+        .params
+        .gitref
+        .clone()
+        .filter(|gitref| !gitref.is_empty());
+    ShowcaseDisplay {
+        formatted_value,
+        unit,
+        pretty_name: showcase.params.pretty_name.clone(),
+        cpu_name,
+        gitref,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use bench_dashboard_shared::BenchmarkGroupMetricsLight;
+    use bench_report::group_metrics_kind::GroupMetricsKind;
+    use bench_report::group_metrics_summary::BenchmarkGroupMetricsSummary;
+
+    #[test]
+    fn 
given_showcase_benchmark_when_building_display_should_copy_fields_verbatim() {
+        let showcase = showcase_fixture(
+            "pinned-producer 64P-1000B",
+            "AMD Ryzen 9 7950X3D",
+            Some("0.7.0-edge.3"),
+            1_200.0,
+        );
+
+        let display = showcase_display(&showcase);
+
+        assert_eq!(display.pretty_name, "pinned-producer 64P-1000B");
+        assert_eq!(display.cpu_name, "AMD Ryzen 9 7950X3D");
+        assert_eq!(display.gitref.as_deref(), Some("0.7.0-edge.3"));
+        assert_eq!(display.formatted_value, "1.20");
+        assert_eq!(display.unit, "GB/s");
+    }
+
+    #[test]
+    fn 
given_showcase_benchmark_when_rendering_should_never_mix_fields_from_other_benchmarks()
 {
+        let peak_throughput =
+            showcase_fixture("peak-throughput-run", "Decoy CPU", 
Some("0.6.0"), 9_999.0);
+        let lowest_p99 =
+            showcase_fixture("lowest-p99-run", "Real CPU", 
Some("0.7.0-edge.1"), 800.0);
+
+        // Hero always reads from THE SHOWCASE (lowest_p99), never from a
+        // sibling like peak_throughput. Changing peak_throughput must not
+        // affect the output of showcase_display(&lowest_p99).
+        let _ignored = showcase_display(&peak_throughput);
+        let display = showcase_display(&lowest_p99);
+
+        assert_eq!(display.pretty_name, "lowest-p99-run");
+        assert_eq!(display.cpu_name, "Real CPU");
+        assert_eq!(display.gitref.as_deref(), Some("0.7.0-edge.1"));
+        assert_ne!(display.pretty_name, "peak-throughput-run");
+        assert_ne!(display.cpu_name, "Decoy CPU");
+        assert_ne!(display.gitref.as_deref(), Some("0.6.0"));
+    }
+
+    #[test]
+    fn 
given_showcase_without_gitref_when_building_display_should_drop_gitref() {
+        let showcase = showcase_fixture("no-tag-run", "CPU", None, 100.0);
+        let display = showcase_display(&showcase);
+        assert_eq!(display.gitref, None);
+    }
+
+    #[test]
+    fn 
given_showcase_without_metrics_when_building_display_should_return_dash_placeholder()
 {
+        let mut showcase = showcase_fixture("empty", "CPU", Some("0.7.0"), 
0.0);
+        showcase.group_metrics.clear();
+        let display = showcase_display(&showcase);
+        assert_eq!(display.formatted_value, "-");
+        assert_eq!(display.unit, "MB/s");
+    }
+
+    fn showcase_fixture(
+        pretty_name: &str,
+        cpu_name: &str,
+        gitref: Option<&str>,
+        throughput_mb_s: f64,
+    ) -> BenchmarkReportLight {
+        let mut report = BenchmarkReportLight::default();
+        report.params.pretty_name = pretty_name.to_string();
+        report.params.gitref = gitref.map(str::to_string);
+        report.hardware.cpu_name = cpu_name.to_string();
+        report.group_metrics.push(BenchmarkGroupMetricsLight {
+            summary: BenchmarkGroupMetricsSummary {
+                kind: GroupMetricsKind::Producers,
+                total_throughput_megabytes_per_second: throughput_mb_s,
+                total_throughput_messages_per_second: 0.0,
+                average_throughput_megabytes_per_second: 0.0,
+                average_throughput_messages_per_second: 0.0,
+                average_p50_latency_ms: 0.0,
+                average_p90_latency_ms: 0.0,
+                average_p95_latency_ms: 0.0,
+                average_p99_latency_ms: 0.0,
+                average_p999_latency_ms: 0.0,
+                average_p9999_latency_ms: 0.0,
+                average_latency_ms: 0.0,
+                average_median_latency_ms: 0.0,
+                min_latency_ms: 0.0,
+                max_latency_ms: 0.0,
+                std_dev_latency_ms: 0.0,
+            },
+            latency_distribution: None,
+        });
+        report
+    }
+}
diff --git 
a/core/bench/dashboard/frontend/src/components/layout/main_content.rs 
b/core/bench/dashboard/frontend/src/components/layout/main_content.rs
index 6b9a796d8..4125b053e 100644
--- a/core/bench/dashboard/frontend/src/components/layout/main_content.rs
+++ b/core/bench/dashboard/frontend/src/components/layout/main_content.rs
@@ -29,15 +29,11 @@ use std::collections::BTreeMap;
 use yew::prelude::*;
 use yew_router::prelude::use_navigator;
 
-#[derive(Properties, PartialEq)]
-pub struct MainContentProps {
-    #[prop_or_default]
-    pub selected_gitref: String,
-}
+#[derive(Properties, PartialEq, Default)]
+pub struct MainContentProps;
 
 #[function_component(MainContent)]
-pub fn main_content(props: &MainContentProps) -> Html {
-    let _ = &props.selected_gitref;
+pub fn main_content(_props: &MainContentProps) -> Html {
     let benchmark_ctx = use_benchmark();
     let ui = use_ui();
     let selected = benchmark_ctx.state.selected_benchmark.clone();
@@ -236,12 +232,18 @@ fn render_loading() -> Html {
     }
 }
 
+/// Map a benchmark gitref to the matching apache/iggy URL.
+/// Tagged releases (`X.Y.Z`, `X.Y.Z-edge.N`) are prefixed `server-` to
+/// match the repo's tag scheme. Plain commit hashes link directly.
+fn iggy_gitref_url(gitref: &str) -> String {
+    if crate::version::parse_semver_recency(gitref).is_some() {
+        format!("https://github.com/apache/iggy/tree/server-{gitref}";)
+    } else {
+        format!("https://github.com/apache/iggy/tree/{gitref}";)
+    }
+}
+
 fn render_benchmark_identifier(benchmark: &BenchmarkReportLight) -> Html {
-    let hardware = benchmark
-        .hardware
-        .identifier
-        .as_deref()
-        .unwrap_or("identifier");
     let cpu = benchmark.hardware.cpu_name.as_str();
     let gitref = benchmark
         .params
@@ -251,12 +253,12 @@ fn render_benchmark_identifier(benchmark: 
&BenchmarkReportLight) -> Html {
 
     html! {
         <>
-            <span>{format!("{hardware} @ {cpu}")}</span>
+            <span>{cpu.to_string()}</span>
             if let Some(gitref) = gitref {
                 <span class="chart-title-sep">{"ยท"}</span>
                 <a
                     class="chart-title-gitref"
-                    
href={format!("https://github.com/apache/iggy/tree/{gitref}";)}
+                    href={iggy_gitref_url(gitref)}
                     target="_blank"
                     rel="noopener noreferrer"
                     title={format!("Browse apache/iggy at {gitref}")}

Reply via email to