use std::time::Duration;
use super::RawContainer;
use crate::core::{client::Client, error::WaitContainerError, wait::WaitStrategy};
#[derive(Debug, Clone)]
pub struct ExitWaitStrategy {
expected_code: Option<i64>,
poll_interval: Duration,
}
impl ExitWaitStrategy {
pub fn new() -> Self {
Self {
expected_code: None,
poll_interval: Duration::from_millis(100),
}
}
pub fn with_poll_interval(mut self, poll_interval: Duration) -> Self {
self.poll_interval = poll_interval;
self
}
pub fn with_exit_code(mut self, expected_code: i64) -> Self {
self.expected_code = Some(expected_code);
self
}
}
impl WaitStrategy for ExitWaitStrategy {
async fn wait_until_ready(
self,
client: &Client,
container: &RawContainer,
) -> crate::core::error::Result<()> {
loop {
let container_state = client
.inspect(container.id())
.await?
.state
.ok_or(WaitContainerError::StateUnavailable)?;
let is_running = container_state.running.unwrap_or_default();
if is_running {
tokio::time::sleep(self.poll_interval).await;
continue;
}
if let Some(expected_code) = self.expected_code {
let exit_code = container_state.exit_code;
if exit_code != Some(expected_code) {
return Err(WaitContainerError::UnexpectedExitCode {
expected: expected_code,
actual: exit_code,
}
.into());
}
}
break;
}
Ok(())
}
}
impl Default for ExitWaitStrategy {
fn default() -> Self {
Self::new()
}
}