withoutboats / romio

asynchronous networking primitives

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Echo server does not respond to multiple clients simultaneously

bIgBV opened this issue · comments

I was trying out romio and started by using the echo server example from juliex. I expected that connecting more than one client would result in both of them getting responses to the messages being sent to them, but instead only one of the clients was getting a response back while the other did not. Once the first client was disconnected, the messages started coming back one line after the other.

I have a screen capture of the same and you can reproduce the issue by cloning the project repository, going into the rustlb directory and running the server using cargo run --bin origin and then connecting to it using nc localhost 7878 from two different terminals.

You should only receive messages echod back on the first client to connect while the second will accept input, but get responses one line after the other only after the first client has disconnected.

I tested this further, by connecting a third client and looks like there is a sequence in which the messages are processed. The second client to connect receives messages back once the first client has disconnected and the third client receives messages back after the second one has.

commented

I'm not sure what's happening, but just tested https://github.com/withoutboats/juliex/blob/master/examples/echo.rs for good measure, and multiple clients connect without a problem.

So I think that can rule out both juliex and romio directly. It's more likely there's a bug in the use of the code.

In your code this seems like an odd line to me: https://github.com/chicagohaskell/async-futures-talk/blob/master/rustlb/src/main.rs#L50 -- it waits to read exactly 100 bytes before proceeding. Is that intentional? Might that explain something perhaps?

I apologize, I should've linked directly to the source file. I'm not running this behind the naive load balancer. Instead I'm running the example directly, that is origin.rs. When I run this and try to connect multiple clients I come across this issue.

commented

@bIgBV ah yes, so this responds to requests one by one. There's only one thread, and as long as it's responding to one request, it can't move onto the next one. This is why Juliex exists.

@bIgBV that makes perfect sense, my bad. I wasn't spawning the tasks on a threadpool.

I just wanted to add: its possible to be concurrent here without using a threadpool (that is, using still a single thread), but it would require you to construct something using library-defined concurrency primitives (such as select, join, futures_unordered), not just async and await. An unusual thing about Rust's async/await feature is that in themselves they do not introduce any concurrency at all - if all you do is block_on an async block with awaits inside of it, it will be entirely sequential.