runc: enhance documentation for ProcessMonitor

Enhance documentation for ProcessMonitor, to explicitly state the
requirement of ProcessMonitor::start().

Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
This commit is contained in:
Liu Jiang 2022-02-13 13:58:50 +08:00
parent 7a55e0f11b
commit 37975426b9
1 changed files with 19 additions and 6 deletions

View File

@ -21,20 +21,29 @@ use log::error;
use time::OffsetDateTime; use time::OffsetDateTime;
use tokio::sync::oneshot::{Receiver, Sender}; use tokio::sync::oneshot::{Receiver, Sender};
// ProcessMonitor for handling runc process exit /// A trait for spawning and waiting for a process.
// Implementation is different from Go's, because if you return Sender in start() and want to ///
// use it in wait(), then start and wait cannot be executed concurrently. /// The design is different from Go's, because if you return a `Sender` in [ProcessMonitor::start()]
// Alternatively, caller of start() and wait() have to prepare channel /// and want to use it in [ProcessMonitor::wait()], then start and wait cannot be executed
/// concurrently. Alternatively, let the caller to prepare the communication channel for
/// [ProcessMonitor::start()] and [ProcessMonitor::wait()] so they could be executed concurrently.
#[async_trait] #[async_trait]
pub trait ProcessMonitor { pub trait ProcessMonitor {
/// Caller cand choose [`std::mem::forget`] about resource /// Spawn a process and return its output.
/// associated to that command, e.g. file descriptors. ///
/// In order to capture the output/error, it is necessary for the caller to create new pipes
/// between parent and child.
/// Use [tokio::process::Command::stdout(Stdio::piped())](https://docs.rs/tokio/1.16.1/tokio/process/struct.Command.html#method.stdout)
/// and/or [tokio::process::Command::stderr(Stdio::piped())](https://docs.rs/tokio/1.16.1/tokio/process/struct.Command.html#method.stderr)
/// respectively, when creating the [Command](https://docs.rs/tokio/1.16.1/tokio/process/struct.Command.html#).
async fn start( async fn start(
&self, &self,
mut cmd: tokio::process::Command, mut cmd: tokio::process::Command,
tx: Sender<Exit>, tx: Sender<Exit>,
) -> std::io::Result<Output> { ) -> std::io::Result<Output> {
let chi = cmd.spawn()?; let chi = cmd.spawn()?;
// Safe to expect() because wait() hasn't been called yet, dependence on tokio interanl
// implementation details.
let pid = chi let pid = chi
.id() .id()
.expect("failed to take pid of the container process."); .expect("failed to take pid of the container process.");
@ -53,6 +62,8 @@ pub trait ProcessMonitor {
} }
} }
} }
/// Wait for the spawned process to exit and return the exit status.
async fn wait(&self, rx: Receiver<Exit>) -> std::io::Result<Exit> { async fn wait(&self, rx: Receiver<Exit>) -> std::io::Result<Exit> {
rx.await.map_err(|_| { rx.await.map_err(|_| {
error!("sender dropped."); error!("sender dropped.");
@ -61,6 +72,7 @@ pub trait ProcessMonitor {
} }
} }
/// A default implementation of [ProcessMonitor].
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct DefaultMonitor {} pub struct DefaultMonitor {}
@ -72,6 +84,7 @@ impl DefaultMonitor {
} }
} }
/// Process exit status returned by [ProcessMonitor::wait()].
#[derive(Debug)] #[derive(Debug)]
pub struct Exit { pub struct Exit {
pub ts: OffsetDateTime, pub ts: OffsetDateTime,