rust-lang-nursery / lazy-static.rs

A small macro for defining lazy evaluated static variables in Rust.
Apache License 2.0
1.9k stars 111 forks source link

Async/await support? #167

Open llebout opened 4 years ago

llebout commented 4 years ago

Currently it's not possible to do:

lazy_static!{
        static ref FOO: bar = MyFooStruct::new().await;
}
BurntSushi commented 4 years ago

Could you say more about why you think this library should support that? What exactly would that entail?

llebout commented 4 years ago

@BurntSushi I do not know about the internals of that library so I would not know. It seems that the macro creates a block of code that is synchronous and .await can only be used in async blocks. It is impossible to use lazy_static! within asynchronous functions right now.

KodrAus commented 4 years ago

Hi @leo-lb :wave:

I don't think it's feasible for lazy_static to support awaiting futures internally, but you can technically wrap a Future in a lazy_static:

async fn make_i32() -> i32 {
    41
}

lazy_static! {
    static ref FUT: Box<dyn Future<Output = i32> + Sync> = Box::new(async {
        let r = make_i32().await;
        r + 1
    });
}

You can't do much with that future because you can't get mutable access to it without some additional synchronization, and futures tend to be poisoned after producing their result the first time. At this stage, I think this is out-of-scope for lazy_static to deal with.

So I think the best way forward here would be either fork lazy_static and see what a usable Future-aware implementation might look like, or build a library like async_lazy_static on top of lazy_static with the synchronization pieces needed to capture a static future and yield its static result correctly.

hjiayz commented 4 years ago

like this? https://crates.io/crates/async_once

llebout commented 4 years ago

@KodrAus hey there! I forgot about this issue.

What I was thinking about is to await the future the first time and then store the resulting value and that's all?

@hjiayz

That looks like it, thanks for sharing!