The following code compiles successfully, but the resulting binary crashes my Ubuntu system.
I thought I might need to use async move instead of async in the closure passed to the map function. However, neither rust-analyzer nor cargo build reported any errors when I used only async. Could anyone please explain what's wrong?
let cache: &Arc<Mutex<crate::llm::Cache>> = &*crate::llm::llm_cache;
let summarys_column:Vec<String> = knowledges.iter()
.map(async |x: &Knowledge| {
let texts: Vec<&str> = x.semantic_text();
super::summary::summary(texts.join("\n").as_str(), cache).await
})
.collect::<futures::stream::FuturesUnordered<_>>()
.try_collect::<Vec<KnowledgeSummary>>()
.await
.unwrap()
.iter()
.map(|x: &KnowledgeSummary| serde_json::to_string(x).unwrap())
.collect();
do you mean the program crashed on Ubuntu, or the operating system itself crashed?
in any case, it has nothing to do with async vs async move, if it compiles, there's no type error in this piece of code.
however, there must be some deeper problem elsewhere, for example, if the OS crashes, you might found a kernel or driver bug; if your program crashes, some unsafe block in your code or the dependency crates is unsound.
more details and efforts are needed to diagnose the root cause.
All instances of that closure are run by the .try_collect().await, and knowledges is not dropped before then, so there is no need to avoid borrowing. Generally, async move is needed for spawned tasks and async callbacks; this is neither, and it doesn't need move any more than the regular .iter().map() you have later does.