tomaka / rouille

Web framework in Rust
Apache License 2.0
1.12k stars 106 forks source link

Rust 1.26.0 causes ~200% CPU use #183

Open CamJN opened 6 years ago

CamJN commented 6 years ago

Not sure what's wrong but this is a pretty bad regression.

LPGhatguy commented 6 years ago

I'm not seeing the same issue -- what platform are you on, and do you have a small reproduction case that other people can try?

CamJN commented 6 years ago

This is more of less what I'm running, my code uses a few include_str! macros for the response contents, and the auth compares against an actual password, but the problem happens if I just return true like this too:

#[macro_use]
extern crate rouille;

use rouille::Response;
use rouille::input::{HttpAuthCredentials, basic_http_auth};

fn main() {
    let handler = move |request: &rouille::Request| {
        match basic_http_auth(request) {
            None => Response::basic_http_auth_login_required("realm"),
            Some(auth) => {
                if authenticate(auth) {
                    router!(request,
                            (GET) ["/"] => {
                                Response::html("<html></html>")
                            },
                            (GET) ["/api"] => {
                                let (response, websocket) = try_or_400!(websocket::start::<String>(&request, None));
                                // Because of the nature of I/O in Rust, we need to spawn a separate thread for each websocket.
                                spawn(move || {
                                    // This line will block until the `response` above has been returned.
                                    let ws = websocket.recv().unwrap();
                                    // We use a separate function for better readability.
                                    websocket_handling_thread(ws);
                                });
                                response
                            },
                            _ => {
                                Response::empty_404()
                            }
                    )
                } else {
                    Response::text("Bad login/password").with_status_code(403)
                }
            }
        }
    };

    rouille::Server::new("0.0.0.0:5000", handler).unwrap().run();
}

fn authenticate(_auth: HttpAuthCredentials) -> bool {
    return true;
}

fn websocket_handling_thread(mut websocket: websocket::Websocket) {
    // We wait for a new message to come from the websocket.
    while let Some(message) = websocket.next() {

        match message {
            websocket::Message::Text(txt) => {
                // If the message is text, send it back with `send_text`.
                println!("received {:?} from a websocket", txt);
                websocket.send_text(&txt).unwrap();
            }
            websocket::Message::Binary(data) => {
                println!("received binary from a websocket {:?}", data);
            }
        }
    }
}
CamJN commented 6 years ago

And I'm on macOS 10.13.4.