Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with tokio? #54

Closed
jedisct1 opened this issue Aug 16, 2019 · 11 comments
Closed

Compatibility with tokio? #54

jedisct1 opened this issue Aug 16, 2019 · 11 comments

Comments

@jedisct1
Copy link

Hi,

And kudos for this very promising project.

I'm currently trying to replace all instances of futures.rs and tokio with async-std.

However, hyper requires streams that implement the tokio::io::AsyncRead and AsyncWrite traits.

Given a stream obtained from async-std, such as a TcpStream, how can I get something that implements tokio's traits?

Thanks again for async-std!

@skade
Copy link
Collaborator

skade commented Aug 16, 2019

I'll take a look at it tomorrow, but on cursory glance, it's probably best to implement tokio::io::AsyncRead/Write outside of this lib as implementing them inside of it is not in scope. We lobby for using futures-rs as the generic way of compatibility between libraries.

FWIW, here's the trick to implement a foreign trait for a foreign type:

use async_std::net::TcpStream;
use some::foreign::Trait;

struct CompatStream(TcpStream);

impl Trait for CompatStream {
   //... use `compat_stream.0` here
}

@jedisct1
Copy link
Author

Probably not the best way to do it, but that did the trick:

use async_std::net::TcpStream;
use async_std::os::unix::net::UnixStream;
use async_std::task::{Context, Poll};
use futures::io::{AsyncRead, AsyncWrite};
use std::io;
use std::pin::Pin;

pub struct TokioCompat<T>(T);

pub trait TokioCompatExt: AsyncRead + AsyncWrite + Sized {
    #[inline]
    fn compat(self) -> TokioCompat<Self> {
        TokioCompat(self)
    }
}

impl<T: AsyncRead + Unpin> tokio::io::AsyncRead for TokioCompat<T> {
    #[inline]
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
        buf: &mut [u8],
    ) -> Poll<Result<usize, io::Error>> {
        Pin::new(&mut self.0).poll_read(cx, buf)
    }
}

impl<T: AsyncWrite + Unpin> tokio::io::AsyncWrite for TokioCompat<T> {
    #[inline]
    fn poll_write(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
        buf: &[u8],
    ) -> Poll<Result<usize, io::Error>> {
        Pin::new(&mut self.0).poll_write(cx, buf)
    }

    #[inline]
    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
        Pin::new(&mut self.0).poll_flush(cx)
    }

    #[inline]
    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
        Pin::new(&mut self.0).poll_close(cx)
    }
}

impl TokioCompatExt for UnixStream {}
impl TokioCompatExt for TcpStream {}

@DoumanAsh
Copy link

hyper still uses tokio's primitives so I'm not sure about getting rid of tokio, at least you'll need it's reactor

@sdroege
Copy link

sdroege commented Aug 17, 2019

hyper still uses tokio's primitives so I'm not sure about getting rid of tokio, at least you'll need it's reactor

And probably the whole tokio runtime as I'm sure hyper also makes use of its timer infrastructure for example.

However, hyper requires streams that implement the tokio::io::AsyncRead and AsyncWrite traits.

I believe the correct way forward here would be for tokio (or more specifically tokio-io) to simply re-export the traits from the futures crate instead of defining their own. I don't think there's a reason left for a separate trait definition. But obviously that would have to be taken up with the tokio project :)

@DoumanAsh
Copy link

DoumanAsh commented Aug 17, 2019

And probably the whole tokio runtime as I'm sure hyper also makes use of its timer infrastructure for example.

No, you only need reactor as it is used to interact with mio.
You can disable runtime features
As async-std has own reactor, it makes them incompatible.

@taiki-e
Copy link
Contributor

taiki-e commented Aug 17, 2019

See also tokio-rs/tokio#1297

@CarlosLanderas
Copy link

I am learning rust and I would like to know what would be the best way to perform async http requests using async-std if you are not coupled to Hyper/Tokio?

