How to manage globals in async code

I’m using warp and finding it very natural, but I’m coming across the following problem:

// ...

let db_pool = get_r2d2_pool();

// ...

warp::get()
    .and_then(|| {
        let conn = db_pool.get();
        // ...
    });

which gives me the error closure may outlive the current function....

What I need is a way to make sure that my context object outlives any futures spawned (and convince the compiler this is true). How do I do this? My current solution uses lazy_static but I don’t think that’s scalable.

Is the r2d2 pool Clone? If so, you’d clone it and then move the clone into the closure.

Otherwise, the canonical way to manage global-like resources is to initialize them early in your program, put them inside an Arc (if you need cross-thread access to them), possibly also inside a Mutex or some other synchronization primitive if you need mutable access, and then share that resource via clones of the Arc.

here’s a quick example maybe?

Thanks! Do you know why this works but my example doesn’t?

Aah, it turns out @vitalyd is right and I misunderstood how values are moved into closures. I assumed that

move || { outer.clone() }

would not solve the problem because outer is still moved into the closure, but this apparently isn’t the case.

That should move outer into the closure; the closure, when invoked, would then return a clone from its owned value. But what happens to the “original” outer depends on its type (e.g. if it’s Copy, such as a reference, then of course you can continue using it despite it being move'd into the closure).