@@ -27,6 +27,7 @@ use std::collections::{HashMap, HashSet};
2727use std:: fs;
2828use std:: path:: Path ;
2929use std:: sync:: Arc ;
30+ use std:: time:: Instant ;
3031use tracing:: { debug, info, warn} ;
3132
3233const USER_AGENT : & str = "docs.rs builder (https://github.com/rust-lang/docs.rs)" ;
@@ -49,6 +50,30 @@ fn get_configured_toolchain(conn: &mut Client) -> Result<Toolchain> {
4950 }
5051}
5152
53+ fn build_workspace ( context : & dyn Context ) -> Result < Workspace > {
54+ let config = context. config ( ) ?;
55+
56+ let mut builder = WorkspaceBuilder :: new ( & config. rustwide_workspace , USER_AGENT )
57+ . running_inside_docker ( config. inside_docker ) ;
58+ if let Some ( custom_image) = & config. docker_image {
59+ let image = match SandboxImage :: local ( custom_image) {
60+ Ok ( i) => i,
61+ Err ( CommandError :: SandboxImageMissing ( _) ) => SandboxImage :: remote ( custom_image) ?,
62+ Err ( err) => return Err ( err. into ( ) ) ,
63+ } ;
64+ builder = builder. sandbox_image ( image) ;
65+ }
66+ if cfg ! ( test) {
67+ builder = builder. fast_init ( true ) ;
68+ }
69+
70+ let workspace = builder. init ( ) . map_err ( FailureError :: compat) ?;
71+ workspace
72+ . purge_all_build_dirs ( )
73+ . map_err ( FailureError :: compat) ?;
74+ Ok ( workspace)
75+ }
76+
5277pub enum PackageKind < ' a > {
5378 Local ( & ' a Path ) ,
5479 CratesIo ,
@@ -65,35 +90,16 @@ pub struct RustwideBuilder {
6590 index : Arc < Index > ,
6691 rustc_version : String ,
6792 repository_stats_updater : Arc < RepositoryStatsUpdater > ,
93+ workspace_initialize_time : Instant ,
6894}
6995
7096impl RustwideBuilder {
7197 pub fn init ( context : & dyn Context ) -> Result < Self > {
7298 let config = context. config ( ) ?;
73-
74- let mut builder = WorkspaceBuilder :: new ( & config. rustwide_workspace , USER_AGENT )
75- . running_inside_docker ( config. inside_docker ) ;
76- if let Some ( custom_image) = & config. docker_image {
77- let image = match SandboxImage :: local ( custom_image) {
78- Ok ( i) => i,
79- Err ( CommandError :: SandboxImageMissing ( _) ) => SandboxImage :: remote ( custom_image) ?,
80- Err ( err) => return Err ( err. into ( ) ) ,
81- } ;
82- builder = builder. sandbox_image ( image) ;
83- }
84- if cfg ! ( test) {
85- builder = builder. fast_init ( true ) ;
86- }
87-
88- let workspace = builder. init ( ) . map_err ( FailureError :: compat) ?;
89- workspace
90- . purge_all_build_dirs ( )
91- . map_err ( FailureError :: compat) ?;
92-
9399 let pool = context. pool ( ) ?;
94100
95101 Ok ( RustwideBuilder {
96- workspace,
102+ workspace : build_workspace ( context ) ? ,
97103 toolchain : get_configured_toolchain ( & mut * pool. get ( ) ?) ?,
98104 config,
99105 db : pool,
@@ -102,9 +108,24 @@ impl RustwideBuilder {
102108 index : context. index ( ) ?,
103109 rustc_version : String :: new ( ) ,
104110 repository_stats_updater : context. repository_stats_updater ( ) ?,
111+ workspace_initialize_time : Instant :: now ( ) ,
105112 } )
106113 }
107114
115+ pub fn reinitialize_workspace_if_interval_passed (
116+ & mut self ,
117+ context : & dyn Context ,
118+ ) -> Result < ( ) > {
119+ let interval = context. config ( ) ?. build_workspace_reinitialization_interval ;
120+ if self . workspace_initialize_time . elapsed ( ) >= interval {
121+ info ! ( "start reinitialize workspace again" ) ;
122+ self . workspace = build_workspace ( context) ?;
123+ self . workspace_initialize_time = Instant :: now ( ) ;
124+ }
125+
126+ Ok ( ( ) )
127+ }
128+
108129 fn prepare_sandbox ( & self , limits : & Limits ) -> SandboxBuilder {
109130 SandboxBuilder :: new ( )
110131 . cpu_limit ( self . config . build_cpu_limit . map ( |limit| limit as f32 ) )
@@ -1265,4 +1286,33 @@ mod tests {
12651286 Ok ( ( ) )
12661287 } )
12671288 }
1289+
1290+ #[ test]
1291+ #[ ignore]
1292+ fn test_workspace_reinitialize_at_once ( ) {
1293+ wrapper ( |env| {
1294+ let mut builder = RustwideBuilder :: init ( env) ?;
1295+ builder. reinitialize_workspace_if_interval_passed ( env) ?;
1296+ assert ! ( builder. build_local_package( Path :: new( "tests/crates/build-std" ) ) ?) ;
1297+ Ok ( ( ) )
1298+ } )
1299+ }
1300+
1301+ #[ test]
1302+ #[ ignore]
1303+ fn test_workspace_reinitialize_after_interval ( ) {
1304+ use std:: thread:: sleep;
1305+ use std:: time:: Duration ;
1306+ wrapper ( |env : & TestEnvironment | {
1307+ env. override_config ( |cfg : & mut Config | {
1308+ cfg. build_workspace_reinitialization_interval = Duration :: from_secs ( 1 )
1309+ } ) ;
1310+ let mut builder = RustwideBuilder :: init ( env) ?;
1311+ assert ! ( builder. build_local_package( Path :: new( "tests/crates/build-std" ) ) ?) ;
1312+ sleep ( Duration :: from_secs ( 1 ) ) ;
1313+ builder. reinitialize_workspace_if_interval_passed ( env) ?;
1314+ assert ! ( builder. build_local_package( Path :: new( "tests/crates/build-std" ) ) ?) ;
1315+ Ok ( ( ) )
1316+ } )
1317+ }
12681318}
0 commit comments