¿Cómo esperar a que finalicen las tareas de tokio?
Estoy intentando escribir en un HashMap
utilizando el patrón Arc<Mutex<T>>
como parte de un ejercicio de raspado de sitios web inspirado en The Rust Cookbook.
Esta primera parte utiliza la ejecución de tokio
. No puedo superar el hecho de que las tareas se completen y devuelvan el HashMap
ya que simplemente se cuelga.
type Db = Arc<Mutex<HashMap<String, bool>>>;
pub async fn handle<em>async</em>tasks(db: Db) -> BoxResult<HashMap<String, bool>> {
let links = NodeUrl::new("https://www.inverness-courier.co.uk/")
.await
.unwrap();
let arc = db.clone();
let mut handles = Vec::new();
for link in links.links_with_paths {
let x = arc.clone();
handles.push(tokio::spawn(async move {
process(x, link).await;
}));
}
futures::future::join_all(handles).await;
let readables = arc.lock().await;
for (key, value) in readables.clone().into_iter() {
println!("Checking db: k, v ==>{} / {}", key, value);
}
let clone_db = readables.clone();
return Ok(clone_db);
}
async fn process(db: Db, url: Url) {
let mut db = db.lock().await;
println!("checking {}", url);
if check_link(&url).await.is_ok() {
db.insert(url.to_string(), true);
} else {
db.insert(url.to_string(), false);
}
}
async fn check<em>link(url: &Url) -> BoxResult<bool> {
let res = reqwest::get(url.as_ref()).await?;
Ok(res.status() != StatusCode::NOT_FOUND)
}
pub struct NodeUrl {
domain: String,
pub links<em>with</em>paths: Vec<Url>,
}
#[tokio::main]
async fn main() {
let db: Db = Arc::new(Mutex::new(HashMap::new()));
let db = futures::executor::block_on(task::handle_async_tasks(db));
}
Me gustaría devolver el HashMap
a main()
donde el hilo principal está bloqueado. ¿Cómo puedo esperar a que se completen todos los procesos roscados asíncronos y devolver el HashMap
?
davy.ai
Para esperar a que finalicen y retornen todos los procesos enhebrados asíncronos y la
HashMap
, se puede usarfutures::future::join_all
para esperar a que todos los handlestokio::spawn
finalicen y luego retornar laHashMap
clonada. Aquí hay una versión actualizada de la funciónhandle_async_tasks
:Tenga en cuenta que clonamos el
MutexGuard
deArc<><><string, bool="">>>
enreadables
antes de devolverlo, ya que no se puede devolver el propio guard.</string,></string,>