use std::time::Duration;
use bollard::models::HealthStatusEnum::*;
use super::RawContainer;
use crate::core::{client::Client, error::WaitContainerError, wait::WaitStrategy};
#[derive(Debug, Clone)]
pub struct HealthWaitStrategy {
poll_interval: Duration,
}
impl HealthWaitStrategy {
pub fn new() -> Self {
Self {
poll_interval: Duration::from_millis(100),
}
}
pub fn with_poll_interval(mut self, poll_interval: Duration) -> Self {
self.poll_interval = poll_interval;
self
}
}
impl WaitStrategy for HealthWaitStrategy {
async fn wait_until_ready(
self,
client: &Client,
container: &RawContainer,
) -> crate::core::error::Result<()> {
loop {
let health_status = client
.inspect(container.id())
.await?
.state
.ok_or(WaitContainerError::StateUnavailable)?
.health
.and_then(|health| health.status);
match health_status {
Some(HEALTHY) => break,
None | Some(EMPTY) | Some(NONE) => Err(
WaitContainerError::HealthCheckNotConfigured(container.id().to_string()),
)?,
Some(UNHEALTHY) => Err(WaitContainerError::Unhealthy)?,
Some(STARTING) => {
tokio::time::sleep(self.poll_interval).await;
}
}
}
Ok(())
}
}
impl Default for HealthWaitStrategy {
fn default() -> Self {
Self::new()
}
}