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

More realistic demos in tokio-core #15

Closed
jrozner opened this issue Sep 11, 2017 · 9 comments
Closed

More realistic demos in tokio-core #15

jrozner opened this issue Sep 11, 2017 · 9 comments

Comments

@jrozner
Copy link

jrozner commented Sep 11, 2017

As someone new to tokio learning has been fairly difficult as I'm sure a lot of people are aware. Something specifically that has been difficult for me was trying to move from the examples in tokio-core to writing real software partly because the examples are so different from how real software would be written.

For instance, the udp-codec example shows how to use the UdpCodec trait to build a server that can send and receive messages that are managed by a defined codec. Unfortunately the way this example is written is unlike how any real software would be written and avoids dealing with some of the issues I ran into while trying to figure out the correct pattern to use for building something that uses this. Specifically it's unlikely you'll ever have both sockets on the same machine sending data back and forth. One of the first strategies I tried was using for_each on the stream and in the block passed attempting to write to the sink the recipient, message pair. This failed due to an issue closure taking ownership of the sink binding.

Ultimately the first solution I ended up getting working was switching to map and having the stream return a new stream of responses. This personally seemed like a non-ergonomic solution and not how I would think about writing the code coming from other using async languages/platforms where a callback with non-blocking I/O would be scheduled inside the event loop.

The next solution was writing to a channel inside the loop and having another task that is reading from the channel and sending the message pairs from it. This was more like the solution in the example but having a more realistic solution would have definitely helped getting something working significantly faster.

@alexcrichton
Copy link
Contributor

Thanks for the report, and it's definitely our desire to have realistic examples! If you've got some suggestions for what you'd like to see, please just let me know!

@jrozner
Copy link
Author

jrozner commented Sep 11, 2017

Thanks for being so responsive. For what it's worth I don't know how valuable this is for anyone else but this is reflective of my experience going through the tokio.rs and tokio-core examples.

Something that might be immediately helpful is providing more of a readme for the examples in tokio-core that explains some of the high level concepts that the example(s) show. I definitely missed out on some really useful examples in them by skipping over ones that didn't seem relevant to what I was working on.

To me personally moving through the documentation on tokio.rs and then to the examples was sort of a stretch. A lot of the steps on tokio.rs felt very siloed and it didn't feel like there was really a clear progression through them. Maybe keeping the same sections but using each one to build on the previous to build a single complete example rather than sort of disjointed separate examples would be helpful. To me it wasn't really clear how a lot of the parts fit together until I was able to find more complete code and get people to answer questions I had.

With respect to the udp-codec example I think something that would be more useful is to modify it so that you can run multiple instances (one for the ping and one for the pong) that communicate with each other. The way that the streams and sinks work in it was personally very confusing trying to understand the back and forth. Now that I understand how it works it's a lot more clear but it just seemed sort of awkward if that makes any sense.

Something I've noticed in the examples with the worker paradigm with each worker getting a channel and the event loop round robin distributes requests to them. This is super awesome but some discussion of it on tokio.rs would be cool to understand a bit more about where it makes sense to use it and where it doesn't.

Something I'm also not really clear about from the examples on tokio.rs and in tokio-core utilizing multiple cores/threads to handle processing from the non-blocking I/O efficiently without blocking new connections. CpuPools are introduced on tokio.rs for cpu intensive tasks but they're ignored in the examples with workers. Some high level discussion and some examples around that would be awesome to just understand what the best practices are around that and how the different abstractions around I/O and computation fit together.

@alexcrichton
Copy link
Contributor

For what it's worth I don't know how valuable this is for anyone else but this is reflective of my experience going through the tokio.rs and tokio-core examples.

Nah this is great, thanks for writing this out! The documentation on tokio.rs can definitely use a lot of improvements, and this sort of feedback is invaluable :)

Something that might be immediately helpful is providing more of a readme for the examples in tokio-core that explains some of the high level concepts that the example(s) show

A great idea!

With respect to the udp-codec example I think something that would be more useful is to modify it so that you can run multiple instances

Sonds like a great idea to me, mind opening an issue on the tokio-core repository?

Something I've noticed in the examples with the worker paradigm with each worker getting a channel and the event loop round robin distributes requests to them

Heh these were added in probably the last 48 hours, so tokio.rs hasn't quite caught up just yet :). In general we've got a lot of planned improvements for the tokio.rs documentation we hope to get done during the impl period for Rust!

Something I'm also not really clear about from the examples on tokio.rs and in tokio-core utilizing multiple cores/threads to handle processing from the non-blocking I/O efficiently without blocking new connections

Definitely, I'll see if I can add an example of CPU intensive work.

@alexcrichton
Copy link
Contributor

I've just added an example of CPU intensive work, let me know what you think!

@jrozner
Copy link
Author

jrozner commented Sep 12, 2017

I'll get an issue filed for tokio-core and would be happy to give writing the change a shot and submit a pull request.

Thanks for adding the example for mixing the CpuCore and the Reactor, that's super helpful. The one thing I guess I'm still not 100% clear on is what sort of situations make sense to spawn a worker per thread and shove off the processing to one vs. putting the processing work into a CpuPool and returning a future? Is the CpuPool going to do a better job of scheduling the work across threads than a round robin approach or are they solving different problems?

@alexcrichton
Copy link
Contributor

would be happy to give writing the change a shot and submit a pull request.

That'd be awesome!

The one thing I guess I'm still not 100% clear on is what sort of situations make sense to spawn a worker per thread and shove off the processing to one vs. putting the processing work into a CpuPool and returning a future? Is the CpuPool going to do a better job of scheduling the work across threads than a round robin approach or are they solving different problems?

In general this depends on your workload as to which you should choose. If everything you do is I/O bound but you still need higher throughput after just using one core you can use multiple I/O threads, but this ends up being a very rare paradigm to use in practice.

Much more common is to use worker threads, where you keep all your work off the main I/O loop to prevent it from blocking.

@carllerche
Copy link
Member

carllerche commented Dec 14, 2017

Relates to #13

@kpp
Copy link
Contributor

kpp commented Feb 6, 2018

@carllerche
Copy link
Member

Indeed!

There is now an accompanying guide to the chat example: https://tokio.rs/docs/getting-started/chat/

I'm going to close this issue as the general "more realistic demos" issue has been handled. However, there is definitely still a need for more examples that cover real world cases. So, I would say that new issues should be created with specific example proposals.

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

5 participants