From 9f6d2d7b3b7678a73126f3920a73cd2084cf2bbb Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 3 Sep 2023 15:33:03 +0100 Subject: [PATCH] Do proper async parallelism --- src/main.rs | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1f2e12f..7bac30a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use axum::{routing::get, Router}; use serde::Serialize; use std::collections::HashSet; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; +use tokio::task::JoinSet; #[derive(Clone)] struct AppState { @@ -18,6 +19,27 @@ struct DokkuApp { hosts: HashSet, } +impl DokkuApp { + async fn try_from_path(path: PathBuf) -> Option { + let vhost_path = path.join("VHOST"); + + if !vhost_path.is_file().await { + return None; + } + + let current_vhosts = read_to_string(&vhost_path).await.unwrap(); + + if current_vhosts.is_empty() { + return None; + } + + Some(DokkuApp { + name: String::from(path.file_name().unwrap().to_str().unwrap()), + hosts: current_vhosts.lines().map(String::from).collect(), + }) + } +} + fn get_dokku_root() -> Option { // First, check if we have a custom directory if let Some(dokku_root) = std::env::var_os("DOKKU_ROOT") { @@ -48,28 +70,22 @@ fn get_dokku_root() -> Option { async fn hosts(State(state): State) -> axum::Json> { let mut dir_entries = state.dokku_root.read_dir().await.unwrap(); - let mut apps: Vec = Vec::new(); + let mut join_set = JoinSet::new(); while let Some(Ok(dir_entry)) = dir_entries.next().await { let path = dir_entry.path(); - let vhost_path = path.join("VHOST"); - - if !vhost_path.is_file().await { - continue; - } - - let current_vhosts = read_to_string(&vhost_path).await.unwrap(); - - if current_vhosts.is_empty() { - continue; - } - - apps.push(DokkuApp { - name: String::from(path.file_name().unwrap().to_str().unwrap()), - hosts: current_vhosts.lines().map(String::from).collect(), - }); + join_set.spawn(DokkuApp::try_from_path(path)); } + + let mut apps: Vec = Vec::new(); + + while let Some(res) = join_set.join_next().await { + if let Some(app) = res.unwrap() { + apps.push(app) + } + } + axum::Json(apps) }