From a5246e3942b937dccff8a3b3d79876ddd727506d Mon Sep 17 00:00:00 2001 From: mgortman Date: Fri, 24 Mar 2017 18:43:47 -0700 Subject: [PATCH] Rust: hyper on tokio-proto/service Refresh for hyper benchmark based on tokio-proto and tokio-service. serde-derive is used for json serialization as that's what people will do in real app. --- frameworks/Rust/hyper/Cargo.toml | 14 ++-- frameworks/Rust/hyper/benchmark_config.json | 1 + frameworks/Rust/hyper/setup.sh | 2 +- frameworks/Rust/hyper/src/main.rs | 82 ++++++++++----------- toolset/setup/linux/languages/rust.sh | 2 +- 5 files changed, 50 insertions(+), 51 deletions(-) diff --git a/frameworks/Rust/hyper/Cargo.toml b/frameworks/Rust/hyper/Cargo.toml index ea4152c8a2e..d450a4b549c 100644 --- a/frameworks/Rust/hyper/Cargo.toml +++ b/frameworks/Rust/hyper/Cargo.toml @@ -1,16 +1,18 @@ [package] name = "hello" -version = "0.2.0" +version = "0.3.0" authors = ["Steve Klabnik ", "Alexander Polyakov "] [dependencies] -net2 = "0.2" futures = "0.1" -pretty_env_logger = "0.1" -log = "0.3.6" -tokio-core = "0.1" +tokio-proto = "0.1" +tokio-service = "0.1" num_cpus = "1.2" +serde = "0.9" +serde_json = "0.9" +serde_derive = "0.9" +mime = "0.2" [dependencies.hyper] git = "https://github.com/hyperium/hyper/" -rev = "39a53fcd3364634125dafcf4d7a1d191241a7ff0" +rev = "43cf9aefe8f9147a0f08aa0f9d609d275549fd7c" diff --git a/frameworks/Rust/hyper/benchmark_config.json b/frameworks/Rust/hyper/benchmark_config.json index 43a1a0d9aa7..904c41569d4 100644 --- a/frameworks/Rust/hyper/benchmark_config.json +++ b/frameworks/Rust/hyper/benchmark_config.json @@ -3,6 +3,7 @@ "tests": [{ "default": { "setup_file": "setup", + "json_url": "/json", "plaintext_url": "/plaintext", "port": 8080, "approach": "Realistic", diff --git a/frameworks/Rust/hyper/setup.sh b/frameworks/Rust/hyper/setup.sh index 6fe5b047a1f..fad7aad5a71 100644 --- a/frameworks/Rust/hyper/setup.sh +++ b/frameworks/Rust/hyper/setup.sh @@ -4,4 +4,4 @@ fw_depends postgresql rust cargo clean cargo build --release -cargo run --release & +./target/release/hello & diff --git a/frameworks/Rust/hyper/src/main.rs b/frameworks/Rust/hyper/src/main.rs index f1cf4f8e29c..9b3360d325f 100644 --- a/frameworks/Rust/hyper/src/main.rs +++ b/frameworks/Rust/hyper/src/main.rs @@ -1,23 +1,29 @@ extern crate futures; +extern crate tokio_proto; +extern crate tokio_service; extern crate hyper; -extern crate pretty_env_logger; #[macro_use] -extern crate log; -extern crate net2; -extern crate tokio_core; +extern crate serde_derive; +extern crate serde_json; extern crate num_cpus; +#[macro_use] +extern crate mime; -use hyper::{Get, StatusCode}; -use hyper::header::{ContentLength, ContentType}; -use hyper::server::{Server, Service, Request, Response}; - -use net2::TcpBuilder; -use net2::unix::UnixTcpBuilderExt; -use tokio_core::net::TcpListener; +use tokio_proto::TcpServer; +use futures::future; +use hyper::Method::Get; +use hyper::header::{ContentLength, ContentType, Server}; +use hyper::status::StatusCode::NotFound; +use hyper::server::{Http, Service, Request, Response}; +use std::net::SocketAddr; static HELLOWORLD: &'static [u8] = b"Hello, world!"; -#[derive(Clone, Copy)] +#[derive(Serialize)] +struct JsonResponse<'a> { + message: &'a str, +} + struct TechEmpower; impl Service for TechEmpower { @@ -27,44 +33,34 @@ impl Service for TechEmpower { type Future = ::futures::Finished; fn call(&self, req: Request) -> Self::Future { - ::futures::finished(match (req.method(), req.path()) { + let response = match (req.method(), req.path()) { (&Get, "/plaintext") => { - use hyper::mime::{Mime,TopLevel,SubLevel,Attr,Value}; Response::new() .with_header(ContentLength(HELLOWORLD.len() as u64)) - .with_header(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![(Attr::Charset, Value::Utf8)]))) + .with_header(ContentType(mime!(Text / Plain))) .with_body(HELLOWORLD) - }, - _ => { + } + (&Get, "/json") => { + let rep = JsonResponse { message: "Hello, world!" }; + let rep_body = serde_json::to_vec(&rep).unwrap(); Response::new() - .with_status(StatusCode::NotFound) + .with_header(ContentLength(rep_body.len() as u64)) + .with_header(ContentType(mime!(Application / Json))) + .with_body(rep_body) } - }) + _ => Response::new().with_status(NotFound), + }; + future::ok(response.with_header(Server("Hyper".to_string()))) } } - fn main() { - use std::net::SocketAddr; - pretty_env_logger::init().unwrap(); - let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap(); - let mut threads = vec![]; - for i in 0..num_cpus::get_physical() { - use std::thread; - let i = i; - let handle = thread::spawn(move|| { - let (listening, server) = Server::standalone(|tokio| { - let listener = TcpBuilder::new_v4()?.reuse_port(true)?.bind(addr)?.listen(10000)?; - let addr = try!(listener.local_addr()); - let listener = try!(TcpListener::from_listener(listener, &addr, tokio)); - Server::new(listener.incoming(), addr).handle(|| Ok(TechEmpower), tokio) - }).unwrap(); - println!("Listening {} on http://{}", i, listening); - server.run(); - }); - threads.push(handle); - } - for t in threads { - t.join().unwrap(); - } -} + let addr: SocketAddr = "0.0.0.0:8080".parse().unwrap(); + let mut srv = TcpServer::new(Http::new(), addr); + println!("Listening on http://{} using {} threads", + addr, + num_cpus::get()); + + srv.threads(num_cpus::get()); + srv.serve(move || Ok(TechEmpower)) +} \ No newline at end of file diff --git a/toolset/setup/linux/languages/rust.sh b/toolset/setup/linux/languages/rust.sh index 600a09c13ff..51d638933cf 100644 --- a/toolset/setup/linux/languages/rust.sh +++ b/toolset/setup/linux/languages/rust.sh @@ -1,6 +1,6 @@ #!/bin/bash -RUST_VERSION="1.13.0" +RUST_VERSION="1.16.0" fw_installed rust && return 0