@@ -7,7 +7,7 @@ use crate::find::identify_python_executables_using_locators;
77use crate :: find:: SearchScope ;
88use crate :: locators:: create_locators;
99use lazy_static:: lazy_static;
10- use log:: { error, info, trace} ;
10+ use log:: { error, info, trace, warn } ;
1111use pet:: initialize_tracing;
1212use pet:: resolve:: resolve_environment;
1313use pet_conda:: Conda ;
@@ -110,28 +110,48 @@ pub struct ConfigureOptions {
110110 pub cache_directory : Option < PathBuf > ,
111111}
112112
113+ /// Threshold for glob expansion duration before emitting a warning.
114+ /// The client has a 30-second timeout for configure requests.
115+ const GLOB_EXPANSION_WARN_THRESHOLD : Duration = Duration :: from_secs ( 5 ) ;
116+
113117pub fn handle_configure ( context : Arc < Context > , id : u32 , params : Value ) {
114118 match serde_json:: from_value :: < ConfigureOptions > ( params. clone ( ) ) {
115119 Ok ( configure_options) => {
120+ info ! ( "Received configure request" ) ;
116121 // Start in a new thread, we can have multiple requests.
117122 thread:: spawn ( move || {
118- let mut cfg = context. configuration . write ( ) . unwrap ( ) ;
119- // Expand glob patterns in workspace_directories
120- cfg. workspace_directories = configure_options. workspace_directories . map ( |dirs| {
123+ let now = SystemTime :: now ( ) ;
124+
125+ // Expand glob patterns before acquiring the write lock so we
126+ // don't block readers/writers while traversing the filesystem.
127+ let workspace_directories = configure_options. workspace_directories . map ( |dirs| {
128+ trace ! ( "Expanding workspace directory patterns: {:?}" , dirs) ;
121129 expand_glob_patterns ( & dirs)
122130 . into_iter ( )
123131 . filter ( |p| p. is_dir ( ) )
124132 . collect ( )
125133 } ) ;
126- cfg. conda_executable = configure_options. conda_executable ;
127- // Expand glob patterns in environment_directories
128- cfg. environment_directories =
134+ let environment_directories =
129135 configure_options. environment_directories . map ( |dirs| {
136+ trace ! ( "Expanding environment directory patterns: {:?}" , dirs) ;
130137 expand_glob_patterns ( & dirs)
131138 . into_iter ( )
132139 . filter ( |p| p. is_dir ( ) )
133140 . collect ( )
134141 } ) ;
142+ let glob_elapsed = now. elapsed ( ) . unwrap_or_default ( ) ;
143+ trace ! ( "Glob expansion completed in {:?}" , glob_elapsed) ;
144+ if glob_elapsed >= GLOB_EXPANSION_WARN_THRESHOLD {
145+ warn ! (
146+ "Glob expansion took {:?}, this may cause client timeouts" ,
147+ glob_elapsed
148+ ) ;
149+ }
150+
151+ let mut cfg = context. configuration . write ( ) . unwrap ( ) ;
152+ cfg. workspace_directories = workspace_directories;
153+ cfg. conda_executable = configure_options. conda_executable ;
154+ cfg. environment_directories = environment_directories;
135155 cfg. pipenv_executable = configure_options. pipenv_executable ;
136156 cfg. poetry_executable = configure_options. poetry_executable ;
137157 // We will not support changing the cache directories once set.
@@ -146,6 +166,10 @@ pub fn handle_configure(context: Arc<Context>, id: u32, params: Value) {
146166 for locator in context. locators . iter ( ) {
147167 locator. configure ( & config) ;
148168 }
169+ info ! (
170+ "Configure completed in {:?}" ,
171+ now. elapsed( ) . unwrap_or_default( )
172+ ) ;
149173 send_reply ( id, None :: < ( ) > ) ;
150174 } ) ;
151175 }
@@ -390,6 +414,8 @@ pub fn handle_find(context: Arc<Context>, id: u32, params: Value) {
390414 thread:: spawn (
391415 move || match serde_json:: from_value :: < FindOptions > ( params. clone ( ) ) {
392416 Ok ( find_options) => {
417+ let now = SystemTime :: now ( ) ;
418+ trace ! ( "Finding environments in {:?}" , find_options. search_path) ;
393419 let global_env_search_paths: Vec < PathBuf > =
394420 get_search_paths_from_env_variables ( context. os_environment . as_ref ( ) ) ;
395421
@@ -424,6 +450,12 @@ pub fn handle_find(context: Arc<Context>, id: u32, params: Value) {
424450 . lock ( )
425451 . expect ( "environments mutex poisoned" )
426452 . clone ( ) ;
453+ trace ! (
454+ "Find completed in {:?}, found {} environments in {:?}" ,
455+ now. elapsed( ) . unwrap_or_default( ) ,
456+ envs. len( ) ,
457+ find_options. search_path
458+ ) ;
427459 if envs. is_empty ( ) {
428460 send_reply ( id, None :: < Vec < PythonEnvironment > > ) ;
429461 } else {
@@ -444,6 +476,7 @@ pub fn handle_find(context: Arc<Context>, id: u32, params: Value) {
444476
445477pub fn handle_conda_telemetry ( context : Arc < Context > , id : u32 , _params : Value ) {
446478 thread:: spawn ( move || {
479+ trace ! ( "Gathering conda telemetry" ) ;
447480 let conda_locator = context. conda_locator . clone ( ) ;
448481 let conda_executable = context
449482 . configuration
@@ -452,6 +485,7 @@ pub fn handle_conda_telemetry(context: Arc<Context>, id: u32, _params: Value) {
452485 . conda_executable
453486 . clone ( ) ;
454487 let info = conda_locator. get_info_for_telemetry ( conda_executable) ;
488+ trace ! ( "Conda telemetry complete" ) ;
455489 send_reply ( id, info. into ( ) ) ;
456490 } ) ;
457491}
0 commit comments