Browse Source

hyper: upgrade to new tokio runtime (#3449)

Sean McArthur 7 years ago
parent
commit
e31c0d208b

+ 14 - 7
frameworks/Rust/hyper/Cargo.toml

@@ -1,15 +1,22 @@
 [package]
-name = "hello"
-version = "0.3.0"
-authors = ["Steve Klabnik <[email protected]>", "Alexander Polyakov <[email protected]>"]
+name = "hyper-techempower"
+version = "0.4.0"
+authors = [
+    "Steve Klabnik <[email protected]>",
+    "Alexander Polyakov <[email protected]>",
+    "Sean McArthur <[email protected]>"
+]
 
 [dependencies]
 futures = "0.1"
-hyper = "0.11.6"
-tokio-proto = "0.1"
-tokio-service = "0.1"
+hyper = { version = "0.11.24", default-features = false }
 num_cpus = "1.2"
 serde = "1.0"
 serde_json = "1.0"
 serde_derive = "1.0"
-mime = "0.3"
+tokio = "0.1"
+
+[profile.release]
+opt-level = 3
+codegen-units = 1
+lto = true

+ 18 - 3
frameworks/Rust/hyper/benchmark_config.json

@@ -3,7 +3,6 @@
   "tests": [{
     "default": {
       "json_url": "/json",
-      "plaintext_url": "/plaintext", 
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
@@ -12,10 +11,26 @@
       "language": "Rust",
       "orm": "Raw",
       "platform": "Rust",
-      "webserver": "Hyper",
+      "webserver": "hyper",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "Hyper",
+      "display_name": "hyper",
+      "notes": ""
+    },
+    "pipeline": {
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "Postgres",
+      "framework": "hyper",
+      "language": "Rust",
+      "orm": "Raw",
+      "platform": "Rust",
+      "webserver": "hyper",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "hyper-pipeline",
       "notes": ""
     }
   }]

+ 6 - 0
frameworks/Rust/hyper/hyper-base.dockerfile

@@ -0,0 +1,6 @@
+FROM tfb/rust:latest
+
+COPY ./ ./
+
+RUN cargo clean
+RUN RUSTFLAGS="-C target-cpu=native" cargo build --release

+ 3 - 0
frameworks/Rust/hyper/hyper-pipeline.dockerfile

@@ -0,0 +1,3 @@
+FROM tfb/hyper-base:latest
+
+CMD ["./target/release/hyper-techempower", "pipeline"]

+ 2 - 7
frameworks/Rust/hyper/hyper.dockerfile

@@ -1,8 +1,3 @@
-FROM tfb/rust:latest
+FROM tfb/hyper-base:latest
 
-COPY ./ ./
-
-RUN cargo clean
-RUN RUSTFLAGS="-C target-cpu=native" cargo build --release
-
-CMD ./target/release/hello
+CMD ["./target/release/hyper-techempower"]

+ 59 - 19
frameworks/Rust/hyper/src/main.rs

@@ -1,20 +1,23 @@
 extern crate futures;
-extern crate tokio_proto;
-extern crate tokio_service;
 extern crate hyper;
+extern crate num_cpus;
 #[macro_use]
 extern crate serde_derive;
 extern crate serde_json;
-extern crate num_cpus;
-extern crate mime;
+extern crate tokio;
+
+use std::env;
+use std::net::SocketAddr;
+use std::process;
+
+use futures::{future, Future, Stream};
 
-use tokio_proto::TcpServer;
-use futures::future;
 use hyper::Method::Get;
 use hyper::header::{ContentLength, ContentType, Server};
 use hyper::StatusCode::NotFound;
 use hyper::server::{Http, Service, Request, Response};
-use std::net::SocketAddr;
+
+use tokio::net::TcpListener;
 
 static HELLOWORLD: &'static [u8] = b"Hello, world!";
 
@@ -36,7 +39,7 @@ impl Service for TechEmpower {
             (&Get, "/plaintext") => {
                 Response::new()
                     .with_header(ContentLength(HELLOWORLD.len() as u64))
-                    .with_header(ContentType(mime::TEXT_PLAIN))
+                    .with_header(ContentType::text())
                     .with_body(HELLOWORLD)
             }
             (&Get, "/json") => {
@@ -44,7 +47,7 @@ impl Service for TechEmpower {
                 let rep_body = serde_json::to_vec(&rep).unwrap();
                 Response::new()
                     .with_header(ContentLength(rep_body.len() as u64))
-                    .with_header(ContentType(mime::APPLICATION_JSON))
+                    .with_header(ContentType::json())
                     .with_body(rep_body)
             }
             _ => Response::new().with_status(NotFound),
@@ -53,15 +56,52 @@ impl Service for TechEmpower {
     }
 }
 
+fn configure() -> Http {
+    let pipeline = {
+        let mut args = env::args();
+        args.next().expect("first arg is this binary");
+
+        args.next()
+            .map(|arg| {
+                if arg == "pipeline" {
+                    true
+                } else {
+                    eprintln!("unknown second argument: {:?}", arg);
+                    process::exit(1);
+                }
+            })
+            .unwrap_or(false)
+    };
+
+    // Set our hyper options
+    // (pipeline is desired for the plaintext route)
+    let mut http = Http::<hyper::Chunk>::new();
+    http.pipeline(pipeline);
+    http
+}
+
 fn main() {
-    let addr: SocketAddr = "0.0.0.0:8080".parse().unwrap();
-    let mut http = Http::new();
-    http.pipeline(true);
-    let mut srv = TcpServer::new(http, addr);
-    println!("Listening on http://{} using {} threads",
-             addr,
-             num_cpus::get());
-
-    srv.threads(num_cpus::get());
-    srv.serve(move || Ok(TechEmpower))
+    // Check for some runtime configuration
+    let http = configure();
+
+    // Bind to 0.0.0.0:8080
+    let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
+    let tcp = TcpListener::bind(&addr)
+        .expect("couldn't bind to addr");
+
+    // For every accepted connection, spawn an HTTP task
+    let server = tcp.incoming()
+        .for_each(move |sock| {
+            let _ = sock.set_nodelay(true);
+            let conn = http.serve_connection(sock, TechEmpower)
+                .map_err(|e| eprintln!("connection error: {}", e));
+
+            tokio::spawn(conn);
+
+            Ok(())
+        })
+        .map_err(|e| eprintln!("accept error: {}", e));
+
+    println!("Listening on http://{}", addr);
+    tokio::run(server);
 }