Browse Source

[xitca-web] add missing bench category. (#8607)

fakeshadow 1 year ago
parent
commit
644b886826

+ 9 - 9
frameworks/Rust/xitca-web/Cargo.lock

@@ -1100,7 +1100,7 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 [[package]]
 [[package]]
 name = "xitca-http"
 name = "xitca-http"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "futures-core",
  "futures-core",
  "http",
  "http",
@@ -1121,7 +1121,7 @@ dependencies = [
 [[package]]
 [[package]]
 name = "xitca-io"
 name = "xitca-io"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "bytes",
  "bytes",
  "tokio",
  "tokio",
@@ -1132,7 +1132,7 @@ dependencies = [
 [[package]]
 [[package]]
 name = "xitca-postgres"
 name = "xitca-postgres"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "fallible-iterator",
  "fallible-iterator",
  "percent-encoding",
  "percent-encoding",
@@ -1148,7 +1148,7 @@ dependencies = [
 [[package]]
 [[package]]
 name = "xitca-router"
 name = "xitca-router"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "xitca-unsafe-collection",
  "xitca-unsafe-collection",
 ]
 ]
@@ -1156,7 +1156,7 @@ dependencies = [
 [[package]]
 [[package]]
 name = "xitca-server"
 name = "xitca-server"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "socket2 0.5.5",
  "socket2 0.5.5",
  "tokio",
  "tokio",
@@ -1170,12 +1170,12 @@ dependencies = [
 [[package]]
 [[package]]
 name = "xitca-service"
 name = "xitca-service"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 
 
 [[package]]
 [[package]]
 name = "xitca-unsafe-collection"
 name = "xitca-unsafe-collection"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "bytes",
  "bytes",
 ]
 ]
@@ -1203,13 +1203,13 @@ dependencies = [
  "xitca-server",
  "xitca-server",
  "xitca-service",
  "xitca-service",
  "xitca-unsafe-collection",
  "xitca-unsafe-collection",
- "xitca-web 0.1.0 (git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e)",
+ "xitca-web 0.1.0 (git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "xitca-web"
 name = "xitca-web"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f#263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f"
 dependencies = [
 dependencies = [
  "futures-core",
  "futures-core",
  "pin-project-lite",
  "pin-project-lite",

+ 14 - 12
frameworks/Rust/xitca-web/Cargo.toml

@@ -21,13 +21,15 @@ required-features = ["web"]
 [[bin]]
 [[bin]]
 name = "xitca-web-axum"
 name = "xitca-web-axum"
 path = "./src/main_axum.rs"
 path = "./src/main_axum.rs"
-required-features = ["axum", "io-uring"]
+required-features = ["axum", "io-uring", "pg-sync", "template"]
 
 
 [features]
 [features]
 # pg optional
 # pg optional
-pg = ["xitca-postgres"]
+pg = ["xitca-postgres/single-thread"]
+# pg send/sync optional
+pg-sync = ["xitca-postgres"]
 # pg io_uring optional
 # pg io_uring optional
-pg-iou = ["xitca-postgres/io-uring"]
+pg-iou = ["pg", "xitca-postgres/io-uring"]
 # http router optional
 # http router optional
 router = ["xitca-http/router"]
 router = ["xitca-http/router"]
 # web optional
 # web optional
@@ -54,7 +56,7 @@ serde_json = { version = "1" }
 xitca-web = { version = "0.1", features = ["json"], optional = true }
 xitca-web = { version = "0.1", features = ["json"], optional = true }
 
 
 # raw-pg optional
 # raw-pg optional
-xitca-postgres = { version = "0.1", features = ["single-thread"], optional = true }
+xitca-postgres = { version = "0.1", optional = true }
 
 
 # template optional
 # template optional
 sailfish = { version = "0.8", default-features = false, features = ["derive", "perf-inline"], optional = true }
 sailfish = { version = "0.8", default-features = false, features = ["derive", "perf-inline"], optional = true }
@@ -80,13 +82,13 @@ codegen-units = 1
 panic = "abort"
 panic = "abort"
 
 
 [patch.crates-io]
 [patch.crates-io]
-xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-router = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
-xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" }
+xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-router = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
+xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "263ea4e01f8f840dfdb3b82ba804d7b0912d5e7f" }
 
 
 mio = { git = "https://github.com/fakeshadow/mio.git", rev = "52b72d372bfe5807755b7f5e3e1edf282954d6ba" }
 mio = { git = "https://github.com/fakeshadow/mio.git", rev = "52b72d372bfe5807755b7f5e3e1edf282954d6ba" }

+ 7 - 3
frameworks/Rust/xitca-web/benchmark_config.json

@@ -67,10 +67,14 @@
       "axum": {
       "axum": {
         "json_url": "/json",
         "json_url": "/json",
         "plaintext_url": "/plaintext",
         "plaintext_url": "/plaintext",
+        "db_url": "/db",
+        "fortune_url": "/fortunes",
+        "query_url": "/queries?q=",
+        "update_url": "/updates?q=",
         "port": 8080,
         "port": 8080,
-        "approach": "Realistic",
-        "classification": "Micro",
-        "database": "none",
+        "approach": "realistic",
+        "classification": "micro",
+        "database": "postgres",
         "framework": "axum [xitca]",
         "framework": "axum [xitca]",
         "language": "rust",
         "language": "rust",
         "orm": "raw",
         "orm": "raw",

+ 23 - 7
frameworks/Rust/xitca-web/src/db.rs

@@ -1,4 +1,4 @@
-use std::{cell::RefCell, collections::HashMap, fmt::Write, future::IntoFuture};
+use std::{collections::HashMap, fmt::Write, future::IntoFuture};
 
 
 use xitca_postgres::{statement::Statement, AsyncIterator, Postgres};
 use xitca_postgres::{statement::Statement, AsyncIterator, Postgres};
 use xitca_unsafe_collection::no_hash::NoHashBuilder;
 use xitca_unsafe_collection::no_hash::NoHashBuilder;
@@ -10,7 +10,10 @@ use super::{
 
 
 pub struct Client {
 pub struct Client {
     client: xitca_postgres::Client,
     client: xitca_postgres::Client,
-    rng: RefCell<Rand>,
+    #[cfg(not(feature = "pg-sync"))]
+    rng: std::cell::RefCell<Rand>,
+    #[cfg(feature = "pg-sync")]
+    rng: std::sync::Mutex<Rand>,
     fortune: Statement,
     fortune: Statement,
     world: Statement,
     world: Statement,
     updates: HashMap<u16, Statement, NoHashBuilder>,
     updates: HashMap<u16, Statement, NoHashBuilder>,
@@ -29,7 +32,7 @@ impl Drop for Client {
 pub async fn create(config: &str) -> HandleResult<Client> {
 pub async fn create(config: &str) -> HandleResult<Client> {
     let (client, driver) = Postgres::new(config.to_string()).connect().await?;
     let (client, driver) = Postgres::new(config.to_string()).connect().await?;
 
 
-    tokio::task::spawn_local(tokio::task::unconstrained(driver.into_future()));
+    tokio::spawn(tokio::task::unconstrained(driver.into_future()));
 
 
     let fortune = client.prepare("SELECT * FROM fortune", &[]).await?.leak();
     let fortune = client.prepare("SELECT * FROM fortune", &[]).await?.leak();
 
 
@@ -62,7 +65,10 @@ pub async fn create(config: &str) -> HandleResult<Client> {
 
 
     Ok(Client {
     Ok(Client {
         client,
         client,
-        rng: RefCell::new(Rand::default()),
+        #[cfg(not(feature = "pg-sync"))]
+        rng: std::cell::RefCell::new(Rand::default()),
+        #[cfg(feature = "pg-sync")]
+        rng: std::sync::Mutex::new(Rand::default()),
         fortune,
         fortune,
         world,
         world,
         updates,
         updates,
@@ -70,8 +76,18 @@ pub async fn create(config: &str) -> HandleResult<Client> {
 }
 }
 
 
 impl Client {
 impl Client {
+    #[cfg(not(feature = "pg-sync"))]
+    fn borrow_rng_mut(&self) -> std::cell::RefMut<'_, Rand> {
+        self.rng.borrow_mut()
+    }
+
+    #[cfg(feature = "pg-sync")]
+    fn borrow_rng_mut(&self) -> std::sync::MutexGuard<'_, Rand> {
+        self.rng.lock().unwrap()
+    }
+
     pub async fn get_world(&self) -> HandleResult<World> {
     pub async fn get_world(&self) -> HandleResult<World> {
-        let id = self.rng.borrow_mut().gen_id();
+        let id = self.borrow_rng_mut().gen_id();
         self.client
         self.client
             .query_raw(&self.world, [id])
             .query_raw(&self.world, [id])
             .await?
             .await?
@@ -86,7 +102,7 @@ impl Client {
         let mut pipe = self.client.pipeline();
         let mut pipe = self.client.pipeline();
 
 
         {
         {
-            let mut rng = self.rng.borrow_mut();
+            let mut rng = self.borrow_rng_mut();
             (0..num).try_for_each(|_| pipe.query_raw(&self.world, [rng.gen_id()]))?;
             (0..num).try_for_each(|_| pipe.query_raw(&self.world, [rng.gen_id()]))?;
         }
         }
 
 
@@ -112,7 +128,7 @@ impl Client {
         let mut pipe = self.client.pipeline();
         let mut pipe = self.client.pipeline();
 
 
         {
         {
-            let mut rng = self.rng.borrow_mut();
+            let mut rng = self.borrow_rng_mut();
             (0..num).try_for_each(|_| {
             (0..num).try_for_each(|_| {
                 let w_id = rng.gen_id();
                 let w_id = rng.gen_id();
                 let r_id = rng.gen_id();
                 let r_id = rng.gen_id();

+ 67 - 13
frameworks/Rust/xitca-web/src/main_axum.rs

@@ -3,30 +3,47 @@
 #[global_allocator]
 #[global_allocator]
 static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
 static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
 
 
+mod db;
 mod ser;
 mod ser;
 mod util;
 mod util;
 
 
+use std::sync::Arc;
+
 use axum::{
 use axum::{
-    http::header::{HeaderValue, SERVER},
-    response::IntoResponse,
+    body::Bytes,
+    extract::{Json, OriginalUri as Uri, State},
+    http::{
+        header::{HeaderValue, SERVER},
+        StatusCode,
+    },
+    response::{Html, IntoResponse, Response},
     routing::{get, Router},
     routing::{get, Router},
-    Json,
 };
 };
 use tower_http::set_header::SetResponseHeaderLayer;
 use tower_http::set_header::SetResponseHeaderLayer;
 
 
-use crate::tower_compat::TowerHttp;
+use crate::{
+    db::Client,
+    tower_compat::TowerHttp,
+    util::{QueryParse, DB_URL},
+};
 
 
 fn main() -> std::io::Result<()> {
 fn main() -> std::io::Result<()> {
     let service = TowerHttp::service(|| async {
     let service = TowerHttp::service(|| async {
-        Router::new()
+        let cli = db::create(DB_URL).await?;
+        let service = Router::new()
             .route("/plaintext", get(plain_text))
             .route("/plaintext", get(plain_text))
             .route("/json", get(json))
             .route("/json", get(json))
+            .route("/db", get(db))
+            .route("/fortunes", get(fortunes))
+            .route("/queries", get(queries))
+            .route("/updates", get(updates))
+            .with_state(Arc::new(cli))
             .layer(SetResponseHeaderLayer::if_not_present(
             .layer(SetResponseHeaderLayer::if_not_present(
                 SERVER,
                 SERVER,
                 HeaderValue::from_static("A"),
                 HeaderValue::from_static("A"),
-            ))
+            ));
+        Ok(service)
     });
     });
-
     xitca_server::Builder::new()
     xitca_server::Builder::new()
         .bind("xitca-axum", "0.0.0.0:8080", service)?
         .bind("xitca-axum", "0.0.0.0:8080", service)?
         .build()
         .build()
@@ -41,10 +58,48 @@ async fn json() -> impl IntoResponse {
     Json(ser::Message::new())
     Json(ser::Message::new())
 }
 }
 
 
+async fn db(State(cli): State<Arc<Client>>) -> impl IntoResponse {
+    cli.get_world().await.map(Json).map_err(Error)
+}
+
+async fn fortunes(State(cli): State<Arc<Client>>) -> impl IntoResponse {
+    use sailfish::TemplateOnce;
+    cli.tell_fortune()
+        .await
+        .map_err(Error)?
+        .render_once()
+        .map(Html)
+        .map_err(|e| Error(Box::new(e)))
+}
+
+async fn queries(State(cli): State<Arc<Client>>, Uri(uri): Uri) -> impl IntoResponse {
+    cli.get_worlds(uri.query().parse_query())
+        .await
+        .map(Json)
+        .map_err(Error)
+}
+
+async fn updates(State(cli): State<Arc<Client>>, Uri(uri): Uri) -> impl IntoResponse {
+    cli.update(uri.query().parse_query())
+        .await
+        .map(Json)
+        .map_err(Error)
+}
+
+struct Error(util::Error);
+
+impl IntoResponse for Error {
+    fn into_response(self) -> Response {
+        let mut res = Bytes::new().into_response();
+        *res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
+        res
+    }
+}
+
+// compat module between xitca-http and axum.
 mod tower_compat {
 mod tower_compat {
     use std::{
     use std::{
         cell::RefCell,
         cell::RefCell,
-        convert::Infallible,
         error, fmt,
         error, fmt,
         future::Future,
         future::Future,
         io,
         io,
@@ -78,24 +133,23 @@ mod tower_compat {
 
 
     impl<S, B> TowerHttp<S, B> {
     impl<S, B> TowerHttp<S, B> {
         pub fn service<F, Fut>(
         pub fn service<F, Fut>(
-            service: F,
+            func: F,
         ) -> impl Service<
         ) -> impl Service<
             Response = impl ReadyService + Service<(TcpStream, SocketAddr)>,
             Response = impl ReadyService + Service<(TcpStream, SocketAddr)>,
             Error = impl fmt::Debug,
             Error = impl fmt::Debug,
         >
         >
         where
         where
             F: Fn() -> Fut + Send + Sync + Clone,
             F: Fn() -> Fut + Send + Sync + Clone,
-            Fut: Future<Output = S>,
+            Fut: Future<Output = Result<S, crate::util::Error>>,
             S: tower::Service<Request<_RequestBody>, Response = Response<B>>,
             S: tower::Service<Request<_RequestBody>, Response = Response<B>>,
             S::Error: fmt::Debug,
             S::Error: fmt::Debug,
             B: Body<Data = Bytes> + Send + 'static,
             B: Body<Data = Bytes> + Send + 'static,
             B::Error: error::Error + Send + Sync,
             B::Error: error::Error + Send + Sync,
         {
         {
             fn_build(move |_| {
             fn_build(move |_| {
-                let service = service.clone();
+                let func = func.clone();
                 async move {
                 async move {
-                    let service = service().await;
-                    Ok::<_, Infallible>(TowerHttp {
+                    func().await.map(|service| TowerHttp {
                         service: RefCell::new(service),
                         service: RefCell::new(service),
                         _p: PhantomData,
                         _p: PhantomData,
                     })
                     })

+ 1 - 3
frameworks/Rust/xitca-web/src/main_wasm.rs

@@ -13,8 +13,6 @@ use xitca_web::{
     App,
     App,
 };
 };
 
 
-use self::util::SERVER_HEADER_VALUE;
-
 fn main() -> io::Result<()> {
 fn main() -> io::Result<()> {
     let fd = env::var("FD_COUNT")
     let fd = env::var("FD_COUNT")
         .ok()
         .ok()
@@ -44,7 +42,7 @@ where
     S: for<'r> Service<WebRequest<'r>, Response = WebResponse, Error = E>,
     S: for<'r> Service<WebRequest<'r>, Response = WebResponse, Error = E>,
 {
 {
     service.call(ctx).await.map(|mut res| {
     service.call(ctx).await.map(|mut res| {
-        res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
+        res.headers_mut().append(SERVER, util::SERVER_HEADER_VALUE);
         res
         res
     })
     })
 }
 }

+ 0 - 2
frameworks/Rust/xitca-web/src/util.rs

@@ -30,7 +30,6 @@ pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
 pub type HandleResult<T> = Result<T, Error>;
 pub type HandleResult<T> = Result<T, Error>;
 
 
 #[cfg(not(target_arch = "wasm32"))]
 #[cfg(not(target_arch = "wasm32"))]
-#[cfg(any(feature = "pg", feature = "pg-iou"))]
 mod non_wasm {
 mod non_wasm {
     use core::{cell::RefCell, future::Future, pin::Pin};
     use core::{cell::RefCell, future::Future, pin::Pin};
 
 
@@ -77,5 +76,4 @@ mod non_wasm {
 }
 }
 
 
 #[cfg(not(target_arch = "wasm32"))]
 #[cfg(not(target_arch = "wasm32"))]
-#[cfg(any(feature = "pg", feature = "pg-iou"))]
 pub use non_wasm::*;
 pub use non_wasm::*;

+ 1 - 1
frameworks/Rust/xitca-web/xitca-web-axum.dockerfile

@@ -3,7 +3,7 @@ FROM rust:1.74
 ADD ./ /xitca-web
 ADD ./ /xitca-web
 WORKDIR /xitca-web
 WORKDIR /xitca-web
 
 
-RUN cargo build --release --bin xitca-web-axum --features axum,io-uring
+RUN cargo build --release --bin xitca-web-axum --features axum,io-uring,pg-sync,template
 
 
 EXPOSE 8080
 EXPOSE 8080