I am trying to execute an async function using a vector containing arguments, then collect the futures in another vector to join later.
I am getting a compiler error due to passing the ldap argument as a mutable reference ldap was mutably borrowed here in the previous iteration of the looprustc(E0499)
. I don't get this error when calling the function synchronously with await()
.
How can fix the lifetime of the ldap argument in run_query()?
Also if anyone has a more idiomatic method of executing a asynchronous function with a vector of arguments please let me know, any help is appreciated thanks!
code:
use ldap3::{Ldap, LdapConnAsync, Scope, SearchEntry, result::Result};
#[derive(Serialize, Deserialize, Debug)]
struct Query{
name: String,
base_dn: String,
query: String,
attr: Vec<String>,
}
async fn run_query(ldap: &mut Ldap, query: Query) -> Result<String>{
// run query
let (rs, _res) = ldap.search(
&query.base_dn,
Scope::Subtree,
&query.query,
&query.attr
).await?.success()?;
// output results
let output = resultentries_to_string(rs).unwrap();
return Ok(output);
}
#[tokio::main]
async fn main() -> Result<()> {
let query = ...Vector of Query struct...
let (conn, mut ldap) = LdapConnAsync::new("ldap://localhost:389").await?;
let mut futures:Vec<_> = Vec::new();
for query in queries{
futures.push(run_query(&mut ldap, query));
}
join_all(futures);
}
Full Error:
error[E0499]: cannot borrow `ldap` as mutable more than once at a time
--> src/main.rs:174:32
|
174 | futures.push(run_query(&mut ldap, query));
| ^^^^^^^^^ `ldap` was mutably borrowed here in the previous iteration of the loop
The reason you get the error is that inisde the for loop you borrow ldap multiple times. In the synchronous case it works because you wait for every iteration to end (no multiple mutable borrows of ldap at the same time, which os not the async case).
To overcome this issue, if it is not too expensive, you can clone ldap every time you use a query:
for query in queries{
let mut ldap_clone = ldap.clone()
futures.push(run_query(&mut ldap_clone, query));
}
You also need to change the signature to accept the actual object, not the reference