@@ -76,7 +76,7 @@ impl fmt::Display for FlycheckConfig {
76
76
#[ derive( Debug ) ]
77
77
pub struct FlycheckHandle {
78
78
// XXX: drop order is significant
79
- sender : Sender < Restart > ,
79
+ sender : Sender < StateChange > ,
80
80
_thread : jod_thread:: JoinHandle ,
81
81
id : usize ,
82
82
}
@@ -89,7 +89,7 @@ impl FlycheckHandle {
89
89
workspace_root : AbsPathBuf ,
90
90
) -> FlycheckHandle {
91
91
let actor = FlycheckActor :: new ( id, sender, config, workspace_root) ;
92
- let ( sender, receiver) = unbounded :: < Restart > ( ) ;
92
+ let ( sender, receiver) = unbounded :: < StateChange > ( ) ;
93
93
let thread = jod_thread:: Builder :: new ( )
94
94
. name ( "Flycheck" . to_owned ( ) )
95
95
. spawn ( move || actor. run ( receiver) )
@@ -99,12 +99,12 @@ impl FlycheckHandle {
99
99
100
100
/// Schedule a re-start of the cargo check worker.
101
101
pub fn restart ( & self ) {
102
- self . sender . send ( Restart :: Yes ) . unwrap ( ) ;
102
+ self . sender . send ( StateChange :: Restart ) . unwrap ( ) ;
103
103
}
104
104
105
105
/// Stop this cargo check worker.
106
106
pub fn cancel ( & self ) {
107
- self . sender . send ( Restart :: No ) . unwrap ( ) ;
107
+ self . sender . send ( StateChange :: Cancel ) . unwrap ( ) ;
108
108
}
109
109
110
110
pub fn id ( & self ) -> usize {
@@ -149,9 +149,9 @@ pub enum Progress {
149
149
DidFailToRestart ( String ) ,
150
150
}
151
151
152
- enum Restart {
153
- Yes ,
154
- No ,
152
+ enum StateChange {
153
+ Restart ,
154
+ Cancel ,
155
155
}
156
156
157
157
/// A [`FlycheckActor`] is a single check instance of a workspace.
@@ -172,7 +172,7 @@ struct FlycheckActor {
172
172
}
173
173
174
174
enum Event {
175
- Restart ( Restart ) ,
175
+ RequestStateChange ( StateChange ) ,
176
176
CheckEvent ( Option < CargoMessage > ) ,
177
177
}
178
178
@@ -191,30 +191,31 @@ impl FlycheckActor {
191
191
self . send ( Message :: Progress { id : self . id , progress } ) ;
192
192
}
193
193
194
- fn next_event ( & self , inbox : & Receiver < Restart > ) -> Option < Event > {
194
+ fn next_event ( & self , inbox : & Receiver < StateChange > ) -> Option < Event > {
195
195
let check_chan = self . cargo_handle . as_ref ( ) . map ( |cargo| & cargo. receiver ) ;
196
196
if let Ok ( msg) = inbox. try_recv ( ) {
197
197
// give restarts a preference so check outputs don't block a restart or stop
198
- return Some ( Event :: Restart ( msg) ) ;
198
+ return Some ( Event :: RequestStateChange ( msg) ) ;
199
199
}
200
200
select ! {
201
- recv( inbox) -> msg => msg. ok( ) . map( Event :: Restart ) ,
201
+ recv( inbox) -> msg => msg. ok( ) . map( Event :: RequestStateChange ) ,
202
202
recv( check_chan. unwrap_or( & never( ) ) ) -> msg => Some ( Event :: CheckEvent ( msg. ok( ) ) ) ,
203
203
}
204
204
}
205
205
206
- fn run ( mut self , inbox : Receiver < Restart > ) {
206
+ fn run ( mut self , inbox : Receiver < StateChange > ) {
207
207
' event: while let Some ( event) = self . next_event ( & inbox) {
208
208
match event {
209
- Event :: Restart ( Restart :: No ) => {
209
+ Event :: RequestStateChange ( StateChange :: Cancel ) => {
210
+ tracing:: debug!( flycheck_id = self . id, "flycheck cancelled" ) ;
210
211
self . cancel_check_process ( ) ;
211
212
}
212
- Event :: Restart ( Restart :: Yes ) => {
213
+ Event :: RequestStateChange ( StateChange :: Restart ) => {
213
214
// Cancel the previously spawned process
214
215
self . cancel_check_process ( ) ;
215
216
while let Ok ( restart) = inbox. recv_timeout ( Duration :: from_millis ( 50 ) ) {
216
217
// restart chained with a stop, so just cancel
217
- if let Restart :: No = restart {
218
+ if let StateChange :: Cancel = restart {
218
219
continue ' event;
219
220
}
220
221
}
@@ -255,10 +256,20 @@ impl FlycheckActor {
255
256
}
256
257
Event :: CheckEvent ( Some ( message) ) => match message {
257
258
CargoMessage :: CompilerArtifact ( msg) => {
259
+ tracing:: trace!(
260
+ flycheck_id = self . id,
261
+ artifact = msg. target. name,
262
+ "artifact received"
263
+ ) ;
258
264
self . report_progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
259
265
}
260
266
261
267
CargoMessage :: Diagnostic ( msg) => {
268
+ tracing:: trace!(
269
+ flycheck_id = self . id,
270
+ message = msg. message,
271
+ "diagnostic received"
272
+ ) ;
262
273
self . send ( Message :: AddDiagnostic {
263
274
id : self . id ,
264
275
workspace_root : self . root . clone ( ) ,
@@ -445,42 +456,56 @@ impl CargoActor {
445
456
// simply skip a line if it doesn't parse, which just ignores any
446
457
// erroneous output.
447
458
448
- let mut error = String :: new ( ) ;
449
- let mut read_at_least_one_message = false ;
459
+ let mut stdout_errors = String :: new ( ) ;
460
+ let mut stderr_errors = String :: new ( ) ;
461
+ let mut read_at_least_one_stdout_message = false ;
462
+ let mut read_at_least_one_stderr_message = false ;
463
+ let process_line = |line : & str , error : & mut String | {
464
+ // Try to deserialize a message from Cargo or Rustc.
465
+ let mut deserializer = serde_json:: Deserializer :: from_str ( line) ;
466
+ deserializer. disable_recursion_limit ( ) ;
467
+ if let Ok ( message) = JsonMessage :: deserialize ( & mut deserializer) {
468
+ match message {
469
+ // Skip certain kinds of messages to only spend time on what's useful
470
+ JsonMessage :: Cargo ( message) => match message {
471
+ cargo_metadata:: Message :: CompilerArtifact ( artifact) if !artifact. fresh => {
472
+ self . sender . send ( CargoMessage :: CompilerArtifact ( artifact) ) . unwrap ( ) ;
473
+ }
474
+ cargo_metadata:: Message :: CompilerMessage ( msg) => {
475
+ self . sender . send ( CargoMessage :: Diagnostic ( msg. message ) ) . unwrap ( ) ;
476
+ }
477
+ _ => ( ) ,
478
+ } ,
479
+ JsonMessage :: Rustc ( message) => {
480
+ self . sender . send ( CargoMessage :: Diagnostic ( message) ) . unwrap ( ) ;
481
+ }
482
+ }
483
+ return true ;
484
+ }
485
+
486
+ error. push_str ( line) ;
487
+ error. push ( '\n' ) ;
488
+ return false ;
489
+ } ;
450
490
let output = streaming_output (
451
491
self . stdout ,
452
492
self . stderr ,
453
493
& mut |line| {
454
- read_at_least_one_message = true ;
455
-
456
- // Try to deserialize a message from Cargo or Rustc.
457
- let mut deserializer = serde_json:: Deserializer :: from_str ( line) ;
458
- deserializer. disable_recursion_limit ( ) ;
459
- if let Ok ( message) = JsonMessage :: deserialize ( & mut deserializer) {
460
- match message {
461
- // Skip certain kinds of messages to only spend time on what's useful
462
- JsonMessage :: Cargo ( message) => match message {
463
- cargo_metadata:: Message :: CompilerArtifact ( artifact)
464
- if !artifact. fresh =>
465
- {
466
- self . sender . send ( CargoMessage :: CompilerArtifact ( artifact) ) . unwrap ( ) ;
467
- }
468
- cargo_metadata:: Message :: CompilerMessage ( msg) => {
469
- self . sender . send ( CargoMessage :: Diagnostic ( msg. message ) ) . unwrap ( ) ;
470
- }
471
- _ => ( ) ,
472
- } ,
473
- JsonMessage :: Rustc ( message) => {
474
- self . sender . send ( CargoMessage :: Diagnostic ( message) ) . unwrap ( ) ;
475
- }
476
- }
494
+ if process_line ( line, & mut stdout_errors) {
495
+ read_at_least_one_stdout_message = true ;
477
496
}
478
497
} ,
479
498
& mut |line| {
480
- error. push_str ( line) ;
481
- error. push ( '\n' ) ;
499
+ if process_line ( line, & mut stderr_errors) {
500
+ read_at_least_one_stderr_message = true ;
501
+ }
482
502
} ,
483
503
) ;
504
+
505
+ let read_at_least_one_message =
506
+ read_at_least_one_stdout_message || read_at_least_one_stderr_message;
507
+ let mut error = stdout_errors;
508
+ error. push_str ( & stderr_errors) ;
484
509
match output {
485
510
Ok ( _) => Ok ( ( read_at_least_one_message, error) ) ,
486
511
Err ( e) => Err ( io:: Error :: new ( e. kind ( ) , format ! ( "{e:?}: {error}" ) ) ) ,
0 commit comments