Search code examples
rustrust-tokioscylla

Tokio cannot use method parameter to spawn future safely


In this function, I would like to add a query to a JoinSet. Inexplicably, the compiler complains that the lifetime of scylla does not last long enough.

pub async fn foobar(scylla: Data<scylla::Session>) {
    let mut queries = tokio::task::JoinSet::new();
    let task = scylla.query("hello", &[]);
    queries.spawn(task);
    queries.join_next().await;
}
`scylla` does not live long enough
borrowed value does not live long enough (rustc) Click for full compiler diagnostic
post.rs(46, 1): `scylla` dropped here while still borrowed

The error specifically happens on the scylla.query call and the line it says scylla is dropped on is at the end of the function. It does not complain if I run await directly without trying to joinset, but I would like many queries to run parallel to each other.

I have tried cloning scylla without any success. I've also tried messing with lifetime brackets. It just really does not want to move its future into a joinset.

JoinSets are also not the problem, I cannot simply tokio::spawn() on this variable either. The issue appears to be that the value is used in the async functions, so the compiler is uncertain that those functions will be completed before the parent method has completed, even though the logic of the code means that it will have.


Solution

  • To convince the compiler, move scylla into the future (by the way, the compiler is right, they may not complete):

    pub async fn foobar(scylla: Data<scylla::Session>) {
        let mut queries = tokio::task::JoinSet::new();
        queries.spawn(async move {
            scylla.query("hello", &[]).await;
        });
        queries.join_next().await;
    }