loam_cli/commands/dev/
docker.rs1use soroban_cli::{commands as cli, CommandParser};
2use std::error::Error;
3
4pub async fn start_local_stellar() -> Result<(), Box<dyn Error>> {
5 let result = cli::container::StartCmd::parse_arg_vec(&["local"])?
6 .run(&soroban_cli::commands::global::Args::default())
7 .await;
8
9 match result {
10 Ok(()) => {
11 tokio::time::sleep(std::time::Duration::from_secs(10)).await;
12 }
13 Err(e) => {
14 if e.to_string().contains("already in use")
15 || e.to_string().contains("port is already allocated")
16 {
17 eprintln!("Container is already running, proceeding to health check...");
18 } else {
19 return Err(Box::new(e));
20 }
21 }
22 }
23
24 wait_for_stellar_health().await?;
25 Ok(())
26}
27async fn wait_for_stellar_health() -> Result<(), Box<dyn Error>> {
28 let client = reqwest::Client::new();
29 let start_time = std::time::Instant::now();
30 let timeout = std::time::Duration::from_secs(60);
31 loop {
32 let elapsed_time = start_time.elapsed();
33 if elapsed_time > timeout {
34 eprintln!("Timeout reached: stopping health checks.");
35 return Err("Health check timed out".into());
36 }
37 let res = client
38 .post("http://localhost:8000/rpc")
39 .header("Content-Type", "application/json")
40 .body(r#"{"jsonrpc": "2.0", "id": 1, "method": "getHealth"}"#)
41 .send()
42 .await?;
43 if res.status().is_success() {
44 let health_status: serde_json::Value = res.json().await?;
45 if health_status["result"]["status"] == "healthy" {
46 break;
47 }
48 eprintln!("Stellar status is not healthy: {health_status:?}");
49 } else {
50 eprintln!("Health check request failed with status: {}", res.status());
51 }
52 tokio::time::sleep(std::time::Duration::from_secs(5)).await;
53 eprintln!("Retrying health check.");
54 }
55 Ok(())
56}