@@ -8,11 +8,10 @@ use std::{
88
99use always_assert:: always;
1010use crossbeam_channel:: { select, Receiver } ;
11- use ide:: { FileId , PrimeCachesProgress } ;
1211use ide_db:: base_db:: { SourceDatabaseExt , VfsPath } ;
1312use lsp_server:: { Connection , Notification , Request } ;
1413use lsp_types:: notification:: Notification as _;
15- use vfs:: ChangeKind ;
14+ use vfs:: { ChangeKind , FileId } ;
1615
1716use crate :: {
1817 config:: Config ,
@@ -67,6 +66,13 @@ pub(crate) enum Task {
6766 FetchBuildData ( BuildDataProgress ) ,
6867}
6968
69+ #[ derive( Debug ) ]
70+ pub ( crate ) enum PrimeCachesProgress {
71+ Begin ,
72+ Report ( ide:: PrimeCachesProgress ) ,
73+ End { cancelled : bool } ,
74+ }
75+
7076impl fmt:: Debug for Event {
7177 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
7278 let debug_verbose_not = |not : & Notification , f : & mut fmt:: Formatter | {
@@ -146,8 +152,10 @@ impl GlobalState {
146152 ) ;
147153 }
148154
149- self . fetch_workspaces_request ( ) ;
150- self . fetch_workspaces_if_needed ( ) ;
155+ self . fetch_workspaces_queue . request_op ( ) ;
156+ if self . fetch_workspaces_queue . should_start_op ( ) {
157+ self . fetch_workspaces ( ) ;
158+ }
151159
152160 while let Some ( event) = self . next_event ( & inbox) {
153161 if let Event :: Lsp ( lsp_server:: Message :: Notification ( not) ) = & event {
@@ -209,17 +217,17 @@ impl GlobalState {
209217 }
210218 }
211219 Task :: PrimeCaches ( progress) => match progress {
212- PrimeCachesProgress :: Started => prime_caches_progress. push ( progress) ,
213- PrimeCachesProgress :: StartedOnCrate { .. } => {
220+ PrimeCachesProgress :: Begin => prime_caches_progress. push ( progress) ,
221+ PrimeCachesProgress :: Report ( _ ) => {
214222 match prime_caches_progress. last_mut ( ) {
215- Some ( last @ PrimeCachesProgress :: StartedOnCrate { .. } ) => {
223+ Some ( last @ PrimeCachesProgress :: Report ( _ ) ) => {
216224 // Coalesce subsequent update events.
217225 * last = progress;
218226 }
219227 _ => prime_caches_progress. push ( progress) ,
220228 }
221229 }
222- PrimeCachesProgress :: Finished => prime_caches_progress. push ( progress) ,
230+ PrimeCachesProgress :: End { .. } => prime_caches_progress. push ( progress) ,
223231 } ,
224232 Task :: FetchWorkspace ( progress) => {
225233 let ( state, msg) = match progress {
@@ -228,14 +236,14 @@ impl GlobalState {
228236 ( Progress :: Report , Some ( msg) )
229237 }
230238 ProjectWorkspaceProgress :: End ( workspaces) => {
231- self . fetch_workspaces_completed ( workspaces) ;
239+ self . fetch_workspaces_queue . op_completed ( workspaces) ;
232240
233241 let old = Arc :: clone ( & self . workspaces ) ;
234242 self . switch_workspaces ( ) ;
235243 let workspaces_updated = !Arc :: ptr_eq ( & old, & self . workspaces ) ;
236244
237245 if self . config . run_build_scripts ( ) && workspaces_updated {
238- self . fetch_build_data_request ( )
246+ self . fetch_build_data_queue . request_op ( )
239247 }
240248
241249 ( Progress :: End , None )
@@ -251,7 +259,7 @@ impl GlobalState {
251259 ( Some ( Progress :: Report ) , Some ( msg) )
252260 }
253261 BuildDataProgress :: End ( build_data_result) => {
254- self . fetch_build_data_completed ( build_data_result) ;
262+ self . fetch_build_data_queue . op_completed ( build_data_result) ;
255263
256264 self . switch_workspaces ( ) ;
257265
@@ -275,22 +283,28 @@ impl GlobalState {
275283 for progress in prime_caches_progress {
276284 let ( state, message, fraction) ;
277285 match progress {
278- PrimeCachesProgress :: Started => {
286+ PrimeCachesProgress :: Begin => {
279287 state = Progress :: Begin ;
280288 message = None ;
281289 fraction = 0.0 ;
282290 }
283- PrimeCachesProgress :: StartedOnCrate { on_crate , n_done , n_total } => {
291+ PrimeCachesProgress :: Report ( report ) => {
284292 state = Progress :: Report ;
285- message = Some ( format ! ( "{}/{} ({})" , n_done, n_total, on_crate) ) ;
286- fraction = Progress :: fraction ( n_done, n_total) ;
293+ message = Some ( format ! (
294+ "{}/{} ({})" ,
295+ report. n_done, report. n_total, report. on_crate
296+ ) ) ;
297+ fraction = Progress :: fraction ( report. n_done , report. n_total ) ;
287298 }
288- PrimeCachesProgress :: Finished => {
299+ PrimeCachesProgress :: End { cancelled } => {
289300 state = Progress :: End ;
290301 message = None ;
291302 fraction = 1.0 ;
292303
293304 self . prime_caches_queue . op_completed ( ( ) ) ;
305+ if cancelled {
306+ self . prime_caches_queue . request_op ( ) ;
307+ }
294308 }
295309 } ;
296310
@@ -413,26 +427,10 @@ impl GlobalState {
413427 for flycheck in & self . flycheck {
414428 flycheck. update ( ) ;
415429 }
430+ self . prime_caches_queue . request_op ( ) ;
416431 }
417432
418433 if !was_quiescent || state_changed {
419- // Ensure that only one cache priming task can run at a time
420- self . prime_caches_queue . request_op ( ) ;
421- if self . prime_caches_queue . should_start_op ( ) {
422- self . task_pool . handle . spawn_with_sender ( {
423- let analysis = self . snapshot ( ) . analysis ;
424- move |sender| {
425- let cb = |progress| {
426- sender. send ( Task :: PrimeCaches ( progress) ) . unwrap ( ) ;
427- } ;
428- match analysis. prime_caches ( cb) {
429- Ok ( ( ) ) => ( ) ,
430- Err ( _canceled) => ( ) ,
431- }
432- }
433- } ) ;
434- }
435-
436434 // Refresh semantic tokens if the client supports it.
437435 if self . config . semantic_tokens_refresh ( ) {
438436 self . semantic_tokens_cache . lock ( ) . clear ( ) ;
@@ -478,11 +476,43 @@ impl GlobalState {
478476 }
479477
480478 if self . config . cargo_autoreload ( ) {
481- self . fetch_workspaces_if_needed ( ) ;
479+ if self . fetch_workspaces_queue . should_start_op ( ) {
480+ self . fetch_workspaces ( ) ;
481+ }
482+ }
483+ if self . fetch_build_data_queue . should_start_op ( ) {
484+ self . fetch_build_data ( ) ;
485+ }
486+ if self . prime_caches_queue . should_start_op ( ) {
487+ self . task_pool . handle . spawn_with_sender ( {
488+ let analysis = self . snapshot ( ) . analysis ;
489+ move |sender| {
490+ sender. send ( Task :: PrimeCaches ( PrimeCachesProgress :: Begin ) ) . unwrap ( ) ;
491+ let res = analysis. prime_caches ( |progress| {
492+ let report = PrimeCachesProgress :: Report ( progress) ;
493+ sender. send ( Task :: PrimeCaches ( report) ) . unwrap ( ) ;
494+ } ) ;
495+ sender
496+ . send ( Task :: PrimeCaches ( PrimeCachesProgress :: End {
497+ cancelled : res. is_err ( ) ,
498+ } ) )
499+ . unwrap ( ) ;
500+ }
501+ } ) ;
482502 }
483- self . fetch_build_data_if_needed ( ) ;
484503
485- self . report_new_status_if_needed ( ) ;
504+ let status = self . current_status ( ) ;
505+ if self . last_reported_status . as_ref ( ) != Some ( & status) {
506+ self . last_reported_status = Some ( status. clone ( ) ) ;
507+
508+ if let ( lsp_ext:: Health :: Error , Some ( message) ) = ( status. health , & status. message ) {
509+ self . show_message ( lsp_types:: MessageType :: Error , message. clone ( ) ) ;
510+ }
511+
512+ if self . config . server_status_notification ( ) {
513+ self . send_notification :: < lsp_ext:: ServerStatusNotification > ( status) ;
514+ }
515+ }
486516
487517 let loop_duration = loop_start. elapsed ( ) ;
488518 if loop_duration > Duration :: from_millis ( 100 ) {
@@ -521,8 +551,7 @@ impl GlobalState {
521551
522552 RequestDispatcher { req : Some ( req) , global_state : self }
523553 . on_sync_mut :: < lsp_ext:: ReloadWorkspace > ( |s, ( ) | {
524- s. fetch_workspaces_request ( ) ;
525- s. fetch_workspaces_if_needed ( ) ;
554+ s. fetch_workspaces_queue . request_op ( ) ;
526555 Ok ( ( ) )
527556 } ) ?
528557 . on_sync_mut :: < lsp_types:: request:: Shutdown > ( |s, ( ) | {
0 commit comments