Tide: Return a Future from app.serve

Created on 11 Apr 2019  路  6Comments  路  Source: http-rs/tide

Feature Request

Detailed Description

Instead of creating a runtime inside app.serve, I propose we return a future instead that allows people to run the app on whichever runtime they choose.

Context

From the API it currently isn't clear that Tide operates asynchronously. Also things like starting a database in parallel to Tide feels a bit awkward because async control flow primitives such as try_join and select don't work.

I propose we move from this:

#![feature(async_await)]

fn main() -> Result<(), failure::Error> {
    let mut app = tide::App::new(());
    app.at("/").get(async move |_| "Hello, world!");
    app.serve("127.0.0.1:8000")?;
}

To this:

#![feature(async_await)]

fn main() -> Result<(), failure::Error> {
    my_runtime::run(async {
        let mut app = tide::App::new(());
        app.at("/").get(async move |_| "Hello, world!");
        await!(app.serve("127.0.0.1:8000")?);
    })
}

We then shift the problem to making my_runtime::run nicer to use, but that's something that's worth solving for the whole async ecosystem, and not just Tide.

Possible Implementation

We would need to patch this line: https://github.com/rustasync/http-service/blob/master/http-service-hyper/src/lib.rs#L94, and propagate it through to Tide.

Most helpful comment

With Runtime we'll be able to also get rid of most of the boilerplate this change would introduce 馃槉 :
```rust

![feature(async_await)]

[runtime::main(runtime_tokio::Tokio)]

async fn main() -> Result<(), failure::Error> {
let mut app = tide::App::new(());
app.at("/").get(async move |_| "Hello, world!");
await!(app.serve("127.0.0.1:8000"))?;
}

All 6 comments

Within the bounds of this proposal, is it possible to still provide a "batteries-included" runtime experience for new users?

@secretfader you could have it return a custom future, that then as a function on it call say sync that will block and start the server. Under the hood it would consume itself, pass itself to a runtime.

I agree with this proposal. Currently, it is a challenge to set up an asynchronous database pool with Tide, as you can't use the same runtime as Tide.

With Runtime we'll be able to also get rid of most of the boilerplate this change would introduce 馃槉 :
```rust

![feature(async_await)]

[runtime::main(runtime_tokio::Tokio)]

async fn main() -> Result<(), failure::Error> {
let mut app = tide::App::new(());
app.at("/").get(async move |_| "Hello, world!");
await!(app.serve("127.0.0.1:8000"))?;
}

I'm working on this, the update on http-service-hyper is here: rustasync/http-service#21

Closed via #203

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Nemo157 picture Nemo157  路  6Comments

asaaki picture asaaki  路  4Comments

kamyuentse picture kamyuentse  路  4Comments

milesgranger picture milesgranger  路  6Comments

eignnx picture eignnx  路  4Comments