Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 35 additions & 192 deletions frameworks/Rust/xitca-web/Cargo.lock

Large diffs are not rendered by default.

34 changes: 18 additions & 16 deletions frameworks/Rust/xitca-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ path = "./src/main.rs"
required-features = ["io-uring", "pg", "router", "template"]

[[bin]]
name = "xitca-web-unrealistic"
path = "./src/main_unrealistic.rs"
required-features = ["perf", "pg", "template"]
name = "xitca-web-barebone"
path = "./src/main_barebone.rs"
required-features = ["perf", "perf-json", "pg", "template"]

[[bin]]
name = "xitca-web-diesel"
path = "./src/main_orm.rs"
required-features = ["diesel", "template", "web-codegen"]
required-features = ["diesel", "perf", "template", "web-codegen"]

[[bin]]
name = "xitca-web-toasty"
path = "./src/main_orm.rs"
required-features = ["toasty", "template", "web-codegen"]
required-features = ["perf", "template", "toasty", "web-codegen"]

[features]
# pg client optional
Expand All @@ -41,7 +41,8 @@ template = ["dep:sailfish"]
# io-uring optional
io-uring = ["dep:tokio-uring", "xitca-http/io-uring", "xitca-server/io-uring"]
# unrealistic performance optimization
perf = ["dep:core_affinity", "dep:mimalloc", "tokio/parking_lot", "simd-json", "simd-json-derive"]
perf = ["dep:core_affinity", "dep:mimalloc", "tokio/parking_lot"]
perf-json = ["simd-json", "simd-json-derive"]

[dependencies]
xitca-http = "0.7"
Expand All @@ -63,7 +64,7 @@ xitca-postgres = { version = "0.3", optional = true }

# diesel orm optional
diesel = { version = "2", features = ["postgres"], optional = true }
diesel-async = { version = "0.7", features = ["bb8", "postgres"], optional = true }
diesel-async = { version = "0.7", optional = true }
xitca-postgres-diesel = { version = "0.2", default-features = false, optional = true }
futures-util = { version = "0.3", default-features = false, optional = true }

