# I need to implement AsyncRead and AsyncWrite but dont know where to get started

**URL:** <https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945>\
**Category:** help\
**Created:** [April 5, 2021, 7:57pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945 "2021-04-05T19:57:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 7:57pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/1 "2021-04-05T19:57:27Z")

</div>

Hi folks.  
I am working on a `UdpStream` api to provide a analogous interface to TcpStream for a udp socket for client session management over udp.  
I want to implement AsyncRead and AsyncWrite for my struct which has its own read and write methods.  
If it was sync code I would simply call self.read and self.write in the `impl Read` and `impl Write` respectively. However I dont have much understanding on the basics of the `Future`s and the docs of tokio about implementing asyncread/write are wip at this stage.

The `poll_read` function takes whole bunch of things and returns a `Poll`.  
So basically I am trying to understand how to go from `async fn self.read -> Result<_,_>` to `Poll`

Thanks

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:16pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/2 "2021-04-05T20:16:10Z")

</div>

You are getting into hard-mode async Rust now, so I can't give a comprehensive answer in a text box, but I can link some resources you might find useful:

1. The last few chapters in the Tokio tutorial, starting from [Async in depth](https://tokio.rs/tokio/tutorial/async)
2. [Pin and suffering](https://fasterthanli.me/articles/pin-and-suffering)
3. The os-phil post on [Async/Await](https://os.phil-opp.com/async-await/)

The last post is pretty long, but it goes in a lot of detail on how async/await fits together.

Depending on what you need, it may be possible to combine [`tokio_util::udp`](https://docs.rs/tokio-util/0.6/tokio_util/udp/index.html) with [`tokio_util::io::StreamReader`](https://docs.rs/tokio-util/0.6/tokio_util/io/struct.StreamReader.html) and sidestep the poll stuff entirely.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:18pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/3 "2021-04-05T20:18:54Z")

</div>

the thing is that I already have a method doing the async read part cant I just call somehow `Future::poll(self.read(),cx)` and get the thing. When I try to do that I get an error saying found opaque type Future expected Pin.

Isnt there any way to use an existing Future without implementing the future itself?  
What I dont understand is that I DO have a future already why is it so difficult to just use the poll method of that

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:22pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/4 "2021-04-05T20:22:27Z")

</div>

If you have a future object you want to poll, you need to store the future as a field in your struct, and repeatedly call `poll` on it every time your wrapper is polled. You might want to check out the source of [`PollSemaphore`](https://github.com/tokio-rs/tokio/blob/master/tokio-util/src/sync/poll_semaphore.rs), which does exactly this.

Note that `ready!(expr)` expands to this:

```rust
match expr {
    Poll::Ready(value) => value,
    Poll::Pending => return Poll::Pending,
}

```

A common mistake is to recreate the future object every time you are polled. This wont work. You must keep the future object around from poll to poll.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:25pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/5 "2021-04-05T20:25:19Z")

</div>

Oh that makes a lot of sense however still How do I get from `impl Future` opaque type to a `Pin`? and Is there a simpler trait which will simply allow me to call self.read().await and handle the future by itself?

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:29pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/6 "2021-04-05T20:29:07Z")

</div>

Most people use the following type to store their futures:

```rust
Pin<Box<dyn Future<Output = ...> + Send>>

```

The futures crate has an alias for this called [`BoxFuture`](https://docs.rs/futures/0.3/futures/future/type.BoxFuture.html). You can turn an `impl Future` into a box of this type by using the `Box::pin` constructor. Once you have a pinned box, you can call [`.as_mut()`](https://doc.rust-lang.org/stable/std/pin/struct.Pin.html#method.as_mut) on it to get a `Pin<&mut TheFuture>`, which you can then call `poll` on.

The example I linked uses [`ReusableBoxFuture`](https://docs.rs/tokio-util/0.6/tokio_util/sync/struct.ReusableBoxFuture.html) instead, but this is just an optimization. It provides the same features as a boxed future.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:33pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/7 "2021-04-05T20:33:19Z")

</div>

but do I have to store my future and poll it myself which will add a lot of complexity to my struct. Isnt there a trait that I can just call my implemented future ? alternatively I think I can create my own trait it will be much simpler I believe.

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:34pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/8 "2021-04-05T20:34:59Z")

</div>

There's no utility that can do this exact thing for you, no. As I said, poll functions are hard-mode async Rust.

You can definitely create your own trait, but it wont work with things that need you to implement the standard IO traits.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:36pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/9 "2021-04-05T20:36:42Z")

</div>

@alice if I were to store my own it would have to be something like

```rust
struct Foo{
currentFut:Arc<Mutex<Option<Pin<Box<dyn Future<Output = ...> + Send>>>>
}

```

right ?

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:37pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/10 "2021-04-05T20:37:58Z")

</div>

I don't think you need the `Arc`/`Mutex` because you shouldn't be sharing the future.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:40pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/11 "2021-04-05T20:40:02Z")

