@@ -7,7 +7,7 @@ use chrono::{DateTime, Utc};
77use path_slash:: PathExt ;
88use postgres:: Client ;
99use serde_json:: Value ;
10- use std:: { collections:: HashMap , fmt, path:: PathBuf } ;
10+ use std:: { collections:: HashMap , fmt, path:: PathBuf , sync :: Arc } ;
1111use tera:: { Result as TeraResult , Tera } ;
1212use tracing:: { error, trace} ;
1313use walkdir:: WalkDir ;
@@ -18,20 +18,49 @@ const TEMPLATES_DIRECTORY: &str = "templates";
1818#[ derive( Debug ) ]
1919pub ( crate ) struct TemplateData {
2020 pub templates : Tera ,
21+ rendering_threadpool : rayon:: ThreadPool ,
2122}
2223
2324impl TemplateData {
24- pub ( crate ) fn new ( conn : & mut Client ) -> Result < Self > {
25+ pub ( crate ) fn new ( conn : & mut Client , num_threads : usize ) -> Result < Self > {
2526 trace ! ( "Loading templates" ) ;
2627
2728 let data = Self {
2829 templates : load_templates ( conn) ?,
30+ rendering_threadpool : rayon:: ThreadPoolBuilder :: new ( )
31+ . num_threads ( num_threads)
32+ . thread_name ( move |idx| format ! ( "docsrs-render {idx}" ) )
33+ . build ( ) ?,
2934 } ;
3035
3136 trace ! ( "Finished loading templates" ) ;
3237
3338 Ok ( data)
3439 }
40+
41+ /// offload CPU intensive rendering into a rayon threadpool.
42+ ///
43+ /// This is a thin wrapper around `rayon::spawn` which waits
44+ /// sync task to finish.
45+ ///
46+ /// Use this instead of `spawn_blocking` so we don't block tokio.
47+ pub ( crate ) async fn render_in_threadpool < F , R > ( self : & Arc < Self > , render_fn : F ) -> Result < R >
48+ where
49+ F : FnOnce ( & TemplateData ) -> Result < R > + Send + ' static ,
50+ R : Send + ' static ,
51+ {
52+ let ( send, recv) = tokio:: sync:: oneshot:: channel ( ) ;
53+ self . rendering_threadpool . spawn ( {
54+ let templates = self . clone ( ) ;
55+ move || {
56+ // `.send` only fails when the receiver is dropped,
57+ // at which point we don't need the result any more.
58+ let _ = send. send ( render_fn ( & templates) ) ;
59+ }
60+ } ) ;
61+
62+ recv. await . context ( "sender was dropped" ) ?
63+ }
3564}
3665
3766fn load_rustc_resource_suffix ( conn : & mut Client ) -> Result < String > {
0 commit comments