diff --git a/frameworks/Rust/rocket/Cargo.toml b/frameworks/Rust/rocket/Cargo.toml index 748a0e8cbd4..fbf5018a104 100644 --- a/frameworks/Rust/rocket/Cargo.toml +++ b/frameworks/Rust/rocket/Cargo.toml @@ -13,6 +13,7 @@ serde = "1.0.101" serde_json = "1.0.41" serde_derive = "1.0.101" yarte = "0.3.5" +lazy_static = "1.4.0" [dependencies.rocket_contrib] version = "*" diff --git a/frameworks/Rust/rocket/rocket.dockerfile b/frameworks/Rust/rocket/rocket.dockerfile index 479a73e8ba1..565f15b8761 100644 --- a/frameworks/Rust/rocket/rocket.dockerfile +++ b/frameworks/Rust/rocket/rocket.dockerfile @@ -15,7 +15,7 @@ RUN set -eux; \ 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; \ + ./rustup-init -y --no-modify-path --default-toolchain nightly-2019-12-13; \ rm rustup-init; \ chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \ rustup --version; \ @@ -36,4 +36,4 @@ ENV DATABASE_URL=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_w RUN cargo clean RUN RUSTFLAGS="-C target-cpu=native" cargo build --release -CMD ./target/release/rocket \ No newline at end of file +CMD ./target/release/rocket diff --git a/frameworks/Rust/rocket/src/main.rs b/frameworks/Rust/rocket/src/main.rs index fe09ad04bb8..de229b35783 100644 --- a/frameworks/Rust/rocket/src/main.rs +++ b/frameworks/Rust/rocket/src/main.rs @@ -8,21 +8,60 @@ extern crate rocket_contrib; extern crate diesel; #[macro_use] extern crate serde_derive; +extern crate lazy_static; use diesel::prelude::*; use diesel::result::Error; -use rand::Rng; -use rocket_contrib::json::Json; -use rocket::config::{Config, LoggingLevel, Environment}; +use lazy_static::lazy_static; +use rand::seq::SliceRandom; +use rand::thread_rng; +use rocket::config::{Config, Environment, LoggingLevel}; use rocket::response::content; +use rocket_contrib::json::Json; +use std::sync::Mutex; use yarte::Template; mod db; mod models; mod schema; +struct RandomArray { + pointer: usize, + size: i32, + data: Vec<i32>, +} + +impl RandomArray { + fn new(size: i32) -> Self { + let mut data: Vec<i32> = (1..=size).collect(); + let mut rng = thread_rng(); + data.shuffle(&mut rng); + + RandomArray { + pointer: 0, + size, + data, + } + } + + fn next(&mut self) -> i32 { + if self.pointer >= self.size as usize { + self.pointer = 1; + } else { + self.pointer += 1; + } + self.data[self.pointer - 1] + } +} + +lazy_static! { + static ref RANDOM_ARRAY: Mutex<RandomArray> = Mutex::new(RandomArray::new(10000)); +} fn random_number() -> i32 { - rand::thread_rng().gen_range(1, 10_001) + RANDOM_ARRAY + .lock() + .expect("Failed to lock RANDOM_ARRAY") + .next() } #[get("/plaintext")] @@ -70,10 +109,11 @@ fn queries(conn: db::DbConn, q: u16) -> Json<Vec<models::World>> { let mut results = Vec::with_capacity(q as usize); for _ in 0..q { + let query_id = random_number(); let result = world - .filter(id.eq(random_number())) + .filter(id.eq(query_id)) .first::<models::World>(&*conn) - .expect("error loading world"); + .unwrap_or_else(|_| panic!("error loading world, id={}", query_id)); results.push(result); } @@ -83,7 +123,7 @@ fn queries(conn: db::DbConn, q: u16) -> Json<Vec<models::World>> { #[derive(Template)] #[template(path = "fortunes.html.hbs")] pub struct FortunesTemplate<'a> { - pub fortunes: &'a Vec<models::Fortune> + pub fortunes: &'a Vec<models::Fortune>, } #[get("/fortunes")] @@ -101,7 +141,13 @@ fn fortunes(conn: db::DbConn) -> content::Html<String> { fortunes.sort_by(|a, b| a.message.cmp(&b.message)); - content::Html(FortunesTemplate{fortunes: &fortunes}.call().expect("error rendering template")) + content::Html( + FortunesTemplate { + fortunes: &fortunes, + } + .call() + .expect("error rendering template"), + ) } #[get("/updates")] @@ -124,10 +170,11 @@ fn updates(conn: db::DbConn, q: u16) -> Json<Vec<models::World>> { let mut results = Vec::with_capacity(q as usize); for _ in 0..q { + let query_id = random_number(); let mut result = world - .filter(id.eq(random_number())) + .filter(id.eq(query_id)) .first::<models::World>(&*conn) - .expect("error loading world"); + .unwrap_or_else(|_| panic!("error loading world, id={}", query_id)); result.randomNumber = random_number(); results.push(result); } @@ -150,9 +197,12 @@ fn main() { .address("0.0.0.0") .port(8000) .log_level(LoggingLevel::Off) - .workers((num_cpus::get()*16) as u16) + .workers((num_cpus::get() * 16) as u16) + .keep_alive(0) .expect("failed to generate config"); - config.set_secret_key("dY+Rj2ybjGxKetLawKGSWi6EzESKejvENbQ3stffZg0=").expect("failed to set secret"); + config + .set_secret_key("dY+Rj2ybjGxKetLawKGSWi6EzESKejvENbQ3stffZg0=") + .expect("failed to set secret"); rocket::custom(config) .mount( "/",