mirror of
https://github.com/bahdotsh/wrkflw.git
synced 2025-12-29 00:24:57 +01:00
background process
This commit is contained in:
36
.github/workflows/background-test.yml
vendored
Normal file
36
.github/workflows/background-test.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Background Process Test
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test-background:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Background process with sleep
|
||||
run: |
|
||||
echo "Starting background process..."
|
||||
sleep 5 &
|
||||
echo "Background process started, PID: $!"
|
||||
echo "This should complete after the background process"
|
||||
sleep 1
|
||||
echo "Foreground process finished, but we should still be waiting for background"
|
||||
|
||||
- name: This step should only run after the background process completes
|
||||
run: echo "If you see this, background process handling works!"
|
||||
|
||||
test-multiple-background:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Multiple background processes
|
||||
run: |
|
||||
echo "Starting multiple background processes"
|
||||
sleep 3 &
|
||||
echo "Started first background process"
|
||||
sleep 6 &
|
||||
echo "Started second background process"
|
||||
echo "Waiting for all background processes to complete"
|
||||
# The workflow should automatically wait for both processes
|
||||
|
||||
- name: Follow-up step
|
||||
run: echo "All background processes completed!"
|
||||
@@ -85,6 +85,35 @@ impl ContainerRuntime for DockerRuntime {
|
||||
// Print detailed debugging info
|
||||
logging::info(&format!("Docker: Running container with image: {}", image));
|
||||
|
||||
// Check if command contains background processes
|
||||
let has_background = cmd.iter().any(|c| c.contains(" &"));
|
||||
|
||||
// If there's a background process, we need to handle it differently
|
||||
let cmd_vec: Vec<String> = if has_background {
|
||||
// If the command contains a background process, wrap it in a shell script
|
||||
// that properly manages the background process and exits when the foreground completes
|
||||
let mut shell_cmd = Vec::new();
|
||||
shell_cmd.push("sh".to_string());
|
||||
shell_cmd.push("-c".to_string());
|
||||
|
||||
// Join the original command and add a wait for any child processes
|
||||
let command_with_wait =
|
||||
if cmd.len() > 2 && (cmd[0] == "sh" || cmd[0] == "bash") && cmd[1] == "-c" {
|
||||
// For shell commands, we just need to modify the command string
|
||||
format!("{} ; wait", cmd[2])
|
||||
} else {
|
||||
// Otherwise join all parts and add wait
|
||||
let cmd_str: Vec<String> = cmd.iter().map(|s| s.to_string()).collect();
|
||||
format!("{} ; wait", cmd_str.join(" "))
|
||||
};
|
||||
|
||||
shell_cmd.push(command_with_wait);
|
||||
shell_cmd
|
||||
} else {
|
||||
// No background processes, use original command
|
||||
cmd.iter().map(|s| s.to_string()).collect()
|
||||
};
|
||||
|
||||
// Always try to pull the image first
|
||||
match self.pull_image(image).await {
|
||||
Ok(_) => logging::info(&format!("🐳 Successfully pulled image: {}", image)),
|
||||
@@ -112,8 +141,6 @@ impl ContainerRuntime for DockerRuntime {
|
||||
platform: None,
|
||||
});
|
||||
|
||||
let cmd_vec: Vec<String> = cmd.iter().map(|s| s.to_string()).collect();
|
||||
|
||||
let host_config = HostConfig {
|
||||
binds: Some(binds),
|
||||
..Default::default()
|
||||
|
||||
@@ -139,6 +139,8 @@ impl ContainerRuntime for EmulationRuntime {
|
||||
));
|
||||
}
|
||||
|
||||
let has_background = cmd.iter().any(|c| c.contains(" &"));
|
||||
|
||||
// For bash/sh with -c, handle specially
|
||||
if (cmd[0] == "bash" || cmd[0] == "sh")
|
||||
&& cmd.len() >= 2
|
||||
@@ -155,6 +157,13 @@ impl ContainerRuntime for EmulationRuntime {
|
||||
// Get the actual command
|
||||
let command_str = cmd[idx + 1];
|
||||
|
||||
// If we have background processes, add a wait command
|
||||
let final_cmd = if has_background && !command_str.contains(" wait") {
|
||||
format!("{{ {}; }} && wait", command_str)
|
||||
} else {
|
||||
command_str.to_string()
|
||||
};
|
||||
|
||||
// Create command
|
||||
let mut command = Command::new(shell);
|
||||
command.current_dir(&container_working_dir);
|
||||
@@ -165,7 +174,7 @@ impl ContainerRuntime for EmulationRuntime {
|
||||
}
|
||||
|
||||
// Add the command
|
||||
command.arg(command_str);
|
||||
command.arg(final_cmd);
|
||||
|
||||
// Set environment variables
|
||||
for (key, value) in env_vars {
|
||||
@@ -186,6 +195,32 @@ impl ContainerRuntime for EmulationRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
if has_background {
|
||||
// For commands with background processes, use shell wrapper
|
||||
let mut shell_command = Command::new("sh");
|
||||
shell_command.current_dir(&container_working_dir);
|
||||
shell_command.arg("-c");
|
||||
|
||||
// Join the original command and add trap for cleanup
|
||||
let command_str = format!("{{ {}; }} && wait", cmd.join(" "));
|
||||
shell_command.arg(command_str);
|
||||
|
||||
// Set environment variables
|
||||
for (key, value) in env_vars {
|
||||
shell_command.env(key, value);
|
||||
}
|
||||
|
||||
let output = shell_command
|
||||
.output()
|
||||
.map_err(|e| ContainerError::ContainerExecutionFailed(e.to_string()))?;
|
||||
|
||||
return Ok(ContainerOutput {
|
||||
stdout: String::from_utf8_lossy(&output.stdout).to_string(),
|
||||
stderr: String::from_utf8_lossy(&output.stderr).to_string(),
|
||||
exit_code: output.status.code().unwrap_or(-1),
|
||||
});
|
||||
}
|
||||
|
||||
// For all other commands
|
||||
let mut command = Command::new(cmd[0]);
|
||||
command.current_dir(&container_working_dir);
|
||||
|
||||
Reference in New Issue
Block a user