@@ -6,18 +6,25 @@ use forge_app::{EnvironmentInfra, FileReaderInfra, TemplateService};
66use forge_domain:: Template ;
77use futures:: future;
88use handlebars:: Handlebars ;
9- use tokio:: sync:: RwLock ;
9+ use tokio:: sync:: { OnceCell , RwLock } ;
1010
1111#[ derive( Clone ) ]
1212pub struct ForgeTemplateService < F > {
13- hb : Arc < RwLock < Handlebars < ' static > > > ,
13+ hb : Arc < OnceCell < RwLock < Handlebars < ' static > > > > ,
1414 infra : Arc < F > ,
1515}
1616
1717impl < F : EnvironmentInfra + FileReaderInfra > ForgeTemplateService < F > {
1818 pub fn new ( infra : Arc < F > ) -> Self {
19- let hb = forge_app:: TemplateEngine :: handlebar_instance ( ) ;
20- Self { hb : Arc :: new ( RwLock :: new ( hb) ) , infra }
19+ Self { hb : Arc :: new ( OnceCell :: new ( ) ) , infra }
20+ }
21+
22+ /// Returns a reference to the lazily-initialized Handlebars RwLock,
23+ /// creating the instance on the first call.
24+ async fn get_hb ( & self ) -> & RwLock < Handlebars < ' static > > {
25+ self . hb
26+ . get_or_init ( || async { RwLock :: new ( forge_app:: TemplateEngine :: handlebar_instance ( ) ) } )
27+ . await
2128 }
2229
2330 /// Reads multiple template files in parallel and returns their names and
@@ -74,7 +81,7 @@ impl<F: EnvironmentInfra + FileReaderInfra> TemplateService for ForgeTemplateSer
7481 let cwd = & self . infra . get_environment ( ) . cwd ;
7582
7683 // Discover and filter unregistered templates in one pass
77- let guard = self . hb . read ( ) . await ;
84+ let guard = self . get_hb ( ) . await . read ( ) . await ;
7885 let path = if path. is_absolute ( ) {
7986 path. to_string_lossy ( ) . to_string ( )
8087 } else {
@@ -98,7 +105,7 @@ impl<F: EnvironmentInfra + FileReaderInfra> TemplateService for ForgeTemplateSer
98105
99106 // Register all templates if any were found
100107 if !templates. is_empty ( ) {
101- let mut guard = self . hb . write ( ) . await ;
108+ let mut guard = self . get_hb ( ) . await . write ( ) . await ;
102109 for ( name, content) in templates {
103110 let template = compile_template ( & name, & content) ?;
104111 guard. register_template ( & name, template) ;
@@ -114,7 +121,8 @@ impl<F: EnvironmentInfra + FileReaderInfra> TemplateService for ForgeTemplateSer
114121 object : & V ,
115122 ) -> anyhow:: Result < String > {
116123 let rendered = self
117- . hb
124+ . get_hb ( )
125+ . await
118126 . read ( )
119127 . await
120128 . render_template ( & template. template , object) ?;
0 commit comments