How do poll an async function in a function that returns a Future but itself is not async?

I tried but this does not work boxed returns a Pin what I need is a futures:future::Ready

That's one way to do it?

Usually you would box the future last, though. There isn't really much advantage to using .boxed() except for the ability to name the exact type of the future. In fact, it will introduce dynamic dispatch, and make things slightly less efficient. The big advantage is that all different types of futures can be unified as a single dynamically-dispatch type, BoxFuture, which you can name (in, say, your trait as type Future = BoxFuture<...>)

You should return a Future that internally calls the async function you wish to await.

Why do you need this? Ready is a particular future, doing exactly one thing - implementing the ready function. Unless you use that function, you cannot produce a Ready. It's not a general-purpose future.

If I box it last I cant to anything with it since there's no and_then map etc on std futures

The FutureExt trait provides a then method that is similar to and_then and usable on std futures.

I am trying to implement FromRequest trait on my type isnt this sooo stupid then all the handlers are async functions in actix-web but extractors have to be blocking what is the point of using async in the first place then

You aren't supposed to block in actix. You need to return a future that does the work you want to happen.

1 Like

If I am understanding correctly, you're forcing yourself to be blocking by declaring your future type as Ready. This is not in general required. Does the followng not work?

impl FromRequest for Thing {
    type Error = Error;
    type Future = BoxFuture<Result<Self, Self::Error>>;
    type Config = ();

    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
        (async {
            (...).await;
        }).boxed()
    }
}
1 Like


this is an example from the official docs

Yes, that example is not using async - because for that example, it wasn't required. In general, the interface does allow for writing async code inside handlers.

The type Future = ... here is declaring what your function returns. You can return any kind of future, such as a BoxFuture if you want to use an async` block and async/await code, but you need to declare it. Let me know if that seems reasonable?

Ah so I can use anything as Future type which would mean I also can use std futures right without having to go through all the trouble of converting things back and forth ?

Yes. To be clear, stuff like Ready is also a certain kind of std future. It's just not a very powerful one.

1 Like

Yep - as long as it is a declarable type!

The reason I suggest BoxFuture is because every combinator adds another type. Like x.then(...).map(...).or_else(...) is OrElse<Map<Then<X, fn(...) -> ...>, fn(...) -> ...>, fn(...) -> ...> and that just because unwieldy (or outright impossible) to type.

apparently I cant use std futures because their size is unknown at compile time but I also cannot use boxed std futures because it is not unpin.

The std future type is a trait and not a struct, so you can't use it directly. To talk about "any type that implements the Future trait", you're going to need a special kind of thing called a trait object. And you can indeed get around the Unpin requirement by using Box::pin like this:

type Future = Pin<Box<dyn Future<Output = Foo>>>
// later
Box::pin(async move { ... })

The BoxFuture that @daboross suggested is a type alias for the Pin<Box<...>> combination above.

If you simply use Box::new without Pin, then you do indeed need the future to be Unpin, which async blocks are not.

2 Likes

this works without using anything specific from futures thanks

1 Like

funny thing is that the documentation doesnt mention anything about Pin

No, Pin comes from the fact that if F implements the Future trait, then Box<F> doesn't necessarily also implement that trait: F must also implement Unpin for Box<F> to implement Future. The unpin issue is a property of boxes, not a property of futures, and so you'd have to look at the doc for Box to find out about this.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.