Переглянути джерело

Update Rocket for more performance (#5174)

* Update Rocket for more performance

Increased the max number of database connections. Increased the
number of workers because rocket is synchronous and may have
many blocked threads. Changed the templating engine to the yarte.
Update the versions of dependencies. Add extra compile time
parameters.

* Use specific cargo version
Brendan Hansknecht 5 роки тому
батько
коміт
68fdd1a8ee

+ 15 - 8
frameworks/Rust/rocket/Cargo.toml

@@ -1,18 +1,25 @@
 [package]
 name = "rocket"
 version = "0.1.0"
-authors = ["Marcelo Barbosa <[email protected]>"]
+authors = ["Marcelo Barbosa <[email protected]>", "Brendan Hansknecht <[email protected]>"]
 edition = "2018"
 
 [dependencies]
-diesel = { version = "1.3.2", features = ["postgres", "r2d2"] }
-rand = "0.5.5"
-rocket = "0.4.0"
-serde = "1.0.71"
-serde_json = "1.0.24"
-serde_derive = "1.0.71"
+diesel = { version = "1.4.3", features = ["postgres", "r2d2"] }
+num_cpus = "1.10.1"
+rand = "0.7.2"
+rocket = "0.4.2"
+serde = "1.0.101"
+serde_json = "1.0.41"
+serde_derive = "1.0.101"
+yarte = "0.3.5"
 
 [dependencies.rocket_contrib]
 version = "*"
 default-features = false
-features = ["json", "handlebars_templates"]
+features = ["json"]
+
+[profile.release]
+lto = true
+opt-level = 3
+codegen-units = 1

+ 0 - 7
frameworks/Rust/rocket/Rocket.toml

@@ -1,7 +0,0 @@
-[global]
-template_dir = "src/templates/"
-
-[production]
-port = 8000
-log = "critical"
-secret_key = "dY+Rj2ybjGxKetLawKGSWi6EzESKejvENbQ3stffZg0="

+ 31 - 5
frameworks/Rust/rocket/rocket.dockerfile

@@ -1,13 +1,39 @@
-FROM rustlang/rust:nightly
+FROM debian:buster-20191014-slim
+ENV RUSTUP_HOME=/usr/local/rustup \
+    CARGO_HOME=/usr/local/cargo \
+    PATH=/usr/local/cargo/bin:$PATH
 
-ADD ./ /rocket
+RUN set -eux; \
+    apt-get update; \
+    apt-get install -y --no-install-recommends \
+        ca-certificates \
+        gcc \
+        libc6-dev \
+        wget \
+        ; \
+    \
+    url="https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init"; \
+    wget "$url"; \
+    chmod +x rustup-init; \
+    ./rustup-init -y --no-modify-path --default-toolchain nightly-2019-10-14; \
+    rm rustup-init; \
+    chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
+    rustup --version; \
+    cargo --version; \
+    rustc --version; \
+    \
+    apt-get remove -y --auto-remove \
+        wget \
+        ; \
+    rm -rf /var/lib/apt/lists/*;
+
+RUN apt-get update && apt-get install -yqq clang-7 libpq-dev
 
+ADD ./ /rocket
 WORKDIR /rocket
 
-ENV ROCKET_ENV=production
 ENV DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world
-
 RUN cargo clean
 RUN RUSTFLAGS="-C target-cpu=native" cargo build --release
 
-CMD ./target/release/rocket
+CMD ./target/release/rocket

+ 1 - 1
frameworks/Rust/rocket/src/db.rs

@@ -31,5 +31,5 @@ impl Deref for DbConn {
 
 pub fn init_pool() -> PgPool {
     let manager = ConnectionManager::<PgConnection>::new(env!("DATABASE_URL"));
-    Pool::new(manager).expect("db pool")
+    Pool::builder().max_size((num_cpus::get()*16) as u32).build(manager).expect("db pool")
 }

+ 22 - 8
frameworks/Rust/rocket/src/main.rs

@@ -13,7 +13,9 @@ use diesel::prelude::*;
 use diesel::result::Error;
 use rand::Rng;
 use rocket_contrib::json::Json;
-use rocket_contrib::templates::Template;
+use rocket::config::{Config, LoggingLevel, Environment};
+use rocket::response::content;
+use yarte::Template;
 
 mod db;
 mod models;
@@ -78,22 +80,28 @@ fn queries(conn: db::DbConn, q: u16) -> Json<Vec<models::World>> {
     Json(results)
 }
 
+#[derive(Template)]
+#[template(path = "fortunes.html.hbs")]
+pub struct FortunesTemplate<'a> {
+    pub fortunes: &'a Vec<models::Fortune>
+}
+
 #[get("/fortunes")]
-fn fortunes(conn: db::DbConn) -> Template {
+fn fortunes(conn: db::DbConn) -> content::Html<String> {
     use schema::fortune::dsl::*;
 
-    let mut context = fortune
+    let mut fortunes = fortune
         .load::<models::Fortune>(&*conn)
         .expect("error loading fortunes");
 
-    context.push(models::Fortune {
+    fortunes.push(models::Fortune {
         id: 0,
         message: "Additional fortune added at request time.".to_string(),
     });
 
-    context.sort_by(|a, b| a.message.cmp(&b.message));
+    fortunes.sort_by(|a, b| a.message.cmp(&b.message));
 
-    Template::render("fortunes", &context)
+    content::Html(FortunesTemplate{fortunes: &fortunes}.call().expect("error rendering template"))
 }
 
 #[get("/updates")]
@@ -138,7 +146,14 @@ fn updates(conn: db::DbConn, q: u16) -> Json<Vec<models::World>> {
 }
 
 fn main() {
-    rocket::ignite()
+    let mut config = Config::build(Environment::Production)
+        .address("0.0.0.0")
+        .port(8000)
+        .log_level(LoggingLevel::Off)
+        .workers((num_cpus::get()*16) as u16)
+        .expect("failed to generate config");
+    config.set_secret_key("dY+Rj2ybjGxKetLawKGSWi6EzESKejvENbQ3stffZg0=").expect("failed to set secret");
+    rocket::custom(config)
         .mount(
             "/",
             routes![
@@ -153,6 +168,5 @@ fn main() {
             ],
         )
         .manage(db::init_pool())
-        .attach(Template::fairing())
         .launch();
 }

+ 0 - 10
frameworks/Rust/rocket/src/templates/fortunes.html.hbs

@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head><title>Fortunes</title></head>
-<body>
-<table>
-<tr><th>id</th><th>message</th></tr>
-{{#each .}}<tr><td>{{id}}</td><td>{{message}}</td></tr>{{/each}}
-</table>
-</body>
-</html>

+ 5 - 0
frameworks/Rust/rocket/templates/fortunes.html.hbs

@@ -0,0 +1,5 @@
+<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>
+      {{~# each fortunes ~}}
+      <tr><td>{{id}}</td><td>{{message}}</td></tr>
+      {{~/each ~}}
+</table></body></html>