Skip to content

Commit 09b07ad

Browse files
author
Andrew
committed
feedback 1
1 parent 2356cc0 commit 09b07ad

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

dsc_lib/src/dscresources/command_resource.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33

44
use jsonschema::JSONSchema;
55
use serde_json::Value;
6-
use std::{collections::HashMap, env};
6+
use std::{collections::HashMap, env, process::Stdio};
77
use crate::{configure::{config_doc::ExecutionKind, {config_result::ResourceGetResult, parameters, Configurator}}, util::parse_input_to_json};
88
use crate::dscerror::DscError;
99
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}};
1010
use tracing::{error, warn, info, debug, trace};
11-
use tokio::process::Command;
12-
use std::process::Stdio;
13-
use tokio::io::{BufReader, AsyncBufReadExt, AsyncWriteExt};
11+
use tokio::{io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, process::Command};
1412

1513
pub const EXIT_PROCESS_TERMINATED: i32 = 0x102;
1614

@@ -556,6 +554,21 @@ pub fn invoke_resolve(resource: &ResourceManifest, cwd: &str, input: &str) -> Re
556554
Ok(result)
557555
}
558556

557+
/// Asynchronously invoke a command and return the exit code, stdout, and stderr.
558+
///
559+
/// # Arguments
560+
///
561+
/// * `executable` - The command to execute
562+
/// * `args` - Optional arguments to pass to the command
563+
/// * `input` - Optional input to pass to the command
564+
/// * `cwd` - Optional working directory to execute the command in
565+
/// * `env` - Optional environment variable mappings to add or update
566+
/// * `exit_codes` - Optional descriptions of exit codes
567+
///
568+
/// # Errors
569+
///
570+
/// Error is returned if the command fails to execute or stdin/stdout/stderr cannot be opened.
571+
///
559572
async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: Option<&str>, cwd: Option<&str>, env: Option<HashMap<String, String>>, exit_codes: &Option<HashMap<i32, String>>) -> Result<(i32, String, String), DscError> {
560573

561574
let mut command = Command::new(executable);
@@ -597,19 +610,20 @@ async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: O
597610
drop(stdin);
598611
}
599612

600-
let child_id: u32 = match child.id() {
601-
Some(id) => id,
602-
None => {
603-
return Err(DscError::CommandOperation("Can't get child process id".to_string(), executable.to_string()));
604-
}
613+
let Some(child_id) = child.id() else {
614+
return Err(DscError::CommandOperation("Can't get child process id".to_string(), executable.to_string()));
605615
};
606616

607617
let child_task = tokio::spawn(async move {
608618
child.wait().await
609619
});
610620

621+
// use somewhat large initial buffer to avoid early string reallocations;
622+
// the value is based on list result of largest of built-in adapters - WMI adapter ~500KB
623+
const INITIAL_BUFFER_CAPACITY: usize = 1024*1024;
624+
611625
let stdout_task = tokio::spawn(async move {
612-
let mut stdout_result = String::with_capacity(1024*1024);
626+
let mut stdout_result = String::with_capacity(INITIAL_BUFFER_CAPACITY);
613627
while let Ok(Some(line)) = stdout_reader.next_line().await {
614628
stdout_result.push_str(&line);
615629
stdout_result.push('\n');
@@ -618,7 +632,7 @@ async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: O
618632
});
619633

620634
let stderr_task = tokio::spawn(async move {
621-
let mut filtered_stderr = String::with_capacity(1024*1024);
635+
let mut filtered_stderr = String::with_capacity(INITIAL_BUFFER_CAPACITY);
622636
while let Ok(Some(stderr_line)) = stderr_reader.next_line().await {
623637
let filtered_stderr_line = log_stderr_line(&child_id, &stderr_line);
624638
if !filtered_stderr_line.is_empty() {
@@ -660,10 +674,13 @@ async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: O
660674
/// * `args` - Optional arguments to pass to the command
661675
/// * `input` - Optional input to pass to the command
662676
/// * `cwd` - Optional working directory to execute the command in
663-
///
677+
/// * `env` - Optional environment variable mappings to add or update
678+
/// * `exit_codes` - Optional descriptions of exit codes
679+
///
664680
/// # Errors
665681
///
666682
/// Error is returned if the command fails to execute or stdin/stdout/stderr cannot be opened.
683+
///
667684
/// # Panics
668685
///
669686
/// Will panic if tokio runtime can't be created.

0 commit comments

Comments
 (0)