Skip to content

Commit a6a96ff

Browse files
committed
feat: Adds service healthy for depends_on
1 parent d7520cf commit a6a96ff

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

SERVICE_CONFIG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,15 @@ The `[depends_on]` section defines dependencies between services.
375375

376376
```toml
377377
[depends_on]
378-
postgres = "service-started"
378+
postgres = "service-healthy"
379379
redis = "service-started"
380380
migration = "service-completed"
381381
```
382382

383383
**Valid conditions:**
384384
- `service-started` or `started` - Wait for service to start
385385
- `service-completed` or `completed` - Wait for service to complete
386+
- `service-healthy` or `healthy` - Wait for service to reach a healthy state. If the service has no health check defined, it is considered healthy as soon as it is started.
386387

387388
## Proxy Configuration
388389

src/service/file.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,19 @@ pub enum DependsOnCondition {
189189
alias = "service_started",
190190
alias = "started"
191191
)]
192-
ServiceStarted,
192+
Started,
193193
#[serde(
194194
alias = "service-completed",
195195
alias = "service_completed",
196196
alias = "completed"
197197
)]
198-
ServiceCompleted,
198+
Completed,
199+
#[serde(
200+
alias = "service-healthy",
201+
alias = "service_healthy",
202+
alias = "healthy"
203+
)]
204+
Healthy,
199205
}
200206

201207
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]

src/service/instance.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::net::{Ipv4Addr, SocketAddrV4};
22
use std::{collections::HashMap, path::PathBuf, sync::Arc, time::Duration};
33

44
use bollard::models::{
5-
ContainerCreateBody, EndpointIpamConfig, EndpointSettings, HostConfig, NetworkConnectRequest,
6-
NetworkingConfig, PortBinding, RestartPolicy, RestartPolicyNameEnum,
5+
ContainerCreateBody, EndpointIpamConfig, EndpointSettings, HealthStatusEnum, HostConfig,
6+
NetworkConnectRequest, NetworkingConfig, PortBinding, RestartPolicy, RestartPolicyNameEnum,
77
};
88
use bollard::query_parameters::{
99
CreateContainerOptions, CreateContainerOptionsBuilder, CreateImageOptions,
@@ -51,8 +51,16 @@ pub struct ServiceInstance {
5151
}
5252

5353
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54+
pub enum HealthStatus {
55+
Starting,
56+
Healthy,
57+
Unhealthy,
58+
None,
59+
}
60+
61+
#[derive(Debug, Clone, PartialEq, Eq)]
5462
pub enum ContainerStatus {
55-
Running,
63+
Running { health: HealthStatus },
5664
Exited(i32),
5765
NotFound,
5866
}
@@ -71,7 +79,13 @@ async fn get_container_status(container_name: &str) -> Result<ContainerStatus, S
7179
Ok(info) => {
7280
if let Some(state) = info.state {
7381
if state.running.unwrap_or(false) {
74-
return Ok(ContainerStatus::Running);
82+
let health = match state.health.and_then(|h| h.status) {
83+
Some(HealthStatusEnum::HEALTHY) => HealthStatus::Healthy,
84+
Some(HealthStatusEnum::UNHEALTHY) => HealthStatus::Unhealthy,
85+
Some(HealthStatusEnum::STARTING) => HealthStatus::Starting,
86+
_ => HealthStatus::None,
87+
};
88+
return Ok(ContainerStatus::Running { health });
7589
}
7690
let exit_code = state.exit_code.unwrap_or(-1) as i32;
7791
return Ok(ContainerStatus::Exited(exit_code));
@@ -92,12 +106,18 @@ impl ServiceInstance {
92106
for (container, condition) in &self.config.depends_on {
93107
let status = match get_container_status(container).await {
94108
Ok(status) => match condition {
95-
DependsOnCondition::ServiceStarted => {
96-
matches!(status, ContainerStatus::Running)
109+
DependsOnCondition::Started => {
110+
matches!(status, ContainerStatus::Running { .. })
97111
}
98-
DependsOnCondition::ServiceCompleted => {
112+
DependsOnCondition::Completed => {
99113
matches!(status, ContainerStatus::Exited(0))
100114
}
115+
DependsOnCondition::Healthy => match status {
116+
ContainerStatus::Running { health } => {
117+
matches!(health, HealthStatus::Healthy | HealthStatus::None)
118+
}
119+
_ => false,
120+
},
101121
},
102122
Err(_) => false,
103123
};

0 commit comments

Comments
 (0)