tokio-rs / tokio-core

I/O primitives and event loop for async I/O in Rust
Apache License 2.0
634 stars 116 forks source link

UdpFramed doesn't return incoming frames #305

Open valarauca opened 6 years ago

valarauca commented 6 years ago

So I've implemented a simple server here. You can build this with cargo build and running it takes a --socket argument for the address it should listen on.

The goal was to test a udp based syslog application. All this really does is check the UTF8 datagrams to valid strings, and print them.


The problem is I see 1 datagram, then it just consumes 100% cpu infinitely spinning on a single core. I can see in wireshark that my remote services are still sending packets, but the only data I'm seeing is Async::NotReady.

netstat -vaun shows myself listening on the expected port and that it is open.

There isn't every anything to encode, I'm just looking for a stream of incoming datagrams.


version info:

rustc 1.26.0-nightly (29f5c699b 2018-02-27)
rustc 1.24.0 (stable)

display idenatical behavior. I'm on Ubuntu 16.04.04 (kernel 4.4.0-116-generic)


Update sometimes I just see no frames, have a port open, and packets hitting the port, and I'm still spinning at 100% cpu with no data.

kpp commented 6 years ago

The problem is I see 1 datagram, then it just consumes 100% cpu infinitely spinning on a single core.

It is ok since you wrote an infinite loop in your code:

        loop {
            match self.data.poll() {
                ...
                Ok(Async::NotReady) => {
                    continue;
                },
                ...
            };
        }
kpp commented 6 years ago

I would recommend you to read udp-codec example.

valarauca commented 6 years ago

@kpp If you read the entire linked issue this always returned Result::Ok(Async::NotReady). I'm streaming about ~100KiB/s of data into the UDP socket (about 500bytes per datagram) and it never is ready. I'll only ever see 1 datagram. I'm only interesting in receiving streaming grams. Returning the Ok(Async::NotReady) just results in the program doing nothing forever.

If switched to a for loop over std::net::UdpSocket and call recv_from() in a for loop i'll actually see each datagram.

The infinite loop doesn't prevent the underlying UdpSocket from being re-added to epoll, or mio right?

Furthermore that protocol (or at least the implementation) that I'm working with requires no responses so I'm not sure how the example is strictly applicable. But thank you for it.

carllerche commented 6 years ago

@valarauca What version of tokio-core? There was a release earlier today w/ a bug fix that might be related.