Expand All @@ -85,7 +86,7 @@ simd-json-derive = { version = "0.18", default-features = false, optional = tru

futures-core = { version = "0.3", default-features = false }
rand = { version = "0.9", features = ["os_rng", "small_rng"], default-features = false }
tokio = "1.41"
tokio = "1.48"

[profile.release]
lto = true
Expand All @@ -94,17 +95,18 @@ codegen-units = 1
panic = "abort"

[patch.crates-io]
xitca-postgres-diesel = { git = "https://github.com/fakeshadow/xitca-postgres-diesel", rev = "7671975" }
xitca-postgres-diesel = { git = "https://github.com/fakeshadow/xitca-postgres-diesel", rev = "fb5dcba" }
xitca-postgres-toasty = { git = "https://github.com/fakeshadow/xitca-postgres-toasty", rev = "04bedb8" }

# personal fork for efficient toasty engine fine tuned with pipelined xitca-postgres client
toasty = { git = "https://github.com/fakeshadow/toasty", branch = "engine" }
toasty-core = { git = "https://github.com/fakeshadow/toasty", branch = "engine" }
toasty-sql = { git = "https://github.com/fakeshadow/toasty", branch = "engine" }

xitca-codegen = { git = "http://github.com/HFQR/xitca-web", rev = "cf70ed7" }
xitca-http = { git = "http://github.com/HFQR/xitca-web", rev = "cf70ed7" }
xitca-postgres = { git = "http://github.com/HFQR/xitca-web", rev = "cf70ed7" }
xitca-server = { git = "http://github.com/HFQR/xitca-web", rev = "cf70ed7" }
xitca-service = { git = "http://github.com/HFQR/xitca-web", rev = "cf70ed7" }
xitca-web = { git = "http://github.com/HFQR/xitca-web", rev = "cf70ed7" }
tokio-uring = { git = "http://github.com/fakeshadow/tokio-uring", rev = "97d9a98" }

xitca-codegen = { git = "http://github.com/HFQR/xitca-web", rev = "adc7ff1" }
xitca-http = { git = "http://github.com/HFQR/xitca-web", rev = "adc7ff1" }
xitca-postgres = { git = "http://github.com/HFQR/xitca-web", rev = "adc7ff1" }
xitca-server = { git = "http://github.com/HFQR/xitca-web", rev = "adc7ff1" }
xitca-service = { git = "http://github.com/HFQR/xitca-web", rev = "adc7ff1" }
xitca-web = { git = "http://github.com/HFQR/xitca-web", rev = "adc7ff1" }
6 changes: 3 additions & 3 deletions frameworks/Rust/xitca-web/benchmark_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
"notes": "",
"versus": ""
},
"unrealistic": {
"barebone": {
"json_url": "/json",
"plaintext_url": "/plaintext",
"db_url": "/db",
"fortune_url": "/fortunes",
"query_url": "/queries?q=",
"update_url": "/updates?q=",
"port": 8080,
"approach": "Stripped",
"approach": "Realistic",
"classification": "Platform",
"database": "Postgres",
"framework": "xitca-web",
Expand All @@ -42,7 +42,7 @@
"webserver": "xitca-server",
"os": "Linux",
"database_os": "Linux",
"display_name": "xitca-web [unrealistic]",
"display_name": "xitca-web [barebone]",
"notes": "",
"versus": ""
},
Expand Down
64 changes: 32 additions & 32 deletions frameworks/Rust/xitca-web/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
#[path = "./db_util.rs"]
mod db_util;

use core::cell::RefCell;

use xitca_postgres::{Execute, iter::AsyncLendingIterator, pipeline::Pipeline, pool::Pool};
use xitca_postgres::{Execute, iter::AsyncLendingIterator, pool::Pool};

use super::{
ser::{Fortune, Fortunes, World},
util::{DB_URL, HandleResult},
util::{DB_URL, HandleResult, Rand},
};

use db_util::{FORTUNE_STMT, Shared, UPDATE_STMT, WORLD_STMT, not_found};
use db_util::{FORTUNE_STMT, UPDATE_STMT, WORLD_STMT, not_found};

pub struct Client {
pool: Pool,
shared: RefCell<Shared>,
rng: core::cell::RefCell<Rand>,
}

pub async fn create() -> HandleResult<Client> {
Ok(Client {
pool: Pool::builder(DB_URL).capacity(1).build()?,
shared: Default::default(),
rng: Default::default(),
})
}

impl Client {
pub async fn get_world(&self) -> HandleResult<World> {
let mut conn = self.pool.get().await?;
let stmt = WORLD_STMT.execute(&mut conn).await?;
let id = self.shared.borrow_mut().0.gen_id();
let id = self.rng.borrow_mut().gen_id();
let mut res = stmt.bind([id]).query(&conn.consume()).await?;
let row = res.try_next().await?.ok_or_else(not_found)?;
Ok(World::new(row.get(0), row.get(1)))
Expand All @@ -38,19 +36,21 @@ impl Client {
let mut conn = self.pool.get().await?;
let stmt = WORLD_STMT.execute(&mut conn).await?;

let mut res = {
let (ref mut rng, ref mut buf) = *self.shared.borrow_mut();
let mut pipe = Pipeline::with_capacity_from_buf(num as _, buf);
rng.gen_multi()
.take(num as _)
.try_for_each(|id| stmt.bind([id]).query(&mut pipe))?;
pipe.query(&conn.consume())?
};
let get = self
.rng
.borrow_mut()
.gen_multi()
.take(num as _)
.map(|id| stmt.bind([id]).query(&conn))
.collect::<Vec<_>>();

drop(conn);

let mut worlds = Vec::with_capacity(num as _);

while let Some(mut item) = res.try_next().await? {
let row = item.try_next().await?.ok_or_else(not_found)?;
for get in get {
let mut res = get.await?;
let row = res.try_next().await?.ok_or_else(not_found)?;
worlds.push(World::new(row.get(0), row.get(1)));
}

Expand All @@ -62,32 +62,32 @@ impl Client {
let world_stmt = WORLD_STMT.execute(&mut conn).await?;
let update_stmt = UPDATE_STMT.execute(&mut conn).await?;

let (mut res, worlds) = {
let (ref mut rng, ref mut buf) = *self.shared.borrow_mut();
let mut pipe = Pipeline::with_capacity_from_buf((num + 1) as _, buf);

let (get, update, worlds) = {
let mut rng = self.rng.borrow_mut();
let mut ids = rng.gen_multi().take(num as _).collect::<Vec<_>>();
ids.sort();

let (rngs, worlds) = ids
let (get, rngs, worlds) = ids
.iter()
.cloned()
.zip(rng.gen_multi())
.map(|(id, rand)| {
world_stmt.bind([id]).query(&mut pipe)?;
HandleResult::Ok((rand, World::new(id, rand)))
let get = world_stmt.bind([id]).query(&conn);
(get, rand, World::new(id, rand))
})
.collect::<HandleResult<(Vec<_>, Vec<_>)>>()?;
update_stmt.bind([&ids, &rngs]).query(&mut pipe)?;
(pipe.query(&conn.consume())?, worlds)
.collect::<(Vec<_>, Vec<_>, Vec<_>)>();

let update = update_stmt.bind([&ids, &rngs]).query(&conn.consume());

(get, update, worlds)
};

while let Some(mut item) = res.try_next().await? {
while let Some(row) = item.try_next().await? {
let _rand = row.get::<i32>(1);
}
for fut in get {
let _rand = fut.await?.try_next().await?.ok_or_else(not_found)?.get::<i32>(1);
}

update.await?;

Ok(worlds)
}

Expand Down
28 changes: 8 additions & 20 deletions frameworks/Rust/xitca-web/src/db_diesel.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use diesel::prelude::*;
use diesel_async::{
RunQueryDsl,
pooled_connection::{AsyncDieselConnectionManager, bb8},
};
use diesel_async::{AsyncConnection, RunQueryDsl};
use futures_util::future::{TryFutureExt, TryJoinAll, try_join};
use xitca_postgres_diesel::AsyncPgConnection;

Expand All @@ -12,18 +9,13 @@ use crate::{
};

pub struct Pool {
pool: bb8::Pool<AsyncPgConnection>,
pool: AsyncPgConnection,
rng: core::cell::RefCell<Rand>,
}

impl Pool {
pub async fn create() -> HandleResult<Self> {
let pool = bb8::Pool::builder()
.max_size(1)
.min_idle(Some(1))
.test_on_check_out(false)
.build(AsyncDieselConnectionManager::new(DB_URL))
.await?;
let pool = AsyncPgConnection::establish(DB_URL).await?;

Ok(Self {
pool,
Expand All @@ -36,8 +28,7 @@ impl Pool {
use schema::world::dsl::*;

let w_id = self.rng.borrow_mut().gen_id();
let mut conn = self.pool.get().await?;
world.filter(id.eq(w_id)).first(&mut conn).map_err(Into::into)
world.filter(id.eq(w_id)).first(&mut &self.pool).map_err(Into::into)
}
.await
}
Expand All @@ -46,12 +37,11 @@ impl Pool {
{
use schema::world::dsl::*;

let mut conn = self.pool.get().await?;
self.rng
.borrow_mut()
.gen_multi()
.take(num as _)
.map(|w_id| world.filter(id.eq(w_id)).first(&mut conn).map_err(Into::into))
.map(|w_id| world.filter(id.eq(w_id)).first(&mut &self.pool).map_err(Into::into))
.collect::<TryJoinAll<_>>()
}
.await
Expand All @@ -61,7 +51,6 @@ impl Pool {
{
use schema::world::dsl::*;

let mut conn = self.pool.get().await?;
let mut rng = self.rng.borrow_mut();
let mut params = Vec::with_capacity(num as _);

Expand All @@ -71,7 +60,7 @@ impl Pool {
.take(num as _)
.zip(rng.gen_multi())
.map(|(w_id, rng)| {
let get = world.filter(id.eq(w_id)).first::<World>(&mut conn);
let get = world.filter(id.eq(w_id)).first::<World>(&mut &self.pool);

params.push((w_id, rng));

Expand All @@ -84,7 +73,7 @@ impl Pool {
.collect::<TryJoinAll<_>>();

let sql = update_query_from_ids(params);
let update = diesel::sql_query(sql).execute(&mut conn).map_err(Into::into);
let update = diesel::sql_query(sql).execute(&mut &self.pool).map_err(Into::into);

try_join(get, update)
}
Expand All @@ -96,8 +85,7 @@ impl Pool {
{
use schema::fortune::dsl::*;

let mut conn = self.pool.get().await?;
fortune.load(&mut conn).map_err(Into::into)
fortune.load(&mut &self.pool).map_err(Into::into)
}
.await
.map(Fortunes::new)
Expand Down
1 change: 0 additions & 1 deletion frameworks/Rust/xitca-web/src/db_toasty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::{
util::{DB_URL, HandleResult, Rand},
};

// this is not a realistic connection pool.
pub struct Pool {
db: Db,
rng: core::cell::RefCell<Rand>,
Expand Down
Loading
Loading