</div>

then wouldnt my entire struct be !Send !Sync ? I feel like I am missing a real good chunk of the entire async await deal and how it fits my needs

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:41pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/12 "2021-04-05T20:41:20Z")

</div>

No, your struct should be `Send`. What makes you think that it wouldn't be?

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:43pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/13 "2021-04-05T20:43:47Z")

</div>

If it's because it has a `dyn Trait`, then that's why I put a `+ Send` in it. Typically you don't need futures to be `Sync`.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:47pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/14 "2021-04-05T20:47:55Z")

</div>

Oh yes it would be Send but not Sync since the Future as a value would be sent to another thread if it was needed. I think I understand what to do now. Lastly what is your opinion about rolling my own AsyncRead/Write traits using async\_trait to make things much simpler?  
Would you advice against it ?

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:50pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/15 "2021-04-05T20:50:37Z")

</div>

If you are in a situation where you don't actually need to implement the general IO traits because you are only using the object in ways where that is unnecessary, then that is usually the _better_ solution.

Though I will say that when you don't need to implement the general IO traits, you can usually have the methods be completely ordinary methods instead of trait methods. It is always simpler to avoid `async_trait` if you don't need it.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 8:54pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/16 "2021-04-05T20:54:37Z")

</div>

```rust
use async_trait::async_trait;
use tokio::io::{AsyncRead, AsyncWrite};
#[async_trait]
pub trait WorkerProvider: Send + Sync {
    type Worker: Worker;
    async fn get(&self) -> Option<Self::Worker> {
        None
    }
}
#[async_trait]
pub trait Worker: Send + Sync {
    async fn handle<RW>(&self, rw: RW)
    where
        RW: AsyncRead + AsyncWrite + Send + Sync + 'static + Unpin;
}

```

This is what my code looks like this is for the refactor of a series of projects using different transports to unify the transport layer and just to split the worker and store logic which doesnt care about the underlaying transport as long as they implement AsyncRead and AsyncWrite

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 8:57pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/17 "2021-04-05T20:57:50Z")

</div>

Fair enough. The main disadvantage of rolling your own IO traits here is that `async_trait` is inherently a lot more expensive than traits based on poll methods, as you incur an allocation cost every time you call a method on the trait.

Besides that, there's no problem if it can do the things it need to do using your own traits.

One of the reasons I recommended using ordinary methods over `async_trait` above is that this would not be subject to these extra costs.

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 9:01pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/18 "2021-04-05T21:01:52Z")

</div>

I think that is for now a little too advanced for me It will require me to implement Future by myself for every type right ?

---

<div class="post-metadata">

**Author:** ![alice](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/alice/32/9777_2.png) [@alice](https://users.rust-lang.org/u/alice)\
**Post date:** [April 5, 2021, 9:02pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/19 "2021-04-05T21:02:53Z")

</div>

Which thing would require that?

---

<div class="post-metadata">

**Author:** ![NikosEfthias](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/nikosefthias/32/9251_2.png) [@NikosEfthias](https://users.rust-lang.org/u/NikosEfthias)\
**Post date:** [April 5, 2021, 9:04pm UTC](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945/20 "2021-04-05T21:04:13Z")

</div>

using poll methods instead of async\_trait

[Next page](https://users.rust-lang.org/t/i-need-to-implement-asyncread-and-asyncwrite-but-dont-know-where-to-get-started/57945.md?page=2)
