use anyhow::{bail, Result};
use linera_base::{command::CommandExt, time::Duration};
use tokio::process::{Child, Command};
use crate::client::{storage_service_check_absence, storage_service_check_validity};
pub struct StorageService {
endpoint: String,
binary: String,
}
pub struct StorageServiceGuard {
_child: Child,
}
impl StorageService {
pub fn new(endpoint: &str, binary: String) -> Self {
Self {
endpoint: endpoint.to_string(),
binary,
}
}
async fn command(&self) -> Command {
let mut command = Command::new(&self.binary);
command.args(["memory", "--endpoint", &self.endpoint]);
command.kill_on_drop(true);
command
}
async fn wait_for_absence(&self) -> Result<()> {
for i in 1..10 {
if storage_service_check_absence(&self.endpoint).await? {
return Ok(());
}
linera_base::time::timer::sleep(Duration::from_secs(i)).await;
}
bail!("Failed to start child server");
}
pub async fn run(&self) -> Result<StorageServiceGuard> {
self.wait_for_absence().await?;
let mut command = self.command().await;
let _child = command.spawn_into()?;
let guard = StorageServiceGuard { _child };
for i in 1..10 {
let result = storage_service_check_validity(&self.endpoint).await;
if result.is_ok() {
return Ok(guard);
}
linera_base::time::timer::sleep(Duration::from_secs(i)).await;
}
bail!("Failed to start child server");
}
}