diff --git a/frameworks/Rust/hyper/hyper.dockerfile b/frameworks/Rust/hyper/hyper.dockerfile index b2f6b8cb6b3..4816011104f 100644 --- a/frameworks/Rust/hyper/hyper.dockerfile +++ b/frameworks/Rust/hyper/hyper.dockerfile @@ -1,8 +1,17 @@ FROM rust:1.85 AS hyper WORKDIR /src -COPY . . -RUN RUSTFLAGS="-C target-cpu=native" cargo install --path . --locked +ENV RUSTFLAGS="-C target-cpu=native" + +# Cache dependency builds (requires passing --force-rm False to tfb command) +COPY Cargo.toml Cargo.lock /src/ +RUN mkdir src \ + && echo "fn main() {println!(\"if you see this, the build broke\")}" > src/main.rs \ + && cargo build --release \ + && rm -rfv src/ target/release/hyper-techempower* target/release/deps/hyper_techempower* + +COPY . /src/ +RUN cargo install --path . --locked EXPOSE 8080 CMD ["hyper-techempower"] HEALTHCHECK CMD curl --fail http://localhost:8080/ping || exit 1 \ No newline at end of file diff --git a/frameworks/Rust/hyper/src/fortunes.rs b/frameworks/Rust/hyper/src/fortunes.rs index 0cdbd2f3ccf..46d9c269581 100644 --- a/frameworks/Rust/hyper/src/fortunes.rs +++ b/frameworks/Rust/hyper/src/fortunes.rs @@ -1,14 +1,12 @@ -use std::convert::Infallible; -use http::header::{CONTENT_LENGTH, CONTENT_TYPE, SERVER}; +use http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use http::Response; -use http_body_util::combinators::BoxBody; -use http_body_util::{BodyExt, Full}; +use http_body_util::Full; use hyper::body::Bytes; use tokio_postgres::Row; use crate::db::POOL; -use crate::{Error, SERVER_HEADER, TEXT_HTML}; +use crate::{Error, Result, TEXT_HTML}; const QUERY: &str = "SELECT id, message FROM fortune"; @@ -26,18 +24,18 @@ impl From<&Row> for Fortune { } } -pub async fn get() -> crate::Result>> { +pub async fn get() -> Result>> { let fortunes = tell_fortune().await?; let content = FortunesTemplate { fortunes }.to_string(); + Response::builder() - .header(SERVER, SERVER_HEADER.clone()) .header(CONTENT_TYPE, TEXT_HTML.clone()) .header(CONTENT_LENGTH, content.len()) - .body(Full::from(content).boxed()) + .body(content.into()) .map_err(Error::from) } -async fn tell_fortune() -> crate::Result> { +async fn tell_fortune() -> Result> { let db = POOL.get().await?; let statement = db.prepare_cached(QUERY).await?; let rows = db.query(&statement, &[]).await?; diff --git a/frameworks/Rust/hyper/src/json.rs b/frameworks/Rust/hyper/src/json.rs index c80ad50c09a..70bdabc4d53 100644 --- a/frameworks/Rust/hyper/src/json.rs +++ b/frameworks/Rust/hyper/src/json.rs @@ -1,13 +1,10 @@ -use std::convert::Infallible; - -use http::header::{CONTENT_LENGTH, CONTENT_TYPE, SERVER}; +use http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use http::Response; -use http_body_util::combinators::BoxBody; -use http_body_util::{BodyExt, Full}; +use http_body_util::Full; use hyper::body::Bytes; use serde::Serialize; -use crate::{Error, Result, APPLICATION_JSON, SERVER_HEADER}; +use crate::{Error, Result, APPLICATION_JSON}; #[derive(Serialize)] struct JsonResponse<'a> { @@ -18,12 +15,12 @@ static CONTENT: JsonResponse = JsonResponse { message: "Hello, world!", }; -pub fn get() -> Result>> { +pub fn get() -> Result>> { let content = serde_json::to_vec(&CONTENT)?; + Response::builder() - .header(SERVER, SERVER_HEADER.clone()) .header(CONTENT_TYPE, APPLICATION_JSON.clone()) .header(CONTENT_LENGTH, content.len()) - .body(Full::from(content).boxed()) + .body(content.into()) .map_err(Error::from) } diff --git a/frameworks/Rust/hyper/src/main.rs b/frameworks/Rust/hyper/src/main.rs index 81b79374172..cf4a652fc01 100644 --- a/frameworks/Rust/hyper/src/main.rs +++ b/frameworks/Rust/hyper/src/main.rs @@ -4,7 +4,7 @@ use std::{io, thread}; use clap::{Parser, ValueEnum}; use http_body_util::combinators::BoxBody; -use http_body_util::{BodyExt, Empty, Full}; +use http_body_util::Empty; use hyper::body::{Bytes, Incoming}; use hyper::header::{HeaderValue, SERVER}; use hyper::server::conn::http1; @@ -181,32 +181,31 @@ async fn accept_loop(handle: runtime::Handle, listener: TcpListener) -> Result<( /// Routes requests to the appropriate handler. async fn router(request: Request) -> Result>> { // The method is always GET, so we don't check it. - match request.uri().path() { - "/ping" => ping(), - "/json" => json::get(), - "/db" => single_query::get().await, - "/queries" => multiple_queries::get(request.uri().query()).await, - "/fortunes" => fortunes::get().await, - "/plaintext" => plaintext::get(), - _ => not_found_error(), - } + let mut response = match request.uri().path() { + "/ping" => ping()?.map(BoxBody::new), + "/json" => json::get()?.map(BoxBody::new), + "/db" => single_query::get().await?.map(BoxBody::new), + "/queries" => multiple_queries::get(request.uri().query()).await?.map(BoxBody::new), + "/fortunes" => fortunes::get().await?.map(BoxBody::new), + "/plaintext" => plaintext::get()?.map(BoxBody::new), + _ => not_found_error()?.map(BoxBody::new), + }; + response.headers_mut().insert(SERVER, SERVER_HEADER.clone()); + Ok(response) } /// A handler that returns a "pong" response. /// /// This handler is used to verify that the server is running and can respond to requests. It is /// used by the docker health check command. -fn ping() -> Result>> { - Response::builder() - .body(Full::from("pong").boxed()) - .map_err(Error::from) +fn ping() -> Result> { + Response::builder().body("pong".to_string()).map_err(Error::from) } /// A handler that returns a 404 response. -fn not_found_error() -> Result>> { +fn not_found_error() -> Result>> { Response::builder() .status(StatusCode::NOT_FOUND) - .header(SERVER, SERVER_HEADER.clone()) - .body(Empty::new().boxed()) + .body(Empty::new()) .map_err(Error::from) } diff --git a/frameworks/Rust/hyper/src/multiple_queries.rs b/frameworks/Rust/hyper/src/multiple_queries.rs index f9aa862acad..a4301bff496 100644 --- a/frameworks/Rust/hyper/src/multiple_queries.rs +++ b/frameworks/Rust/hyper/src/multiple_queries.rs @@ -1,15 +1,12 @@ -use std::convert::Infallible; - -use http::header::{CONTENT_LENGTH, CONTENT_TYPE, SERVER}; +use http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use http::Response; -use http_body_util::combinators::BoxBody; -use http_body_util::{BodyExt, Full}; +use http_body_util::Full; use hyper::body::Bytes; use serde::Serialize; use tokio_postgres::Row; use crate::db::POOL; -use crate::{Error, Result, APPLICATION_JSON, SERVER_HEADER}; +use crate::{Error, Result, APPLICATION_JSON}; const QUERY: &str = "SELECT id, randomnumber FROM world WHERE id = $1"; @@ -28,21 +25,19 @@ impl From for World { } } -pub async fn get(query: Option<&str>) -> Result>> { +pub async fn get(query: Option<&str>) -> Result>> { let count = query .and_then(|query| query.strip_prefix("count=")) .and_then(|query| query.parse().ok()) .unwrap_or(1) .clamp(1, 500); - let worlds = query_worlds(count).await?; - let json = serde_json::to_vec(&worlds)?; + let content = serde_json::to_vec(&worlds)?; Response::builder() - .header(SERVER, SERVER_HEADER.clone()) .header(CONTENT_TYPE, APPLICATION_JSON.clone()) - .header(CONTENT_LENGTH, json.len()) - .body(Full::from(json).boxed()) + .header(CONTENT_LENGTH, content.len()) + .body(content.into()) .map_err(Error::from) } diff --git a/frameworks/Rust/hyper/src/plaintext.rs b/frameworks/Rust/hyper/src/plaintext.rs index e2a081d2d39..2e523adf41e 100644 --- a/frameworks/Rust/hyper/src/plaintext.rs +++ b/frameworks/Rust/hyper/src/plaintext.rs @@ -1,20 +1,16 @@ -use std::convert::Infallible; - -use http::header::{CONTENT_LENGTH, CONTENT_TYPE, SERVER}; +use http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use http::Response; -use http_body_util::combinators::BoxBody; -use http_body_util::{BodyExt, Full}; +use http_body_util::Full; use hyper::body::Bytes; -use crate::{Error, Result, SERVER_HEADER, TEXT_PLAIN}; +use crate::{Error, Result, TEXT_PLAIN}; static CONTENT: &[u8] = b"Hello, world!"; -pub fn get() -> Result>> { +pub fn get() -> Result>> { Response::builder() - .header(SERVER, SERVER_HEADER.clone()) .header(CONTENT_TYPE, TEXT_PLAIN.clone()) .header(CONTENT_LENGTH, CONTENT.len()) - .body(Full::from(CONTENT).boxed()) + .body(CONTENT.into()) .map_err(Error::from) } diff --git a/frameworks/Rust/hyper/src/single_query.rs b/frameworks/Rust/hyper/src/single_query.rs index 62083dd4d3a..86d77b3666d 100644 --- a/frameworks/Rust/hyper/src/single_query.rs +++ b/frameworks/Rust/hyper/src/single_query.rs @@ -1,15 +1,12 @@ -use std::convert::Infallible; - -use http::header::{CONTENT_LENGTH, CONTENT_TYPE, SERVER}; +use http::header::{CONTENT_LENGTH, CONTENT_TYPE}; use http::Response; -use http_body_util::combinators::BoxBody; -use http_body_util::{BodyExt, Full}; +use http_body_util::Full; use hyper::body::Bytes; use serde::Serialize; use tokio_postgres::Row; use crate::db::POOL; -use crate::{Error, Result, APPLICATION_JSON, SERVER_HEADER}; +use crate::{Error, Result, APPLICATION_JSON}; static QUERY: &str = "SELECT id, randomnumber FROM world WHERE id = $1"; @@ -28,16 +25,15 @@ impl From for World { } } -pub async fn get() -> Result>> { +pub async fn get() -> Result>> { let id = fastrand::i32(1..10_000); let world = query_world(id).await?; - let json = serde_json::to_vec(&world)?; - + let content = serde_json::to_vec(&world)?; + Response::builder() - .header(SERVER, SERVER_HEADER.clone()) .header(CONTENT_TYPE, APPLICATION_JSON.clone()) - .header(CONTENT_LENGTH, json.len()) - .body(Full::from(json).boxed()) + .header(CONTENT_LENGTH, content.len()) + .body(content.into()) .map_err(Error::from) } diff --git a/toolset/run-tests.py b/toolset/run-tests.py index a70fff3a490..a5716913cab 100644 --- a/toolset/run-tests.py +++ b/toolset/run-tests.py @@ -208,6 +208,10 @@ def main(argv=None): nargs='*', default=None, help='Extra docker arguments to be passed to the test container') + parser.add_argument( + '--force-rm', + default=True, + help='Remove intermediate docker containers after running.') # Network options parser.add_argument( diff --git a/toolset/utils/benchmark_config.py b/toolset/utils/benchmark_config.py index 48755e9f460..1a5dc339b0f 100755 --- a/toolset/utils/benchmark_config.py +++ b/toolset/utils/benchmark_config.py @@ -55,6 +55,7 @@ def __init__(self, args): self.cpuset_cpus = args.cpuset_cpus self.test_container_memory = args.test_container_memory self.extra_docker_runtime_args = args.extra_docker_runtime_args + self.force_rm_intermediate_docker_layers = args.force_rm if self.network_mode is None: self.network = 'tfb' diff --git a/toolset/utils/docker_helper.py b/toolset/utils/docker_helper.py index e48a910e99d..f25a9d133a0 100644 --- a/toolset/utils/docker_helper.py +++ b/toolset/utils/docker_helper.py @@ -39,7 +39,7 @@ def __build(self, base_url, path, build_log_file, log_prefix, dockerfile, path=path, dockerfile=dockerfile, tag=tag, - forcerm=True, + forcerm=self.benchmarker.config.force_rm_intermediate_docker_layers, timeout=3600, pull=True, buildargs=buildargs,