Tide: Choosing my own executor

Created on 12 Jun 2019  路  4Comments  路  Source: http-rs/tide

Feature Request

Hi, I checked the examples and the documentation, and couldn't find a way to choose my own executor to use with tide. I was wondering if there is a way to do this.
Note: Cross posted on the actix-web repository.

Detailed Description

Consider the basic example shown in this repository:

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

On which Executor does this app run? Is there a way to provide my own Executor?

Context

Let me explain why I want to do this: I have some code that uses Futures 0.3 and creates a TCP server. I would like to have all the code work together on one Executor, so for example, during the processing of some HTTP request I will be able to send something asynchronously through my TCP server.

One workaround I was thinking about is creating a new executor, having my other server run there and create a channel::mpsc to send messages from the tide HTTP server to my TCP server. I haven't tried it yet, I was wondering if this should actually work.

I am sure that most users that care about async request handling do some other kind of asynchronous processes (Otherwise, why would they need async request handling from the first place). I see no reason why those other asynchronous processes can't run on the same Executor.

Possible Implementation

An example of how this would look like is inspired by the aiohttp library (Python). See for example this piece of code:

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

In the example above it can be seen that aiohttp plays like a good citizen in the async world. It creates one future state machine, and finally the user of the library can put this state machine into any loop he wants. (loop can be seen as python's equivalent for Rust Futures's Executor).

Most helpful comment

So, after some hacking on http-service-hyper and runtime I've managed to get a Tide webapp running on runtime-native 馃帀

I'll try and open some PRs tomorrow to integrate these changes (although documenting how all these pieces fit together seems like another task in itself).

All 4 comments

Yes, it should be possible to run a Tide app on your own executor. Tide itself does not spawn futures, it provides an HttpService implementation (from https://github.com/rustasync/http-service) that is then run on a server which manages the futures. The App::run method is just a helper for using (currently, but presumably this could invisibly change) http-service-hyper to run the service. You could write your own HttpService host using your executor and use App::into_http_service to run a Tide application on it.

@Nemo157 : Thanks! I tried to play a bit with the code on master, but I didn't manage to run an App on the local thread executor (using block_on). See this issue: https://github.com/rustasync/tide/issues/280.
Most likely I have done something incorrect there.

So, after some hacking on http-service-hyper and runtime I've managed to get a Tide webapp running on runtime-native 馃帀

I'll try and open some PRs tomorrow to integrate these changes (although documenting how all these pieces fit together seems like another task in itself).

@Nemo157 wow, that's very impressive! -- very cool!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Nemo157 picture Nemo157  路  6Comments

kamyuentse picture kamyuentse  路  4Comments

friktor picture friktor  路  3Comments

milesgranger picture milesgranger  路  6Comments

deities-online picture deities-online  路  5Comments