Maybe using reqwest in an async function?

@skade
Copy link
Collaborator

skade commented Aug 17, 2019

I can recommend using https://github.com/rustasync/surf

@opensourcegeek
Copy link

How about HTTP server? Is there any implementation that uses async-std (may be even in pipeline currently)?

@jedisct1
Copy link
Author

jedisct1 commented Aug 18, 2019

@opensourcegeek Try Tide

I'm trying to build a proxy, that accepts and connects to Unix sockets and fixed IP addresses, so the surf +tide combo doesn't seem to be an option. Back to tokio :(

@yoshuawuyts
Copy link
Contributor

It seems conversation has settled down here so I'm going to go ahead and close this. Thanks everyone!

kevinastone added a commit to kevinastone/gotham that referenced this issue Nov 5, 2019
kevinastone added a commit to kevinastone/gotham that referenced this issue Nov 8, 2019
With the anticipated release of async-await in stable rust this week, I took an effort to migrate Gotham to run on std futures using the pre-release versions of the dependencies (tokio, hyper, etc).

This doesn't attempt to introduce `await` or `async fn` into the codebase (there was a single unavoidable case due to an `tokio::File::metadata` API change).  That is designed as a future activity.

This migration involved a few key efforts:

1. Convert from Futures 0.1 to Futures-preview 0.3 (mostly `Future<Item=>` to `Future<Output=Result<>>`).
2. Update dependencies to pre-release versions (`tokio-0.2` and `hyper-0.13`).  There's still other dependencies that are outstanding and blocking the full release.
3. Migrate Handler trait to a pinned box HandlerFuture.

This is a work-in-progress with a few blockers before this would be ready:

Gotham Dependencies:

[ ] Update Futures from `futures-preview` to `futures = 0.3` when the other dependencies (hyper, tokio, etc) update in concert.
[ ] Update Tokio to `0.2` from alpha pre-releases
[ ] Update Hyper to `0.13` from alpha pre-releases
[ ] Update Tower-Service to `0.3` from alpha pre-releases.  Hyper is migrating many of its traits to `tower-service::Service` and so is now a direct dependency.
[ ] Released version of `futures_rustls` which is currently a branch of `tokio-rustls` ported to Futures-preview
[ ] Released version of `futures-tokio-compat` or suggested `tokio::compat` library for bridging `futures::AsyncRead` and `tokio::AsyncRead`.  See tokio-rs/tokio#1297
    and async-rs/async-std#54

Middleware Dependencies:

[ ] Diesel - Requires updated release of `tokio-threadpool`
[ ] JWT - Requires updated release of `jsonwebtoken`
kevinastone added a commit to kevinastone/gotham that referenced this issue Nov 8, 2019
With the anticipated release of async-await in stable rust this week, I took an effort to migrate Gotham to run on std futures using the pre-release versions of the dependencies (tokio, hyper, etc).

*NOTE*: This doesn't attempt to introduce `await` or `async fn` into the codebase (there was a single unavoidable case due to an `tokio::File::metadata` API change).  That is designed as a future activity.

This migration involved a few key efforts:

1. Convert from Futures 0.1 to Futures-preview 0.3 (mostly `Future<Item=>` to `Future<Output=Result<>>`).
2. Update dependencies to pre-release versions (`tokio-0.2` and `hyper-0.13`).  There's still other dependencies that are outstanding and blocking the full release.
3. Migrate Handler trait to a pinned box HandlerFuture.

This is a **work-in-progress** with a few blockers before this would be ready:

Gotham Dependencies:

- [ ] Update Futures from `futures-preview` to `futures = 0.3` when the other dependencies (hyper, tokio, etc) update in concert.
- [ ] Update Tokio to `0.2` from alpha pre-releases
- [ ] Update Hyper to `0.13` from alpha pre-releases
- [ ] Update Tower-Service to `0.3` from alpha pre-releases.  Hyper is migrating many of its traits to `tower-service::Service` and so is now a direct dependency.
- [ ] Released version of `futures_rustls` which is currently a branch of `tokio-rustls` ported to Futures-preview
- [ ] Released version of `futures-tokio-compat` or suggested `tokio::compat` library for bridging `futures::AsyncRead` and `tokio::AsyncRead`.  See tokio-rs/tokio#1297
    and async-rs/async-std#54

Middleware Dependencies:

- [ ] Diesel - Requires updated release of `tokio-threadpool`
- [ ] JWT - Requires updated release of `jsonwebtoken`
kevinastone added a commit to kevinastone/gotham that referenced this issue Nov 8, 2019
With the anticipated release of async-await in stable rust this week, I took an effort to migrate Gotham to run on std futures using the pre-release versions of the dependencies (tokio, hyper, etc).

*NOTE*: This doesn't attempt to introduce `await` or `async fn` into the codebase (there was a single unavoidable case due to an `tokio::File::metadata` API change).  That is designed as a future activity.

This migration involved a few key efforts:

1. Convert from Futures 0.1 to Futures-preview 0.3 (mostly `Future<Item=>` to `Future<Output=Result<>>`).
2. Update dependencies to pre-release versions (`tokio-0.2` and `hyper-0.13`).  There's still other dependencies that are outstanding and blocking the full release.
3. Migrate Handler trait to a pinned box HandlerFuture.

This is a **work-in-progress** with a few blockers before this would be ready:

Gotham Dependencies:

- [ ] Update Futures from `futures-preview` to `futures = 0.3` when the other dependencies (hyper, tokio, etc) update in concert.
- [ ] Update Tokio to `0.2` from alpha pre-releases
- [ ] Update Hyper to `0.13` from alpha pre-releases
- [ ] Update Tower-Service to `0.3` from alpha pre-releases.  Hyper is migrating many of its traits to `tower-service::Service` and so is now a direct dependency.
- [ ] Released version of `futures_rustls` which is currently a branch of `tokio-rustls` ported to Futures-preview
- [ ] Released version of `futures-tokio-compat` or suggested `tokio::compat` library for bridging `futures::AsyncRead` and `tokio::AsyncRead`.  See tokio-rs/tokio#1297
    and async-rs/async-std#54

Middleware Dependencies:

- [ ] Diesel - Requires updated release of `tokio-threadpool`
- [ ] JWT - Requires updated release of `jsonwebtoken` since it's dependency `ring` conflicts withs `futures-rustls`.
kevinastone added a commit to kevinastone/gotham that referenced this issue Nov 8, 2019
With the anticipated release of async-await in stable rust this week, I took an effort to migrate Gotham to run on std futures using the pre-release versions of the dependencies (tokio, hyper, etc).

*NOTE*: This doesn't attempt to introduce `await` or `async fn` into the codebase (there was a single unavoidable case due to an `tokio::File::metadata` API change).  That is designed as a future activity.

This migration involved a few key efforts:

1. Convert from Futures 0.1 to Futures-preview 0.3 (mostly `Future<Item=>` to `Future<Output=Result<>>`).
2. Update dependencies to pre-release versions (`tokio-0.2` and `hyper-0.13`).  There's still other dependencies that are outstanding and blocking the full release.
3. Migrate Handler trait to a pinned box HandlerFuture.

This is a **work-in-progress** with a few blockers before this would be ready:

Gotham Dependencies:

- [ ] Update Futures from `futures-preview` to `futures = 0.3` when the other dependencies (hyper, tokio, etc) update in concert.
- [ ] Update Tokio to `0.2` from alpha pre-releases
- [ ] Update Hyper to `0.13` from alpha pre-releases
- [ ] Update Tower-Service to `0.3` from alpha pre-releases.  Hyper is migrating many of its traits to `tower-service::Service` and so is now a direct dependency.
- [ ] Released version of `futures_rustls` which is currently a branch of `tokio-rustls` ported to Futures-preview
- [ ] Released version of `futures-tokio-compat` or suggested `tokio::compat` library for bridging `futures::AsyncRead` and `tokio::AsyncRead`.  See tokio-rs/tokio#1297
    and async-rs/async-std#54

Middleware Dependencies:

- [ ] Diesel - Requires updated release of `tokio-threadpool`
- [ ] JWT - Requires updated release of `jsonwebtoken` since it's dependency `ring` conflicts withs `futures-rustls`.
colinbankier pushed a commit to gotham-rs/gotham that referenced this issue Jan 20, 2020
* Ported examples to Std::Future

The following examples were not updated (and thus commented out in `Cargo.toml`) due to incompatible dependencies:

- [ ] `hello_world_until` is dependent on a compatible version of `tokio-signal`
- [ ] `diesel` is dependent on the Diesel middleware
- [ ] `openssl` is dependent on `tokio-openssl`
- [ ] `websocket` is dependent on `tokio-tungstenite`

* Migrate Gotham to std Futures to support Async/Await

With the anticipated release of async-await in stable rust this week, I took an effort to migrate Gotham to run on std futures using the pre-release versions of the dependencies (tokio, hyper, etc).

*NOTE*: This doesn't attempt to introduce `await` or `async fn` into the codebase (there was a single unavoidable case due to an `tokio::File::metadata` API change).  That is designed as a future activity.

This migration involved a few key efforts:

1. Convert from Futures 0.1 to Futures-preview 0.3 (mostly `Future<Item=>` to `Future<Output=Result<>>`).
2. Update dependencies to pre-release versions (`tokio-0.2` and `hyper-0.13`).  There's still other dependencies that are outstanding and blocking the full release.
3. Migrate Handler trait to a pinned box HandlerFuture.

This is a **work-in-progress** with a few blockers before this would be ready:

Gotham Dependencies:

- [ ] Update Futures from `futures-preview` to `futures = 0.3` when the other dependencies (hyper, tokio, etc) update in concert.
- [ ] Update Tokio to `0.2` from alpha pre-releases
- [ ] Update Hyper to `0.13` from alpha pre-releases
- [ ] Update Tower-Service to `0.3` from alpha pre-releases.  Hyper is migrating many of its traits to `tower-service::Service` and so is now a direct dependency.
- [ ] Released version of `futures_rustls` which is currently a branch of `tokio-rustls` ported to Futures-preview
- [ ] Released version of `futures-tokio-compat` or suggested `tokio::compat` library for bridging `futures::AsyncRead` and `tokio::AsyncRead`.  See tokio-rs/tokio#1297
    and async-rs/async-std#54

Middleware Dependencies:

- [ ] Diesel - Requires updated release of `tokio-threadpool`
- [ ] JWT - Requires updated release of `jsonwebtoken` since it's dependency `ring` conflicts withs `futures-rustls`.

* Updated to crates.io verison of futures-rustls

* Migrated to tokio-0.2 final and hyper-0.13 final

This involved changing the way that the runtime is managed and handling
`block_on` for synchronously running futures.

Hyper-0.13 required changing to the tower_service trait for implementing
a `Connect` trait used for the TLS and plain tcp stream wrappers.

The other major change is that Hyper migrated from a `Chunk` trait to
use `Bytes`.  Bytes-0.5 is now a trait rather than a struct which no
longer implements `Extends<u8>` requiring a new `BytesMut` buffer for
some common concatenation operations.

* Re-enable hello_world_until

Replace tokio-signal with tokio (signal was migrated into tokio itself)

* Remove commented out code

Co-Authored-By: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>

* Async-ified the init_server helpers

* Simplify executing futures in tls/test to match plain/test

* Re-enabled diesel middleware and example

* Addressed review comments.

Co-authored-by: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants