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.
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.
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.
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
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
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"))?;
}