Skip to content

Commit

Permalink
Rust: hyper on tokio-proto/service
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nayato committed Mar 25, 2017
1 parent 6df2046 commit 5ba6a30
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 49 deletions.
14 changes: 8 additions & 6 deletions frameworks/Rust/hyper/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
[package]
name = "hello"
version = "0.2.0"
version = "0.3.0"
authors = ["Steve Klabnik <steve@steveklabnik.com>", "Alexander Polyakov <plhk@sdf.org>"]

[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 = "*"
serde_json = "*"
serde_derive = "*"
mime = "*"

[dependencies.hyper]
git = "https://github.com/hyperium/hyper/"
rev = "39a53fcd3364634125dafcf4d7a1d191241a7ff0"
rev = "43cf9aefe8f9147a0f08aa0f9d609d275549fd7c"
1 change: 1 addition & 0 deletions frameworks/Rust/hyper/benchmark_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"tests": [{
"default": {
"setup_file": "setup",
"json_url": "/json",
"plaintext_url": "/plaintext",
"port": 8080,
"approach": "Realistic",
Expand Down
2 changes: 1 addition & 1 deletion frameworks/Rust/hyper/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ fw_depends postgresql rust

cargo clean
cargo build --release
cargo run --release &
./target/release/hello &
81 changes: 39 additions & 42 deletions frameworks/Rust/hyper/src/main.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -27,44 +33,35 @@ impl Service for TechEmpower {
type Future = ::futures::Finished<Response, hyper::Error>;

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))
}

0 comments on commit 5ba6a30

Please sign in to comment.