I have the following code:
#[tokio::main]
async fn main() {
let db: Db = Arc::new(Mutex::new(HashMap::new()));
let block_res = get_block_addresses().await;
match block_res {
Ok(v) => {
println!("Block downloaded, grabbing contracts");
println!("Txs: {}", v.result.transactions.len());
for obj in v.result.transactions {
let db1 = db.clone();
let db2 = db.clone();
let to = obj.to.clone();
let from = obj.from.clone();
tokio::spawn(async move {
let resp = check_if_contract(to, db1).await;
});
tokio::spawn(async move {
let resp = check_if_contract(from, db2).await;
});
}
}
Err(e) => {
println!("error parsing header: {:?}", e);
}
}
}
As you can see it never awaits the result of the spawns. How can I properly await these JoinHandle
s after the for loop has done it's thing? I wanted to avoid using an array of tasks and iterating over them. Since I had seen in Jon Gjengset's video that there exists something like a NotifyHandle
, that stores tasks by id. But I have no clue how to use it, or if it even makes sense in this context. I'm new to rust and async programming so I hope my question made some sense.
The most efficient way at this point in time for a dynamic amount of tasks is to utilize FuturesUnordered, which represents a collection of Future
s where one can wait on the next Future
to resolve.
In your case it would be something along:
let tasks = FuturesUnordered::new();
for obj in v.result.transactions {
let db1 = db.clone();
let db2 = db.clone();
let to = obj.to.clone();
let from = obj.from.clone();
tasks.push(tokio::spawn(async move {
check_if_contract(to, db1).await
}));
tasks.push(tokio::spawn(async move {
check_if_contract(from, db2).await
}));
}
while let Some(finished_task) = tasks.next().await {
match finished_task {
Err(e) => { /* e is a JoinError - the task has panicked */},
Ok(result) => { /* result is the result of check_if_contract */ }
}
}
If you need to identify the transaction in the final loop, return something which identifies the task from the functions you spawn - then it will be part of result
.