tower-rs / tower-h2

An HTTP/2.0 client and server `Service` implementation.
MIT License
89 stars 18 forks source link

Integrate with default tokio runtime via tokio::run #36

Closed caipre closed 6 years ago

caipre commented 6 years ago

I'm having trouble getting tower-h2 to work with the default tokio runtime. See the code in https://github.com/caipre/tower-h2-tokio-run/blob/e79f83365164d64ae35c1e0f446c16c0d7388bcc/src/main.rs#L84-L98 ; it's virtually identical to the example included in this repository, but using tokio::run rather than building the Runtime manually.

The error I'm seeing is:

error[E0599]: no method named `map_err` found for type `tower_h2::server::Connection<tokio::net::TcpStream, FooNewService, tokio::reactor::Handle, RespBody, ()>` in the current scope
  --> src/main.rs:91:18
   |
91 |                 .map_err(|err| error!("h2 error: {:?}", err))
   |                  ^^^^^^^
   |
   = note: the method `map_err` exists but the following trait bounds were not satisfied:
           `tower_h2::server::Connection<tokio::net::TcpStream, FooNewService, tokio::reactor::Handle, RespBody, ()> : futures::Future`
           `&mut tower_h2::server::Connection<tokio::net::TcpStream, FooNewService, tokio::reactor::Handle, RespBody, ()> : futures::Stream`
`&mut tower_h2::server::Connection<tokio::net::TcpStream, FooNewService, tokio::reactor::Handle, RespBody, ()> : futures::Future`

Any help is greatly appreciated!

carllerche commented 6 years ago

Here is an example: https://github.com/tower-rs/tower-h2/blob/master/examples/server.rs#L102

Unfortunately, to pass in DefaultExecutor does not work yet. It requires a change on master which should be released this week.

I'm closing, please let me know if this did not solve your problem.

caipre commented 6 years ago

Thanks for the response. I guess my problem is exactly that that, that DefaultExecutor doesn't work yet. I guess I'll wait for the upcoming change. Is there an issue tracking it, or more details about what's not working?

I also don't understand why map_err isn't available when the Connection type returned by h2.serve implements Future. Mind explaining that if you're able?

carllerche commented 6 years ago

It is because the trait bounds are not satisfied. Server only implements Future when a T: Executor is passed in. However, tokio_reactor::Handle is not an executor. Because of this, Server does not implement Future which means that the associated methods like map_err are not available.

caipre commented 6 years ago

Hmm, okay -- my interpretation of the error was that the Connection type was missing the map_err method, rather than the Server type. I've now changed from using Handle to DefaultExecutor, but this gives the same error as before (even though DefaultExecutor does implement Executor). Seems I'll need to wait for the changes you mentioned as landing later this week; curious to see what they are.

Thanks for the responses. 👍

ebkalderon commented 5 years ago

By any chance, have these proposed changes landed yet? I am still seeing this error when using h2 with a DefaultExecutor.

error[E0599]: no method named `map_err` found for type `tower_h2::server::Connection<tokio::net::TcpStream, example::foo::server::FooServer<ServerImpl>, tokio::executor::DefaultExecutor, example::foo::server::foo::ResponseBody<ServerImpl>, ()>` in the current scope
  --> src/bin/server.rs:58:26
   |
58 |             .spawn(serve.map_err(|e| { println!("{:?}", e); () }));
   |                          ^^^^^^^
   |
   = note: the method `map_err` exists but the following trait bounds were not satisfied:
           `tower_h2::server::Connection<tokio::net::TcpStream, example::foo::server::FooServer<ServerImpl>, tokio::executor::DefaultExecutor, example::foo::server::foo::ResponseBody<ServerImpl>, ()> : futures::Future`
           `&mut tower_h2::server::Connection<tokio::net::TcpStream, example::foo::server::FooServer<ServerImpl>, tokio::executor::DefaultExecutor, example::foo::server::foo::ResponseBody<ServerImpl>, ()> : futures::Stream`
           `&mut tower_h2::server::Connection<tokio::net::TcpStream, example::foo::server::FooServer<ServerImpl>, tokio::executor::DefaultExecutor, example::foo::server::foo::ResponseBody<ServerImpl>, ()> : futures::Future`
carllerche commented 5 years ago

@ebkalderon It should be possible now! Make sure you are on the latest version of Tokio.

I have updated the example in this PR: https://github.com/tower-rs/tower-h2/pull/47