From 5322fad245457bb7f7695d87d0517f38e8241c5d Mon Sep 17 00:00:00 2001 From: Tushar Date: Mon, 30 Mar 2026 13:44:02 +0530 Subject: [PATCH 1/2] perf(template): lazily initialize Handlebars in ForgeTemplateService --- crates/forge_display/src/markdown.rs | 9 ++++++--- crates/forge_services/src/template.rs | 24 +++++++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/crates/forge_display/src/markdown.rs b/crates/forge_display/src/markdown.rs index 52f089a929..0843c3c8af 100644 --- a/crates/forge_display/src/markdown.rs +++ b/crates/forge_display/src/markdown.rs @@ -1,3 +1,5 @@ +use std::sync::OnceLock; + use derive_setters::Setters; use regex::Regex; use termimad::crossterm::style::{Attribute, Color}; @@ -13,7 +15,7 @@ pub struct MarkdownFormat { skin: MadSkin, max_consecutive_newlines: usize, #[setters(skip)] - highlighter: SyntaxHighlighter, + highlighter: OnceLock, } impl Default for MarkdownFormat { @@ -39,7 +41,7 @@ impl MarkdownFormat { Self { skin, max_consecutive_newlines: 2, - highlighter: SyntaxHighlighter::default(), + highlighter: OnceLock::new(), } } @@ -55,8 +57,9 @@ impl MarkdownFormat { // Render with termimad, then restore highlighted code let rendered = self.skin.term_text(processed.markdown()).to_string(); + let highlighter = self.highlighter.get_or_init(SyntaxHighlighter::default); processed - .restore(&self.highlighter, rendered) + .restore(highlighter, rendered) .trim() .to_string() } diff --git a/crates/forge_services/src/template.rs b/crates/forge_services/src/template.rs index 3f04daa3c0..8ee5115f13 100644 --- a/crates/forge_services/src/template.rs +++ b/crates/forge_services/src/template.rs @@ -6,18 +6,27 @@ use forge_app::{EnvironmentInfra, FileReaderInfra, TemplateService}; use forge_domain::Template; use futures::future; use handlebars::Handlebars; -use tokio::sync::RwLock; +use tokio::sync::{OnceCell, RwLock}; #[derive(Clone)] pub struct ForgeTemplateService { - hb: Arc>>, + hb: Arc>>>, infra: Arc, } impl ForgeTemplateService { pub fn new(infra: Arc) -> Self { - let hb = forge_app::TemplateEngine::handlebar_instance(); - Self { hb: Arc::new(RwLock::new(hb)), infra } + Self { hb: Arc::new(OnceCell::new()), infra } + } + + /// Returns a reference to the lazily-initialized Handlebars RwLock, + /// creating the instance on the first call. + async fn get_hb(&self) -> &RwLock> { + self.hb + .get_or_init(|| async { + RwLock::new(forge_app::TemplateEngine::handlebar_instance()) + }) + .await } /// Reads multiple template files in parallel and returns their names and @@ -74,7 +83,7 @@ impl TemplateService for ForgeTemplateSer let cwd = &self.infra.get_environment().cwd; // Discover and filter unregistered templates in one pass - let guard = self.hb.read().await; + let guard = self.get_hb().await.read().await; let path = if path.is_absolute() { path.to_string_lossy().to_string() } else { @@ -98,7 +107,7 @@ impl TemplateService for ForgeTemplateSer // Register all templates if any were found if !templates.is_empty() { - let mut guard = self.hb.write().await; + let mut guard = self.get_hb().await.write().await; for (name, content) in templates { let template = compile_template(&name, &content)?; guard.register_template(&name, template); @@ -114,7 +123,8 @@ impl TemplateService for ForgeTemplateSer object: &V, ) -> anyhow::Result { let rendered = self - .hb + .get_hb() + .await .read() .await .render_template(&template.template, object)?; From fe9075dc1008034bf397b6ade1f36b3f90b9aba7 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 08:15:52 +0000 Subject: [PATCH 2/2] [autofix.ci] apply automated fixes --- crates/forge_display/src/markdown.rs | 5 +---- crates/forge_services/src/template.rs | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/crates/forge_display/src/markdown.rs b/crates/forge_display/src/markdown.rs index 0843c3c8af..43e2d7bf90 100644 --- a/crates/forge_display/src/markdown.rs +++ b/crates/forge_display/src/markdown.rs @@ -58,10 +58,7 @@ impl MarkdownFormat { // Render with termimad, then restore highlighted code let rendered = self.skin.term_text(processed.markdown()).to_string(); let highlighter = self.highlighter.get_or_init(SyntaxHighlighter::default); - processed - .restore(highlighter, rendered) - .trim() - .to_string() + processed.restore(highlighter, rendered).trim().to_string() } fn strip_excessive_newlines(&self, content: &str) -> String { diff --git a/crates/forge_services/src/template.rs b/crates/forge_services/src/template.rs index 8ee5115f13..19a63c357a 100644 --- a/crates/forge_services/src/template.rs +++ b/crates/forge_services/src/template.rs @@ -23,9 +23,7 @@ impl ForgeTemplateService { /// creating the instance on the first call. async fn get_hb(&self) -> &RwLock> { self.hb - .get_or_init(|| async { - RwLock::new(forge_app::TemplateEngine::handlebar_instance()) - }) + .get_or_init(|| async { RwLock::new(forge_app::TemplateEngine::handlebar_instance()) }) .await }