tokio_process_tools/
terminate_on_drop.rs1use crate::process_handle::ProcessHandle;
2use crate::{OutputStream, async_drop};
3use std::ops::{Deref, DerefMut};
4use std::time::Duration;
5
6#[derive(Debug)]
32pub struct TerminateOnDrop<Stdout: OutputStream, Stderr: OutputStream = Stdout> {
33 pub(crate) process_handle: ProcessHandle<Stdout, Stderr>,
34 pub(crate) interrupt_timeout: Duration,
35 pub(crate) terminate_timeout: Duration,
36}
37
38impl<Stdout, Stderr> Deref for TerminateOnDrop<Stdout, Stderr>
39where
40 Stdout: OutputStream,
41 Stderr: OutputStream,
42{
43 type Target = ProcessHandle<Stdout, Stderr>;
44
45 fn deref(&self) -> &Self::Target {
46 &self.process_handle
47 }
48}
49
50impl<Stdout, Stderr> DerefMut for TerminateOnDrop<Stdout, Stderr>
51where
52 Stdout: OutputStream,
53 Stderr: OutputStream,
54{
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 &mut self.process_handle
57 }
58}
59
60impl<Stdout, Stderr> Drop for TerminateOnDrop<Stdout, Stderr>
61where
62 Stdout: OutputStream,
63 Stderr: OutputStream,
64{
65 fn drop(&mut self) {
66 async_drop::run_future(async {
67 match self.process_handle.is_running() {
68 crate::RunningState::Terminated(_) => {
69 tracing::debug!(
70 process = %self.process_handle.name,
71 "Process already terminated"
72 );
73 self.process_handle.must_not_be_terminated();
76 return;
77 }
78 crate::RunningState::Running => {}
79 crate::RunningState::Uncertain(err) => {
80 tracing::warn!(
81 process = %self.process_handle.name,
82 error = %err,
83 "Could not determine process state during drop; attempting best-effort termination"
84 );
85 }
86 }
87
88 tracing::debug!(process = %self.process_handle.name, "Terminating process");
89 match self
90 .process_handle
91 .terminate(self.interrupt_timeout, self.terminate_timeout)
92 .await
93 {
94 Ok(exit_status) => {
95 tracing::debug!(
96 process = %self.process_handle.name,
97 ?exit_status,
98 "Successfully terminated process"
99 );
100 }
101 Err(err) => {
102 tracing::error!(
103 process = %self.process_handle.name,
104 error = %err,
105 "Failed to terminate process during drop"
106 );
107 }
108 }
109 });
110 }
111}