3
3
4
4
use jsonschema:: JSONSchema ;
5
5
use serde_json:: Value ;
6
- use std:: { collections:: HashMap , env, io :: { Read , Write } } ;
6
+ use std:: { collections:: HashMap , env} ;
7
7
use crate :: { configure:: { config_doc:: ExecutionKind , { config_result:: ResourceGetResult , parameters, Configurator } } , util:: parse_input_to_json} ;
8
8
use crate :: dscerror:: DscError ;
9
9
use super :: { dscresource:: get_diff, invoke_result:: { ExportResult , GetResult , ResolveResult , SetResult , TestResult , ValidateResult , ResourceGetResponse , ResourceSetResponse , ResourceTestResponse , get_in_desired_state} , resource_manifest:: { ArgKind , InputKind , Kind , ResourceManifest , ReturnKind , SchemaKind } } ;
10
10
use tracing:: { error, warn, info, debug, trace} ;
11
11
use tokio:: process:: Command ;
12
12
use std:: process:: Stdio ;
13
- use std:: process:: ExitStatus ;
14
13
use tokio:: io:: { BufReader , AsyncBufReadExt , AsyncWriteExt } ;
15
- use tokio:: task:: JoinError ;
16
14
17
15
pub const EXIT_PROCESS_TERMINATED : i32 = 0x102 ;
18
16
@@ -593,37 +591,43 @@ async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: O
593
591
stdin. write ( input. as_bytes ( ) ) . await . expect ( "could not write to stdin" ) ;
594
592
drop ( stdin) ;
595
593
}
596
-
594
+
597
595
let child_id: u32 = match child. id ( ) {
598
596
Some ( id) => id,
599
597
None => {
600
598
return Err ( DscError :: CommandOperation ( "Can't get child process id" . to_string ( ) , executable. to_string ( ) ) ) ;
601
599
}
602
600
} ;
603
601
604
- // Ensure the child process is spawned in the runtime so it can
605
- // make progress on its own while we await for any output.
606
- let child_result: Result < ExitStatus , JoinError > = tokio:: spawn ( async {
607
- let status = child. wait_with_output ( ) . await ;
608
- return status. unwrap ( ) . status
609
- } ) . await ;
610
-
611
- let mut stdout_result = String :: with_capacity ( 1024 * 1024 ) ;
612
- while let Some ( line) = stdout_reader. next_line ( ) . await ? {
613
- stdout_result. push_str ( & line) ;
614
- stdout_result. push ( '\n' ) ;
615
- }
602
+ let child_task = tokio:: spawn ( async move {
603
+ child. wait ( ) . await
604
+ } ) ;
616
605
617
- let mut filtered_stderr = String :: with_capacity ( 1024 * 1024 ) ;
618
- while let Some ( stderr_line) = stderr_reader. next_line ( ) . await ? {
619
- let filtered_stderr_line = log_stderr_line ( executable, & child_id, & stderr_line) ;
620
- if !filtered_stderr_line. is_empty ( ) {
621
- filtered_stderr. push_str ( filtered_stderr_line) ;
622
- filtered_stderr. push ( '\n' ) ;
606
+ let stdout_task = tokio:: spawn ( async move {
607
+ let mut stdout_result = String :: with_capacity ( 1024 * 1024 ) ;
608
+ while let Ok ( Some ( line) ) = stdout_reader. next_line ( ) . await {
609
+ stdout_result. push_str ( & line) ;
610
+ stdout_result. push ( '\n' ) ;
623
611
}
624
- }
612
+ return stdout_result
613
+ } ) ;
614
+
615
+ let stderr_task = tokio:: spawn ( async move {
616
+ let mut filtered_stderr = String :: with_capacity ( 1024 * 1024 ) ;
617
+ while let Ok ( Some ( stderr_line) ) = stderr_reader. next_line ( ) . await {
618
+ let filtered_stderr_line = log_stderr_line ( "pn" , & child_id, & stderr_line) ;
619
+ if !filtered_stderr_line. is_empty ( ) {
620
+ filtered_stderr. push_str ( filtered_stderr_line) ;
621
+ filtered_stderr. push ( '\n' ) ;
622
+ }
623
+ }
624
+ return filtered_stderr
625
+ } ) ;
626
+
627
+ let exit_code = child_task. await . unwrap ( ) ?. code ( ) ;
628
+ let stdout_result = stdout_task. await . unwrap ( ) ;
629
+ let stderr_result = stderr_task. await . unwrap ( ) ;
625
630
626
- let exit_code = child_result. unwrap ( ) . code ( ) ;
627
631
match exit_code {
628
632
Some ( code) => {
629
633
debug ! ( "Process '{executable}' id {child_id} exited with code {code}" ) ;
@@ -634,10 +638,10 @@ async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: O
634
638
return Err ( DscError :: CommandExitFromManifest ( executable. to_string ( ) , code, error_message. to_string ( ) ) ) ;
635
639
}
636
640
}
637
- return Err ( DscError :: Command ( executable. to_string ( ) , code, filtered_stderr ) ) ;
641
+ return Err ( DscError :: Command ( executable. to_string ( ) , code, stderr_result ) ) ;
638
642
}
639
643
640
- Ok ( ( code, stdout_result, filtered_stderr ) ) } ,
644
+ Ok ( ( code, stdout_result, stderr_result ) ) } ,
641
645
None => {
642
646
debug ! ( "Process '{executable}' id {child_id} terminated by signal" ) ;
643
647
return Err ( DscError :: CommandOperation ( "Process terminated by signal" . to_string ( ) , executable. to_string ( ) ) ) ;
0 commit comments