use super::http_server::DataFoldHttpServer;
use crate::datafold_node::DataFoldNode;
use crate::error::FoldDbResult;
use std::sync::Arc;
use tokio::task::JoinHandle;
pub struct EmbeddedServerHandle {
task_handle: JoinHandle<FoldDbResult<()>>,
bind_address: String,
}
impl EmbeddedServerHandle {
pub fn bind_address(&self) -> &str {
&self.bind_address
}
pub fn is_running(&self) -> bool {
!self.task_handle.is_finished()
}
pub async fn wait(self) -> FoldDbResult<()> {
self.task_handle
.await
.map_err(|e| crate::error::FoldDbError::Other(format!("Server task panicked: {}", e)))?
}
pub fn abort(&self) {
self.task_handle.abort();
}
}
pub async fn start_embedded_server(
node: DataFoldNode,
port: u16,
) -> FoldDbResult<EmbeddedServerHandle> {
let bind_address = format!("127.0.0.1:{}", port);
let server = DataFoldHttpServer::new(node, &bind_address).await?;
let address = bind_address.clone();
let task_handle = tokio::spawn(async move { server.run().await });
Ok(EmbeddedServerHandle {
task_handle,
bind_address: address,
})
}
pub async fn start_embedded_server_shared(
node: Arc<tokio::sync::Mutex<DataFoldNode>>,
port: u16,
) -> FoldDbResult<EmbeddedServerHandle> {
let node_instance = {
let guard = node.lock().await;
guard.clone()
};
start_embedded_server(node_instance, port).await
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[tokio::test]
async fn test_embedded_server_starts() {
let temp_dir = tempdir().unwrap();
let mut config =
crate::datafold_node::config::NodeConfig::new(temp_dir.path().to_path_buf());
config.schema_service_url = Some("mock://test".to_string());
let node = DataFoldNode::new(config).await.unwrap();
use rand::Rng;
let port = rand::thread_rng().gen_range(50000..60000);
let handle = start_embedded_server(node, port).await.unwrap();
assert!(handle.is_running());
assert_eq!(handle.bind_address(), format!("127.0.0.1:{}", port));
handle.abort();
}
}