Browse Source

[xitca-web] enable xitca-web-iou bench. (#8485)

* [xitca-web] enable xitca-web-iou bench.

* fix wasm build.

* use async trait.
fakeshadow 1 year ago
parent
commit
780f823f5a

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

@@ -70,9 +70,9 @@ dependencies = [
 
 [[package]]
 name = "byteorder"
-version = "1.4.3"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
@@ -190,9 +190,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
 
 [[package]]
 name = "hermit-abi"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
 
 [[package]]
 name = "hmac"
@@ -259,15 +259,15 @@ checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8"
 
 [[package]]
 name = "libc"
-version = "0.2.148"
+version = "0.2.149"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
+checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
 
 [[package]]
 name = "libmimalloc-sys"
-version = "0.1.34"
+version = "0.1.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25d058a81af0d1c22d7a1c948576bee6d673f7af3c0f35564abd6c81122f513d"
+checksum = "3979b5c37ece694f1f5e51e7ecc871fdb0f517ed04ee45f88d15d6d553cb9664"
 dependencies = [
  "cc",
  "libc",
@@ -275,24 +275,25 @@ dependencies = [
 
 [[package]]
 name = "md-5"
-version = "0.10.5"
+version = "0.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
 dependencies = [
+ "cfg-if",
  "digest",
 ]
 
 [[package]]
 name = "memchr"
-version = "2.6.3"
+version = "2.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
 
 [[package]]
 name = "mimalloc"
-version = "0.1.38"
+version = "0.1.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "972e5f23f6716f62665760b0f4cbf592576a80c7b879ba9beaafc0e558894127"
+checksum = "fa01922b5ea280a911e323e4d2fd24b7fe5cc4042e0d2cda3c40775cdc4bdc9c"
 dependencies = [
  "libmimalloc-sys",
 ]
@@ -324,9 +325,9 @@ checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
 
 [[package]]
 name = "num-traits"
-version = "0.2.16"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
+checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
 dependencies = [
  "autocfg",
 ]
@@ -399,9 +400,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.67"
+version = "1.0.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
 dependencies = [
  "unicode-ident",
 ]
@@ -468,9 +469,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
 
 [[package]]
 name = "sailfish"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7519b7521780097b0183bb4b0c7c2165b924f5f1d44c3ef765bde8c2f8008fd1"
+checksum = "7861181faa2e413410444757deca246c70959cee725fbfd8f736a94a660eb377"
 dependencies = [
  "itoap",
  "ryu",
@@ -480,9 +481,9 @@ dependencies = [
 
 [[package]]
 name = "sailfish-compiler"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "535500faca492ee8054fbffdfca6447ca97fa495e0ede9f28fa473e1a44f9d5c"
+checksum = "7c38d77ced03b393e820ac70109857bd857f93e746f5d7d631829c9ee2e4f3fa"
 dependencies = [
  "filetime",
  "home",
@@ -494,9 +495,9 @@ dependencies = [
 
 [[package]]
 name = "sailfish-macros"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06a95a6b8a0f59bf66f430a4ed37ece23fcefcd26898399573043e56fb202be2"
+checksum = "c8f73db14456f861a5c89166ab6ac76afd94b4d2a9416638ae2952ae051089c5"
 dependencies = [
  "proc-macro2",
  "sailfish-compiler",
@@ -510,18 +511,18 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
 
 [[package]]
 name = "serde"
-version = "1.0.188"
+version = "1.0.189"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
+checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.188"
+version = "1.0.189"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
+checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -530,9 +531,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.106"
+version = "1.0.107"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2"
+checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
 dependencies = [
  "itoa",
  "ryu",
@@ -541,9 +542,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.10.7"
+version = "0.10.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -607,9 +608,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
 
 [[package]]
 name = "syn"
-version = "2.0.33"
+version = "2.0.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668"
+checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -633,9 +634,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.32.0"
+version = "1.33.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
+checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
 dependencies = [
  "backtrace",
  "libc",
@@ -664,26 +665,25 @@ dependencies = [
 
 [[package]]
 name = "tracing"
-version = "0.1.37"
+version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
 dependencies = [
- "cfg-if",
  "pin-project-lite",
  "tracing-core",
 ]
 
 [[package]]
 name = "tracing-core"
-version = "0.1.31"
+version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
 
 [[package]]
 name = "typenum"
-version = "1.16.0"
+version = "1.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
 [[package]]
 name = "unicode-bidi"
@@ -809,7 +809,7 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 [[package]]
 name = "xitca-http"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "futures-core",
  "http",
@@ -830,7 +830,7 @@ dependencies = [
 [[package]]
 name = "xitca-io"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "bytes",
  "tokio",
@@ -841,7 +841,7 @@ dependencies = [
 [[package]]
 name = "xitca-postgres"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "fallible-iterator",
  "percent-encoding",
@@ -857,7 +857,7 @@ dependencies = [
 [[package]]
 name = "xitca-router"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "xitca-unsafe-collection",
 ]
@@ -865,7 +865,7 @@ dependencies = [
 [[package]]
 name = "xitca-server"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "socket2 0.5.4",
  "tokio",
@@ -879,12 +879,12 @@ dependencies = [
 [[package]]
 name = "xitca-service"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 
 [[package]]
 name = "xitca-unsafe-collection"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "bytes",
 ]
@@ -907,13 +907,13 @@ dependencies = [
  "xitca-server",
  "xitca-service",
  "xitca-unsafe-collection",
- "xitca-web 0.1.0 (git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9)",
+ "xitca-web 0.1.0 (git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a)",
 ]
 
 [[package]]
 name = "xitca-web"
 version = "0.1.0"
-source = "git+https://github.com/HFQR/xitca-web.git?rev=66a20d5fae8303918e0972798e85f55d1a5f97b9#66a20d5fae8303918e0972798e85f55d1a5f97b9"
+source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a"
 dependencies = [
  "futures-core",
  "pin-project-lite",

+ 16 - 18
frameworks/Rust/xitca-web/Cargo.toml

@@ -6,25 +6,25 @@ edition = "2021"
 [[bin]]
 name = "xitca-web"
 path = "./src/main.rs"
-required-features = ["io-uring", "pg", "serde", "template"]
+required-features = ["io-uring", "pg", "router", "template"]
 
 [[bin]]
 name = "xitca-web-iou"
 path = "./src/main_iou.rs"
-required-features = ["io-uring", "pg-iou", "serde", "template"]
+required-features = ["io-uring", "pg-iou", "template"]
 
 [[bin]]
 name = "xitca-web-wasm"
 path = "./src/main_wasm.rs"
-required-features = ["serde", "web"]
+required-features = ["web"]
 
 [features]
 # pg optional
 pg = ["xitca-postgres"]
 # pg io_uring optional
 pg-iou = ["xitca-postgres/io-uring"]
-# serde optional
-serde = ["dep:serde", "serde_json"]
+# http router optional
+router = ["xitca-http/router"]
 # web optional
 web = ["xitca-web"]
 # template optional
@@ -33,13 +33,15 @@ template = ["sailfish"]
 io-uring = ["xitca-http/io-uring", "xitca-server/io-uring"]
 
 [dependencies]
-xitca-http = { version = "0.1", features = ["util-service"] }
+xitca-http = "0.1"
 xitca-io = "0.1"
 xitca-server = "0.1"
 xitca-service = "0.1"
 xitca-unsafe-collection = "0.1"
 
 atoi = "2"
+serde = { version = "1" }
+serde_json = { version = "1" }
 
 # web optional
 xitca-web = { version = "0.1", features = ["json"], optional = true }
@@ -47,10 +49,6 @@ xitca-web = { version = "0.1", features = ["json"], optional = true }
 # raw-pg optional
 xitca-postgres = { version = "0.1", features = ["single-thread"], optional = true }
 
-# serde optional
-serde = { version = "1", optional = true }
-serde_json = { version = "1", optional = true }
-
 # template optional
 sailfish = { version = "0.8", default-features = false, features = ["derive", "perf-inline"], optional = true }
 
@@ -68,13 +66,13 @@ codegen-units = 1
 panic = "abort"
 
 [patch.crates-io]
-xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-router = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
-xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "66a20d5fae8303918e0972798e85f55d1a5f97b9" }
+xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-router = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
+xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" }
 
 mio = { git = "https://github.com/fakeshadow/mio.git", rev = "eb67f6794edba8bc2e973ddef32e066b41ff812a" }

+ 4 - 5
frameworks/Rust/xitca-web/benchmark_config.json

@@ -35,17 +35,16 @@
         "approach": "Stripped",
         "classification": "Platform",
         "database": "Postgres",
-        "framework": "xitca-web",
+        "framework": "xitca-web [unrealistic]",
         "language": "Rust",
         "orm": "Raw",
         "platform": "None",
         "webserver": "xitca-server",
         "os": "Linux",
         "database_os": "Linux",
-        "display_name": "xitca-web [io-uring]",
+        "display_name": "xitca-web [unrealistic]",
         "notes": "",
-        "versus": "",
-        "tags": ["broken"]
+        "versus": ""
       },
       "wasm": {
         "json_url": "/json",
@@ -54,7 +53,7 @@
         "approach": "Realistic",
         "classification": "Micro",
         "database": "none",
-        "framework": "xitca-web",
+        "framework": "xitca-web [wasm]",
         "language": "rust",
         "orm": "raw",
         "platform": "none",

+ 1 - 1
frameworks/Rust/xitca-web/rust-toolchain.toml

@@ -1,2 +1,2 @@
 [toolchain]
-channel = "nightly-2023-09-26"
+channel = "nightly-2023-10-19"

+ 2 - 13
frameworks/Rust/xitca-web/src/db.rs

@@ -1,4 +1,4 @@
-use std::{cell::RefCell, collections::HashMap, fmt::Write};
+use std::{cell::RefCell, collections::HashMap, fmt::Write, future::IntoFuture};
 
 use xitca_postgres::{statement::Statement, AsyncIterator, Postgres};
 use xitca_unsafe_collection::no_hash::NoHashBuilder;
@@ -29,18 +29,7 @@ impl Drop for Client {
 pub async fn create(config: &str) -> HandleResult<Client> {
     let (client, driver) = Postgres::new(config.to_string()).connect().await?;
 
-    tokio::task::spawn_local({
-        #[cfg(feature = "pg-iou")]
-        {
-            let mut drv = driver.try_into_io_uring_tcp();
-            async move { while drv.next().await.is_some() {} }
-        }
-
-        #[cfg(not(feature = "pg-iou"))]
-        {
-            std::future::IntoFuture::into_future(driver)
-        }
-    });
+    tokio::task::spawn_local(tokio::task::unconstrained(driver.into_future()));
 
     let fortune = client.prepare("SELECT * FROM fortune", &[]).await?.leak();
 

+ 22 - 38
frameworks/Rust/xitca-web/src/main.rs

@@ -5,11 +5,9 @@ mod db;
 mod ser;
 mod util;
 
-use std::{cell::RefCell, io};
-
 use xitca_http::{
     body::Once,
-    bytes::{Bytes, BytesMut},
+    bytes::Bytes,
     config::HttpServiceConfig,
     h1::RequestBody,
     http::{
@@ -18,48 +16,37 @@ use xitca_http::{
         header::{CONTENT_TYPE, SERVER},
         IntoResponse, RequestExt,
     },
-    util::service::{
-        context::{Context, ContextBuilder},
-        route::get,
-        router::Router,
-    },
+    util::service::{route::get, router::Router},
     HttpServiceBuilder,
 };
 use xitca_service::{fn_service, Service, ServiceExt};
 
 use self::{
-    db::Client,
     ser::{json_response, Message},
-    util::{HandleResult, QueryParse, DB_URL, SERVER_HEADER_VALUE},
+    util::{context_mw, HandleResult, QueryParse, SERVER_HEADER_VALUE},
 };
 
 type Response = http::Response<Once<Bytes>>;
 type Request = http::Request<RequestExt<RequestBody>>;
-type Ctx<'a> = Context<'a, Request, State>;
+type Ctx<'a> = self::util::Ctx<'a, Request>;
 
-fn main() -> io::Result<()> {
+fn main() -> std::io::Result<()> {
     xitca_server::Builder::new()
         .bind("xitca-web", "0.0.0.0:8080", || {
-            HttpServiceBuilder::h1(
-                ContextBuilder::new(|| async {
-                    db::create(DB_URL).await.map(|client| State {
-                        client,
-                        write_buf: RefCell::new(BytesMut::new()),
-                    })
-                })
-                .service(
-                    Router::new()
-                        .insert("/plaintext", get(fn_service(plain_text)))
-                        .insert("/json", get(fn_service(json)))
-                        .insert("/db", get(fn_service(db)))
-                        .insert("/fortunes", get(fn_service(fortunes)))
-                        .insert("/queries", get(fn_service(queries)))
-                        .insert("/updates", get(fn_service(updates)))
-                        .enclosed_fn(middleware_fn),
-                ),
-            )
-            .config(HttpServiceConfig::new().max_request_headers::<8>())
-            .io_uring()
+            Router::new()
+                .insert("/plaintext", get(fn_service(plain_text)))
+                .insert("/json", get(fn_service(json)))
+                .insert("/db", get(fn_service(db)))
+                .insert("/fortunes", get(fn_service(fortunes)))
+                .insert("/queries", get(fn_service(queries)))
+                .insert("/updates", get(fn_service(updates)))
+                .enclosed_fn(middleware_fn)
+                .enclosed(context_mw())
+                .enclosed(
+                    HttpServiceBuilder::h1()
+                        .io_uring()
+                        .config(HttpServiceConfig::new().max_request_headers::<8>()),
+                )
         })?
         .build()
         .wait()
@@ -75,9 +62,11 @@ where
     })
 }
 
+const HELLO: Bytes = Bytes::from_static(b"Hello, World!");
+
 async fn plain_text(ctx: Ctx<'_>) -> HandleResult<Response> {
     let (req, _) = ctx.into_parts();
-    let mut res = req.into_response(Bytes::from_static(b"Hello, World!"));
+    let mut res = req.into_response(HELLO);
     res.headers_mut().append(CONTENT_TYPE, TEXT);
     Ok(res)
 }
@@ -115,8 +104,3 @@ async fn updates(ctx: Ctx<'_>) -> HandleResult<Response> {
     let worlds = state.client.update(num).await?;
     json_response(req, &mut state.write_buf.borrow_mut(), worlds.as_slice())
 }
-
-struct State {
-    client: Client,
-    write_buf: RefCell<BytesMut>,
-}

+ 55 - 119
frameworks/Rust/xitca-web/src/main_iou.rs

@@ -1,9 +1,6 @@
 // used as reference of if/how moving from epoll to io-uring(or mixture of the two) make sense for
 // network io.
 
-#![allow(dead_code)]
-#![feature(impl_trait_in_assoc_type)]
-
 #[global_allocator]
 static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
 
@@ -11,14 +8,7 @@ mod db;
 mod ser;
 mod util;
 
-use std::{
-    cell::RefCell,
-    convert::Infallible,
-    fmt,
-    future::{poll_fn, Future},
-    io,
-    pin::pin,
-};
+use std::{convert::Infallible, fmt, future::poll_fn, io, pin::pin};
 
 use futures_core::stream::Stream;
 use xitca_http::{
@@ -31,45 +21,45 @@ use xitca_http::{
         header::{CONTENT_TYPE, SERVER},
         IntoResponse, RequestExt, StatusCode,
     },
-    util::service::context::{Context as Ctx, ContextBuilder},
 };
 use xitca_io::{
     bytes::{Bytes, BytesMut},
     io_uring::IoBuf,
     net::{io_uring::TcpStream as IOUTcpStream, TcpStream},
 };
-use xitca_service::{fn_service, middleware::UncheckedReady, Service, ServiceExt};
-use xitca_unsafe_collection::futures::NowOrPanic;
+use xitca_service::{fn_build, fn_service, middleware::UncheckedReady, Service, ServiceExt};
 
 use self::{
-    db::Client,
     ser::{json_response, Message},
-    util::{QueryParse, DB_URL, SERVER_HEADER_VALUE},
+    util::{context_mw, Ctx, QueryParse, SERVER_HEADER_VALUE},
 };
 
+type Request = http::Request<RequestExt<()>>;
+type Response = http::Response<Once<Bytes>>;
+
 fn main() -> io::Result<()> {
     xitca_server::Builder::new()
         .bind("xitca-iou", "0.0.0.0:8080", || {
-            Http1IOU::new(
-                ContextBuilder::new(|| async {
-                    db::create(DB_URL).await.map(|client| State {
-                        client,
-                        write_buf: RefCell::new(BytesMut::new()),
+            fn_service(handler)
+                .enclosed(context_mw())
+                .enclosed(fn_build(|service| async {
+                    Ok::<_, Infallible>(Http1IOU {
+                        service,
+                        date: DateTimeService::new(),
                     })
-                })
-                .service(fn_service(handler)),
-            )
-            .enclosed(UncheckedReady)
+                }))
+                .enclosed(UncheckedReady)
         })?
         .build()
         .wait()
 }
 
-async fn handler(ctx: Ctx<'_, Request, State>) -> Result<Response, Infallible> {
+async fn handler(ctx: Ctx<'_, Request>) -> Result<Response, Infallible> {
     let (req, state) = ctx.into_parts();
     let mut res = match req.uri().path() {
         "/plaintext" => {
-            let mut res = req.into_response(Bytes::from_static(b"Hello, World!"));
+            const HELLO: Bytes = Bytes::from_static(b"Hello, World!");
+            let mut res = req.into_response(HELLO);
             res.headers_mut().insert(CONTENT_TYPE, TEXT);
             res
         }
@@ -113,111 +103,57 @@ async fn handler(ctx: Ctx<'_, Request, State>) -> Result<Response, Infallible> {
 
 struct Http1IOU<S> {
     service: S,
-}
-
-impl<S> Http1IOU<S> {
-    fn new(service: S) -> Self {
-        Self { service }
-    }
-}
-
-// builder for http service.
-impl<S> Service for Http1IOU<S>
-where
-    S: Service,
-{
-    type Response = Http1IOUService<S::Response>;
-    type Error = S::Error;
-    type Future<'f> = impl Future<Output = Result<Self::Response, Self::Error>> + 'f
-    where
-        Self: 'f,
-        (): 'f;
-
-    fn call<'s>(&'s self, _: ()) -> Self::Future<'s>
-    where
-        (): 's,
-    {
-        async {
-            self.service.call(()).await.map(|service| Http1IOUService {
-                service,
-                date: DateTimeService::new(),
-            })
-        }
-    }
-}
-
-struct Http1IOUService<S> {
-    service: S,
     date: DateTimeService,
 }
 
 // runner for http service.
-impl<S> Service<TcpStream> for Http1IOUService<S>
+impl<S> Service<TcpStream> for Http1IOU<S>
 where
     S: Service<Request, Response = Response>,
     S::Error: fmt::Debug,
 {
     type Response = ();
     type Error = io::Error;
-    type Future<'f> = impl Future<Output = Result<Self::Response, Self::Error>> + 'f
-    where
-        Self: 'f,
-        TcpStream: 'f;
-
-    fn call<'s>(&'s self, stream: TcpStream) -> Self::Future<'s>
-    where
-        TcpStream: 's,
-    {
-        async {
-            let mut ctx = Context::<_, 8>::new(self.date.get());
-            let mut read_buf = BytesMut::new();
-            let mut write_buf = BytesMut::with_capacity(4096);
-
-            let std = stream.into_std()?;
-            let stream = IOUTcpStream::from_std(std);
-
-            loop {
-                let len = read_buf.len();
-                let rem = read_buf.capacity() - len;
-                if rem < 4096 {
-                    read_buf.reserve(4096 - rem);
-                }
-
-                let (res, buf) = stream.read(read_buf.slice(len..)).await;
-                read_buf = buf.into_inner();
-                if res? == 0 {
-                    break;
-                }
-
-                while let Some((req, _)) = ctx.decode_head::<{ usize::MAX }>(&mut read_buf).unwrap()
-                {
-                    let (parts, body) = self.service.call(req).await.unwrap().into_parts();
-                    let mut encoder = ctx.encode_head(parts, &body, &mut write_buf).unwrap();
-                    let mut body = pin!(body);
-                    let chunk = poll_fn(|cx| body.as_mut().poll_next(cx))
-                        .now_or_panic()
-                        .unwrap()
-                        .unwrap();
-                    encoder.encode(chunk, &mut write_buf);
-                    encoder.encode_eof(&mut write_buf);
-                }
-
-                let (res, b) = stream.write_all(write_buf).await;
-                write_buf = b;
-                write_buf.clear();
-                res?;
+
+    async fn call(&self, stream: TcpStream) -> Result<Self::Response, Self::Error> {
+        let std = stream.into_std()?;
+        let stream = IOUTcpStream::from_std(std);
+
+        let mut ctx = Context::<_, 8>::new(self.date.get());
+        let mut read_buf = BytesMut::new();
+        let mut write_buf = BytesMut::with_capacity(4096);
+
+        loop {
+            let len = read_buf.len();
+            let rem = read_buf.capacity() - len;
+            if rem < 4096 {
+                read_buf.reserve(4096 - rem);
             }
 
-            stream.shutdown(std::net::Shutdown::Both)
-        }
-    }
-}
+            let (res, buf) = stream.read(read_buf.slice(len..)).await;
+            read_buf = buf.into_inner();
+            if res? == 0 {
+                break;
+            }
 
-type Request = http::Request<RequestExt<()>>;
+            while let Some((req, _)) = ctx.decode_head::<{ usize::MAX }>(&mut read_buf).unwrap() {
+                let (parts, body) = self.service.call(req).await.unwrap().into_parts();
+                let mut encoder = ctx.encode_head(parts, &body, &mut write_buf).unwrap();
+                let mut body = pin!(body);
+                let chunk = poll_fn(|cx| body.as_mut().poll_next(cx))
+                    .await
+                    .unwrap()
+                    .unwrap();
+                encoder.encode(chunk, &mut write_buf);
+                encoder.encode_eof(&mut write_buf);
+            }
 
-type Response = http::Response<Once<Bytes>>;
+            let (res, b) = stream.write_all(write_buf).await;
+            write_buf = b;
+            write_buf.clear();
+            res?;
+        }
 
-struct State {
-    client: Client,
-    write_buf: RefCell<BytesMut>,
+        stream.shutdown(std::net::Shutdown::Both)
+    }
 }

+ 40 - 49
frameworks/Rust/xitca-web/src/ser.rs

@@ -2,6 +2,15 @@
 
 use std::borrow::Cow;
 
+use serde::{ser::SerializeStruct, Serialize, Serializer};
+use xitca_http::{
+    body::Once,
+    bytes::{BufMutWriter, Bytes, BytesMut},
+    http::{const_header_value::JSON, header::CONTENT_TYPE, IntoResponse, Request, Response},
+};
+
+use crate::util::Error;
+
 pub struct Message {
     message: &'static str,
 }
@@ -15,7 +24,6 @@ impl Message {
     }
 }
 
-#[cfg_attr(feature = "pg-orm", derive(Queryable))]
 pub struct World {
     pub id: i32,
     pub randomnumber: i32,
@@ -28,7 +36,6 @@ impl World {
     }
 }
 
-#[cfg_attr(feature = "pg-orm", derive(Queryable))]
 pub struct Fortune {
     pub id: i32,
     pub message: Cow<'static, str>,
@@ -44,6 +51,7 @@ impl Fortune {
     }
 }
 
+// TODO: use another template engine with faster compile time.(perferably with no proc macro)
 #[cfg_attr(
     feature = "template",
     derive(sailfish::TemplateOnce),
@@ -60,56 +68,39 @@ impl Fortunes {
     }
 }
 
-#[cfg(feature = "serde")]
-pub use _serde::*;
-
-#[cfg(feature = "serde")]
-mod _serde {
-    use serde::{ser::SerializeStruct, Serialize, Serializer};
-    use xitca_http::{
-        body::Once,
-        bytes::{BufMutWriter, Bytes, BytesMut},
-        http::{const_header_value::JSON, header::CONTENT_TYPE, IntoResponse, Request, Response},
-    };
-
-    use crate::util::Error;
-
-    use super::{Message, World};
-
-    impl Serialize for Message {
-        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-        where
-            S: Serializer,
-        {
-            let mut res = serializer.serialize_struct("Message", 1)?;
-            res.serialize_field("message", self.message)?;
-            res.end()
-        }
-    }
-
-    impl Serialize for World {
-        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-        where
-            S: Serializer,
-        {
-            let mut res = serializer.serialize_struct("World", 2)?;
-            res.serialize_field("id", &self.id)?;
-            res.serialize_field("randomnumber", &self.randomnumber)?;
-            res.end()
-        }
+impl Serialize for Message {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut res = serializer.serialize_struct("Message", 1)?;
+        res.serialize_field("message", self.message)?;
+        res.end()
     }
+}
 
-    pub fn json_response<Ext, S>(
-        req: Request<Ext>,
-        buf: &mut BytesMut,
-        value: &S,
-    ) -> Result<Response<Once<Bytes>>, Error>
+impl Serialize for World {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
-        S: ?Sized + Serialize,
+        S: Serializer,
     {
-        serde_json::to_writer(BufMutWriter(buf), value)?;
-        let mut res = req.into_response(buf.split().freeze());
-        res.headers_mut().append(CONTENT_TYPE, JSON);
-        Ok(res)
+        let mut res = serializer.serialize_struct("World", 2)?;
+        res.serialize_field("id", &self.id)?;
+        res.serialize_field("randomnumber", &self.randomnumber)?;
+        res.end()
     }
 }
+
+pub fn json_response<Ext, S>(
+    req: Request<Ext>,
+    buf: &mut BytesMut,
+    value: &S,
+) -> Result<Response<Once<Bytes>>, Error>
+where
+    S: ?Sized + Serialize,
+{
+    serde_json::to_writer(BufMutWriter(buf), value)?;
+    let mut res = req.into_response(buf.split().freeze());
+    res.headers_mut().append(CONTENT_TYPE, JSON);
+    Ok(res)
+}

+ 45 - 11
frameworks/Rust/xitca-web/src/util.rs

@@ -1,6 +1,6 @@
 #![allow(dead_code)]
 
-use std::cmp;
+use core::cmp;
 
 use xitca_http::http::header::HeaderValue;
 
@@ -29,17 +29,51 @@ pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
 
 pub type HandleResult<T> = Result<T, Error>;
 
-pub const DB_URL: &str = "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world";
-
 #[cfg(not(target_arch = "wasm32"))]
-#[derive(Default)]
-pub struct Rand(nanorand::WyRand);
+mod non_wasm {
+    use core::{cell::RefCell, future::Future, pin::Pin};
 
-#[cfg(not(target_arch = "wasm32"))]
-impl Rand {
-    #[inline]
-    pub fn gen_id(&mut self) -> i32 {
-        use nanorand::Rng;
-        (self.0.generate::<u32>() % 10_000 + 1) as _
+    use xitca_http::{
+        bytes::BytesMut,
+        util::middleware::context::{Context, ContextBuilder},
+    };
+
+    use super::*;
+
+    use crate::db::{self, Client};
+
+    pub const DB_URL: &str = "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world";
+
+    #[derive(Default)]
+    pub struct Rand(nanorand::WyRand);
+
+    impl Rand {
+        #[inline]
+        pub fn gen_id(&mut self) -> i32 {
+            use nanorand::Rng;
+            (self.0.generate::<u32>() % 10_000 + 1) as _
+        }
+    }
+
+    pub type Ctx<'a, Req> = Context<'a, Req, State>;
+
+    pub struct State {
+        pub client: Client,
+        pub write_buf: RefCell<BytesMut>,
+    }
+
+    pub fn context_mw(
+    ) -> ContextBuilder<impl Fn() -> Pin<Box<dyn Future<Output = HandleResult<State>>>>> {
+        ContextBuilder::new(|| {
+            Box::pin(async {
+                db::create(DB_URL).await.map(|client| State {
+                    client,
+                    write_buf: RefCell::new(BytesMut::new()),
+                })
+            }) as _
+        })
     }
 }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub use non_wasm::*;

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

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

+ 4 - 4
frameworks/Rust/xitca-web/xitca-web-wasm.dockerfile

@@ -11,21 +11,21 @@ COPY / ./
 RUN curl -LSs "https://github.com/bytecodealliance/wasmtime/releases/download/v${WASMTIME_VERSION}/wasmtime-v${WASMTIME_VERSION}-$(uname -m)-linux.tar.xz" | \
 tar --strip-components=1 -Jx && \
 rustup target add ${WASM_TARGET} && \
-cargo build --bin xitca-web-wasm --features serde,web --release --target ${WASM_TARGET}
+cargo build --bin xitca-web-wasm --features web --release --target ${WASM_TARGET}
 
 
 FROM ubuntu:22.04
 
 ARG WASM_TARGET
+ARG BENCHMARK_ENV
+ARG TFB_TEST_DATABASE
+ARG TFB_TEST_NAME
 
 COPY --from=compile \
 /tmp/target/${WASM_TARGET}/release/xitca-web-wasm.wasm \
 /tmp/wasmtime \
 /opt/xitca-web-wasm/
 EXPOSE 8080
-ARG BENCHMARK_ENV
-ARG TFB_TEST_DATABASE
-ARG TFB_TEST_NAME
 
 CMD /opt/xitca-web-wasm/wasmtime run /opt/xitca-web-wasm/xitca-web-wasm.wasm \
 --wasm-features=threads \

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

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