diff --git a/frameworks/Rust/xitca-web/Cargo.lock b/frameworks/Rust/xitca-web/Cargo.lock index 14daebadc05..71038073ca5 100644 --- a/frameworks/Rust/xitca-web/Cargo.lock +++ b/frameworks/Rust/xitca-web/Cargo.lock @@ -1,12 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "async-trait" -version = "0.1.82" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", @@ -39,59 +39,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "axum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" -dependencies = [ - "async-trait", - "axum-core", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper 1.0.1", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper 0.1.2", - "tower-layer", - "tower-service", -] +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -114,6 +64,18 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bb8" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b10cf871f3ff2ce56432fddc2615ac7acc3aa22ca321f8fea800846fbb32f188" +dependencies = [ + "async-trait", + "futures-util", + "parking_lot", + "tokio", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -135,6 +97,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -143,15 +111,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" -version = "1.1.18" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" dependencies = [ "shlex", ] @@ -230,6 +198,20 @@ dependencies = [ "r2d2", ] +[[package]] +name = "diesel-async" +version = "0.5.0" +source = "git+https://github.com/weiznich/diesel_async?rev=5b8262b#5b8262b86d8ed0e13adbbc4aee39500b9931ef8d" +dependencies = [ + "async-trait", + "bb8", + "diesel", + "futures-util", + "scoped-futures", + "tokio", + "tokio-postgres", +] + [[package]] name = "diesel_derives" version = "2.2.3" @@ -289,18 +271,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "filetime" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" -dependencies = [ - "cfg-if", - "libc", - "libredox", - "windows-sys 0.59.0", -] - [[package]] name = "fnv" version = "1.0.7" @@ -316,12 +286,39 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + [[package]] name = "futures-task" version = "0.3.30" @@ -335,6 +332,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-macro", + "futures-sink", "futures-task", "pin-project-lite", "pin-utils", @@ -364,9 +363,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "heck" @@ -389,15 +388,6 @@ dependencies = [ "digest", ] -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "http" version = "1.1.0" @@ -409,34 +399,11 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -472,11 +439,20 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8" +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libmimalloc-sys" @@ -488,17 +464,6 @@ dependencies = [ "libc", ] -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", - "redox_syscall", -] - [[package]] name = "lock_api" version = "0.4.12" @@ -515,12 +480,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "md-5" version = "0.10.6" @@ -546,12 +505,6 @@ dependencies = [ "libmimalloc-sys", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -569,7 +522,7 @@ dependencies = [ "hermit-abi", "libc", "wasi", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -583,18 +536,21 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "parking_lot" @@ -643,26 +599,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -675,6 +611,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "postgres-protocol" version = "0.6.7" @@ -695,9 +637,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02048d9e032fb3cc3413bbf7b83a15d84a5d419778e2628751896d856498eee9" +checksum = "f66ea23a2d0e5734297357705193335e0a957696f34bed2f2faefacb2fec336f" dependencies = [ "bytes", "fallible-iterator", @@ -715,9 +657,9 @@ dependencies = [ [[package]] name = "pq-sys" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92c30dd81695321846d4dfe348da67b1752ebb61cd1549d203a7b57e323c435" +checksum = "f6cc05d7ea95200187117196eee9edd0644424911821aeb28a18ce60ea0b8793" dependencies = [ "vcpkg", ] @@ -783,9 +725,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -796,12 +738,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - [[package]] name = "ryu" version = "1.0.18" @@ -816,41 +752,26 @@ checksum = "d4d5cd6d4f24f3ab107e949ab424738cf55b03deddce3b184c46985d7b1394ef" dependencies = [ "itoap", "ryu", - "sailfish-macros", "version_check", ] [[package]] -name = "sailfish-compiler" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7254ec7b3651f7f723a9073153f5dcddc1f2bf1bf8d1b23ac71c236ef6360d2b" -dependencies = [ - "filetime", - "home", - "memchr", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sailfish-macros" -version = "0.9.0" +name = "scheduled-thread-pool" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00812289fe1891c191cc2d9db461352fc410619e07ec2bb748faaa06412619d0" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "proc-macro2", - "sailfish-compiler", + "parking_lot", ] [[package]] -name = "scheduled-thread-pool" -version = "0.2.7" +name = "scoped-futures" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +checksum = "b1473e24c637950c9bd38763220bea91ec3e095a89f672bbd7a10d03e77ba467" dependencies = [ - "parking_lot", + "cfg-if", + "pin-utils", ] [[package]] @@ -891,16 +812,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_path_to_error" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" -dependencies = [ - "itoa", - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -977,7 +888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -1005,27 +916,15 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" - [[package]] name = "tinyvec" version = "1.8.0" @@ -1048,13 +947,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", + "bytes", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", - "windows-sys 0.52.0", + "windows-sys", +] + +[[package]] +name = "tokio-postgres" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b5d3742945bc7d7f210693b0c58ae542c6fd47b17adbbda0885f3dcb34a6bdb" +dependencies = [ + "async-trait", + "byteorder", + "bytes", + "fallible-iterator", + "futures-channel", + "futures-util", + "log", + "parking_lot", + "percent-encoding", + "phf", + "pin-project-lite", + "postgres-protocol", + "postgres-types", + "rand", + "socket2 0.5.7", + "tokio", + "tokio-util", + "whoami", ] [[package]] @@ -1073,55 +999,24 @@ dependencies = [ ] [[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.5.2" +name = "tokio-util" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ - "bitflags 2.6.0", "bytes", - "http", - "http-body", - "http-body-util", + "futures-core", + "futures-sink", "pin-project-lite", - "tower-layer", - "tower-service", + "tokio", ] -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-core", ] @@ -1131,9 +1026,6 @@ name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] [[package]] name = "typenum" @@ -1143,9 +1035,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" @@ -1155,18 +1047,18 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-properties" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "vcpkg" @@ -1186,6 +1078,88 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whoami" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +dependencies = [ + "redox_syscall", + "wasite", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1217,15 +1191,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -1292,9 +1257,8 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "xitca-codegen" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b646a30e6d44093beaae1bbe5dda664e8466d387663fc9d61c55fb2d78424" +version = "0.4.0" +source = "git+http://github.com/HFQR/xitca-web?rev=d3066ba#d3066ba5fc65e89c8a20890dd529f05818c853d6" dependencies = [ "quote", "syn", @@ -1302,9 +1266,8 @@ dependencies = [ [[package]] name = "xitca-http" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b5b036e32261c69d4f0e81bcb28c2e058ed569518959336fd75fc086208d3f" +version = "0.7.0" +source = "git+http://github.com/HFQR/xitca-web?rev=d3066ba#d3066ba5fc65e89c8a20890dd529f05818c853d6" dependencies = [ "futures-core", "http", @@ -1336,12 +1299,13 @@ dependencies = [ [[package]] name = "xitca-postgres" -version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=0cda225#0cda2254f98b40f21bc3170dd8983f16444f0bd0" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46046cb7a3d4fcfb5c858bab0651c73bb45c0c5f9f0f53dd4eb991f2d6e5d6f4" dependencies = [ "fallible-iterator", + "futures-core", "percent-encoding", - "phf", "postgres-protocol", "postgres-types", "tokio", @@ -1350,6 +1314,19 @@ dependencies = [ "xitca-unsafe-collection", ] +[[package]] +name = "xitca-postgres-diesel" +version = "0.1.0" +source = "git+https://github.com/fakeshadow/xitca-postgres-diesel?rev=ae93ee9#ae93ee95277e281fb87b351c42bfc2fc5a56703a" +dependencies = [ + "diesel", + "diesel-async", + "futures-core", + "scoped-futures", + "tokio", + "xitca-postgres", +] + [[package]] name = "xitca-router" version = "0.3.0" @@ -1361,9 +1338,8 @@ dependencies = [ [[package]] name = "xitca-server" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40a05f18780f1de843c5077583e4650b08d0518fcf9cf7948e28bc92e489736" +version = "0.5.0" +source = "git+http://github.com/HFQR/xitca-web?rev=d3066ba#d3066ba5fc65e89c8a20890dd529f05818c853d6" dependencies = [ "socket2 0.5.7", "tokio", @@ -1376,9 +1352,8 @@ dependencies = [ [[package]] name = "xitca-service" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b093ca75b264924773d53e445de08a937100bf1cbe4f62d4dc2c0d04a3ba4b" +version = "0.3.0" +source = "git+http://github.com/HFQR/xitca-web?rev=d3066ba#d3066ba5fc65e89c8a20890dd529f05818c853d6" [[package]] name = "xitca-unsafe-collection" @@ -1394,42 +1369,39 @@ name = "xitca-web" version = "0.1.0" dependencies = [ "atoi", - "axum", "diesel", + "diesel-async", "futures-core", - "http-body", + "futures-util", + "httparse", "mimalloc", "rand", "sailfish", "serde", "serde_json", "tokio", - "tower", - "tower-http", + "tokio-uring", "xitca-http", "xitca-io", "xitca-postgres", + "xitca-postgres-diesel", "xitca-server", "xitca-service", "xitca-unsafe-collection", - "xitca-web 0.6.2", + "xitca-web 0.7.0", ] [[package]] name = "xitca-web" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4f8f16791ea2a8845f617f1e87887f917835e0603d01f03a51e638b9613d0c" +version = "0.7.0" +source = "git+http://github.com/HFQR/xitca-web?rev=d3066ba#d3066ba5fc65e89c8a20890dd529f05818c853d6" dependencies = [ "futures-core", - "http-body", "pin-project-lite", "serde", "serde_json", "serde_urlencoded", "tokio", - "tower-layer", - "tower-service", "xitca-codegen", "xitca-http", "xitca-server", diff --git a/frameworks/Rust/xitca-web/Cargo.toml b/frameworks/Rust/xitca-web/Cargo.toml index 6c16d2d7a54..03d7098e796 100644 --- a/frameworks/Rust/xitca-web/Cargo.toml +++ b/frameworks/Rust/xitca-web/Cargo.toml @@ -19,9 +19,9 @@ path = "./src/main_wasm.rs" required-features = ["web"] [[bin]] -name = "xitca-web-axum" -path = "./src/main_axum.rs" -required-features = ["axum", "io-uring", "perf", "pg-sync", "template"] +name = "xitca-web-orm" +path = "./src/main_orm.rs" +required-features = ["pg-orm-async", "template", "web-codegen"] [[bin]] name = "xitca-web-sync" @@ -29,55 +29,56 @@ path = "./src/main_sync.rs" required-features = ["pg-orm", "template", "web-codegen"] [features] -# pg optional +# pg client optional pg = ["dep:xitca-postgres"] -# pg send/sync optional -pg-sync = ["dep:xitca-postgres"] -# pg orm optional -pg-orm = ["dep:diesel"] +# diesel orm optional +pg-orm = ["diesel/r2d2"] +# diesel async orm optional +pg-orm-async = ["dep:diesel", "dep:diesel-async", "dep:xitca-postgres-diesel", "futures-util"] # http router optional router = ["xitca-http/router"] # web optional web = ["dep:xitca-web"] -# web codegen optional +# web with macros optional web-codegen = ["xitca-web/codegen", "xitca-web/urlencoded"] # template optional template = ["dep:sailfish"] # io-uring optional -io-uring = ["xitca-http/io-uring", "xitca-server/io-uring"] -# axum optional -axum = ["dep:axum", "dep:http-body", "dep:tower", "dep:tower-http", "xitca-web/tower-http-compat" ] +io-uring = ["dep:tokio-uring", "xitca-http/io-uring", "xitca-server/io-uring"] # unrealistic performance optimization perf = ["dep:mimalloc", "tokio/parking_lot"] [dependencies] -xitca-http = "0.6" -xitca-io = "0.4" -xitca-server = "0.4" -xitca-service = "0.2" +xitca-http = "0.7" +xitca-io = "0.4.1" +xitca-server = "0.5" +xitca-service = "0.3" xitca-unsafe-collection = "0.2" atoi = "2" +httparse = "1" serde = { version = "1" } serde_json = { version = "1" } # web optional -xitca-web = { version = "0.6", features = ["json"], optional = true } +xitca-web = { version = "0.7", features = ["json"], optional = true } # raw-pg optional -xitca-postgres = { version = "0.1", optional = true } +xitca-postgres = { version = "0.2", optional = true } # orm optional -diesel = { version = "2", features = ["postgres", "r2d2"], optional = true } +diesel = { version = "2", features = ["postgres"], optional = true } + +# orm async optional +diesel-async = { version = "0.5", features = ["bb8", "postgres"], optional = true } +xitca-postgres-diesel = { version = "0.1", optional = true } +futures-util = { version = "0.3", default-features = false, optional = true } # template optional -sailfish = { version = "0.9", default-features = false, features = ["derive", "perf-inline"], optional = true } +sailfish = { version = "0.9", default-features = false, features = ["perf-inline"], optional = true } -# axum optional -axum = { version = "0.7", optional = true, default-features = false, features = ["json", "query"] } -http-body = { version = "1", optional = true } -tower = { version = "0.4", optional = true } -tower-http = { version = "0.5", features = ["set-header"], optional = true } +# io-uring optional +tokio-uring = { version = "0.5", optional = true } # perf optional mimalloc = { version = "0.1", default-features = false, optional = true } @@ -95,5 +96,13 @@ codegen-units = 1 panic = "abort" [patch.crates-io] -xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "0cda225" } +xitca-postgres-diesel = { git = "https://github.com/fakeshadow/xitca-postgres-diesel", rev = "ae93ee9" } + +diesel-async = { git = "https://github.com/weiznich/diesel_async", rev = "5b8262b" } mio = { git = "https://github.com/fakeshadow/mio", rev = "9bae6012b7ecfc6083350785f71a5e8265358178" } + +xitca-codegen = { git = "http://github.com/HFQR/xitca-web", rev = "d3066ba" } +xitca-http = { git = "http://github.com/HFQR/xitca-web", rev = "d3066ba" } +xitca-server = { git = "http://github.com/HFQR/xitca-web", rev = "d3066ba" } +xitca-service = { git = "http://github.com/HFQR/xitca-web", rev = "d3066ba" } +xitca-web = { git = "http://github.com/HFQR/xitca-web", rev = "d3066ba" } diff --git a/frameworks/Rust/xitca-web/benchmark_config.json b/frameworks/Rust/xitca-web/benchmark_config.json index f4c152eb729..973d1961472 100755 --- a/frameworks/Rust/xitca-web/benchmark_config.json +++ b/frameworks/Rust/xitca-web/benchmark_config.json @@ -35,14 +35,14 @@ "approach": "Stripped", "classification": "Platform", "database": "Postgres", - "framework": "xitca-web [unrealistic]", + "framework": "xitca-web", "language": "Rust", "orm": "Raw", "platform": "None", "webserver": "xitca-server", "os": "Linux", "database_os": "Linux", - "display_name": "xitca-web [unrealistic]", + "display_name": "xitca-web [iou]", "notes": "", "versus": "" }, @@ -53,7 +53,7 @@ "approach": "Realistic", "classification": "Micro", "database": "none", - "framework": "xitca-web [wasm]", + "framework": "xitca-web", "language": "rust", "orm": "raw", "platform": "none", @@ -64,7 +64,7 @@ "notes": "", "versus": "" }, - "axum": { + "orm": { "json_url": "/json", "plaintext_url": "/plaintext", "db_url": "/db", @@ -73,16 +73,16 @@ "update_url": "/updates?q=", "port": 8080, "approach": "realistic", - "classification": "micro", + "classification": "fullstack", "database": "postgres", - "framework": "axum [xitca]", + "framework": "xitca-web", "language": "rust", - "orm": "raw", + "orm": "full", "platform": "none", "webserver": "xitca-server", "os": "linux", "database_os": "linux", - "display_name": "axum [xitca]", + "display_name": "xitca-web [orm]", "notes": "", "versus": "" }, @@ -97,7 +97,7 @@ "approach": "realistic", "classification": "micro", "database": "postgres", - "framework": "xitca-web [sync]", + "framework": "xitca-web", "language": "rust", "orm": "full", "platform": "none", diff --git a/frameworks/Rust/xitca-web/src/db.rs b/frameworks/Rust/xitca-web/src/db.rs index 818804341b1..ad75d6f8bbe 100644 --- a/frameworks/Rust/xitca-web/src/db.rs +++ b/frameworks/Rust/xitca-web/src/db.rs @@ -1,101 +1,63 @@ -// clippy is dumb and have no idea what should be lazy or not -#![allow(clippy::unnecessary_lazy_evaluations)] +#[path = "./db_util.rs"] +mod db_util; -use xitca_io::bytes::BytesMut; -use xitca_postgres::{pipeline::Pipeline, pool::Pool, AsyncLendingIterator, Type}; +use std::cell::RefCell; + +use xitca_postgres::{ + iter::AsyncLendingIterator, pipeline::Pipeline, pool::Pool, statement::Statement, Execute, ExecuteMut, +}; use super::{ ser::{Fortune, Fortunes, World}, - util::{bulk_update_gen, HandleResult, Rand, DB_URL}, + util::{HandleResult, DB_URL}, }; +use db_util::{sort_update_params, update_query, Shared, FORTUNE_STMT, WORLD_STMT}; + pub struct Client { pool: Pool, - #[cfg(not(feature = "pg-sync"))] - shared: std::cell::RefCell, - #[cfg(feature = "pg-sync")] - shared: std::sync::Mutex, + shared: RefCell, updates: Box<[Box]>, } -type Shared = (Rand, BytesMut); - -const FORTUNE_SQL: &str = "SELECT * FROM fortune"; - -const FORTUNE_SQL_TYPES: &[Type] = &[]; - -const WORLD_SQL: &str = "SELECT * FROM world WHERE id=$1"; - -const WORLD_SQL_TYPES: &[Type] = &[Type::INT4]; - -fn update_query(num: usize) -> Box { - bulk_update_gen(|query| { - use std::fmt::Write; - (1..=num).fold((1, query), |(idx, query), _| { - write!(query, "(${}::int,${}::int),", idx, idx + 1).unwrap(); - (idx + 2, query) - }); - }) - .into_boxed_str() -} - pub async fn create() -> HandleResult { - let pool = Pool::builder(DB_URL).capacity(1).build()?; - - let shared = (Rand::default(), BytesMut::new()); - - let updates = core::iter::once(Box::from("")) - .chain((1..=500).map(update_query)) - .collect(); - Ok(Client { - pool, - #[cfg(not(feature = "pg-sync"))] - shared: std::cell::RefCell::new(shared), - #[cfg(feature = "pg-sync")] - shared: std::sync::Mutex::new(shared), - updates, + pool: Pool::builder(DB_URL).capacity(1).build()?, + shared: Default::default(), + updates: core::iter::once(Box::from("")) + .chain((1..=500).map(update_query)) + .collect(), }) } impl Client { - #[cfg(not(feature = "pg-sync"))] - fn shared(&self) -> std::cell::RefMut<'_, Shared> { - self.shared.borrow_mut() - } - - #[cfg(feature = "pg-sync")] - fn shared(&self) -> std::sync::MutexGuard<'_, Shared> { - self.shared.lock().unwrap() - } - pub async fn get_world(&self) -> HandleResult { let mut conn = self.pool.get().await?; - let stmt = conn.prepare(WORLD_SQL, WORLD_SQL_TYPES).await?; - let id = self.shared().0.gen_id(); - let mut res = conn.consume().query_raw(&stmt, [id])?; - let row = res.try_next().await?.ok_or_else(|| "World does not exist")?; - Ok(World::new(row.get_raw(0), row.get_raw(1))) + let stmt = WORLD_STMT.execute_mut(&mut conn).await?; + let id = self.shared.borrow_mut().0.gen_id(); + let mut res = stmt.bind([id]).query(&conn.consume()).await?; + let row = res.try_next().await?.ok_or("request World does not exist")?; + Ok(World::new(row.get(0), row.get(1))) } pub async fn get_worlds(&self, num: u16) -> HandleResult> { let len = num as usize; let mut conn = self.pool.get().await?; - let stmt = conn.prepare(WORLD_SQL, WORLD_SQL_TYPES).await?; + let stmt = WORLD_STMT.execute_mut(&mut conn).await?; let mut res = { - let (ref mut rng, ref mut buf) = *self.shared(); + let (ref mut rng, ref mut buf) = *self.shared.borrow_mut(); let mut pipe = Pipeline::with_capacity_from_buf(len, buf); - (0..num).try_for_each(|_| pipe.query_raw(&stmt, [rng.gen_id()]))?; - conn.consume().pipeline(pipe)? + (0..num).try_for_each(|_| stmt.bind([rng.gen_id()]).query_mut(&mut pipe))?; + pipe.query(&conn.consume())? }; let mut worlds = Vec::with_capacity(len); while let Some(mut item) = res.try_next().await? { while let Some(row) = item.try_next().await? { - worlds.push(World::new(row.get_raw(0), row.get_raw(1))) + worlds.push(World::new(row.get(0), row.get(1))) } } @@ -105,25 +67,24 @@ impl Client { pub async fn update(&self, num: u16) -> HandleResult> { let len = num as usize; - let update = self.updates.get(len).ok_or_else(|| "num out of bound")?; - + let update = self.updates.get(len).ok_or("request num is out of range")?; let mut conn = self.pool.get().await?; - let world_stmt = conn.prepare(WORLD_SQL, WORLD_SQL_TYPES).await?; - let update_stmt = conn.prepare(update, &[]).await?; + let world_stmt = WORLD_STMT.execute_mut(&mut conn).await?; + let update_stmt = Statement::named(update, &[]).execute_mut(&mut conn).await?; let mut params = Vec::with_capacity(len); let mut res = { - let (ref mut rng, ref mut buf) = *self.shared(); + let (ref mut rng, ref mut buf) = *self.shared.borrow_mut(); let mut pipe = Pipeline::with_capacity_from_buf(len + 1, buf); (0..num).try_for_each(|_| { let w_id = rng.gen_id(); let r_id = rng.gen_id(); params.push([w_id, r_id]); - pipe.query_raw(&world_stmt, [w_id]) + world_stmt.bind([w_id]).query_mut(&mut pipe) })?; - pipe.query_raw(&update_stmt, sort_update_params(¶ms))?; - conn.consume().pipeline(pipe)? + update_stmt.bind(sort_update_params(¶ms)).query_mut(&mut pipe)?; + pipe.query(&conn.consume())? }; let mut worlds = Vec::with_capacity(len); @@ -133,7 +94,7 @@ impl Client { while let Some(mut item) = res.try_next().await? { while let Some(row) = item.try_next().await? { let r_id = r_ids.next().unwrap()[1]; - worlds.push(World::new(row.get_raw(0), r_id)) + worlds.push(World::new(row.get(0), r_id)) } } @@ -145,11 +106,11 @@ impl Client { items.push(Fortune::new(0, "Additional fortune added at request time.")); let mut conn = self.pool.get().await?; - let stmt = conn.prepare(FORTUNE_SQL, FORTUNE_SQL_TYPES).await?; - let mut res = conn.consume().query_raw::<[i32; 0]>(&stmt, [])?; + let stmt = FORTUNE_STMT.execute_mut(&mut conn).await?; + let mut res = stmt.query(&conn.consume()).await?; while let Some(row) = res.try_next().await? { - items.push(Fortune::new(row.get_raw(0), row.get_raw::(1))); + items.push(Fortune::new(row.get(0), row.get::(1))); } items.sort_by(|it, next| it.message.cmp(&next.message)); @@ -157,33 +118,3 @@ impl Client { Ok(Fortunes::new(items)) } } - -fn sort_update_params(params: &[[i32; 2]]) -> impl ExactSizeIterator { - let mut params = params.to_owned(); - params.sort_by(|a, b| a[0].cmp(&b[0])); - - struct ParamIter(I); - - impl Iterator for ParamIter - where - I: Iterator, - { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - self.0.next() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } - } - - // impl depends on compiler optimization to flat Vec<[T]> to Vec when inferring - // it's size hint. possible to cause runtime panic. - impl ExactSizeIterator for ParamIter where I: Iterator {} - - ParamIter(params.into_iter().flatten()) -} diff --git a/frameworks/Rust/xitca-web/src/db_diesel_async.rs b/frameworks/Rust/xitca-web/src/db_diesel_async.rs new file mode 100644 index 00000000000..fdd93e43a74 --- /dev/null +++ b/frameworks/Rust/xitca-web/src/db_diesel_async.rs @@ -0,0 +1,153 @@ +use std::{ + io, + sync::{Arc, Mutex}, +}; + +use diesel::prelude::*; +use diesel_async::{ + pooled_connection::{bb8, AsyncDieselConnectionManager}, + RunQueryDsl, +}; +use futures_util::{ + future::join, + stream::{FuturesUnordered, TryStreamExt}, +}; +use xitca_postgres_diesel::AsyncPgConnection; + +use crate::{ + ser::{Fortune, Fortunes, World}, + util::{bulk_update_gen, Error, HandleResult, Rand, DB_URL}, +}; + +pub type Pool = Arc<_Pool>; + +pub struct _Pool { + pool: bb8::Pool, + rng: Mutex, +} + +pub async fn create() -> io::Result> { + bb8::Pool::builder() + .max_size(1) + .min_idle(Some(1)) + .test_on_check_out(false) + .build(AsyncDieselConnectionManager::new(DB_URL)) + .await + .map_err(io::Error::other) + .map(|pool| { + Arc::new(_Pool { + pool, + rng: Mutex::new(Rand::default()), + }) + }) +} + +#[cold] +#[inline(never)] +fn not_found() -> Error { + "world not found".into() +} + +impl _Pool { + pub async fn get_world(&self) -> HandleResult { + use crate::schema::world::dsl::*; + { + let w_id = self.rng.lock().unwrap().gen_id(); + let mut conn = self.pool.get().await?; + world.filter(id.eq(w_id)).load(&mut conn) + } + .await? + .pop() + .ok_or_else(not_found) + } + + pub async fn get_worlds(&self, num: u16) -> HandleResult> { + use crate::schema::world::dsl::*; + { + let mut conn = self.pool.get().await?; + let mut rng = self.rng.lock().unwrap(); + (0..num) + .map(|_| { + let w_id = rng.gen_id(); + let fut = world.filter(id.eq(w_id)).load::(&mut conn); + async { fut.await?.pop().ok_or_else(not_found) } + }) + .collect::>() + } + .try_collect() + .await + } + + pub async fn update(&self, num: u16) -> HandleResult> { + use crate::schema::world::dsl::*; + + let mut rngs = Vec::with_capacity(num as _); + + let (select_res, update_res) = { + let mut conn = self.pool.get().await?; + + let mut rng = self.rng.lock().unwrap(); + + let select = (0..num) + .map(|_| { + let w_id = rng.gen_id(); + let num = rng.gen_id(); + + rngs.push((w_id, num)); + + let fut = world.filter(id.eq(w_id)).load::(&mut conn); + + async move { + fut.await? + .pop() + .map(|mut w| { + w.randomnumber = num; + w + }) + .ok_or_else(not_found) + } + }) + .collect::>(); + + rngs.sort_by(|(a, _), (b, _)| a.cmp(b)); + + let update = diesel::sql_query(update_query(&rngs)).execute(&mut conn); + + join(select.try_collect::>(), update) + } + .await; + + update_res?; + let mut worlds = select_res?; + + worlds.sort_by_key(|w| w.id); + + Ok(worlds) + } + + pub async fn tell_fortune(&self) -> HandleResult { + use crate::schema::fortune::dsl::*; + + let mut items = { + let mut conn = self.pool.get().await?; + fortune.load::(&mut conn) + } + .await?; + + items.push(Fortune::new(0, "Additional fortune added at request time.")); + items.sort_by(|it, next| it.message.cmp(&next.message)); + + Ok(Fortunes::new(items)) + } +} + +// diesel does not support high level bulk update api. use raw sql to bypass the limitation. +// relate discussion: https://github.com/diesel-rs/diesel/discussions/2879 +fn update_query(ids: &[(i32, i32)]) -> String { + bulk_update_gen(|query| { + use std::fmt::Write; + ids.iter().for_each(|(w_id, num)| { + write!(query, "({}::int,{}::int),", w_id, num).unwrap(); + }); + }) +} diff --git a/frameworks/Rust/xitca-web/src/db_unrealistic.rs b/frameworks/Rust/xitca-web/src/db_unrealistic.rs new file mode 100644 index 00000000000..7b04449a716 --- /dev/null +++ b/frameworks/Rust/xitca-web/src/db_unrealistic.rs @@ -0,0 +1,130 @@ +//! this module is unrealistic. related issue: +//! https://github.com/TechEmpower/FrameworkBenchmarks/issues/8790 + +#[path = "./db_util.rs"] +mod db_util; + +use std::cell::RefCell; + +use xitca_postgres::{iter::AsyncLendingIterator, pipeline::Pipeline, statement::Statement, Execute, ExecuteMut}; + +use super::{ + ser::{Fortune, Fortunes, World}, + util::{HandleResult, DB_URL}, +}; + +use db_util::{sort_update_params, update_query, Shared, FORTUNE_STMT, WORLD_STMT}; + +pub struct Client { + cli: xitca_postgres::Client, + shared: RefCell, + fortune: Statement, + world: Statement, + updates: Box<[Statement]>, +} + +pub async fn create() -> HandleResult { + let (cli, mut drv) = xitca_postgres::Postgres::new(DB_URL).connect().await?; + + tokio::task::spawn(tokio::task::unconstrained(async move { + while drv.try_next().await?.is_some() {} + HandleResult::Ok(()) + })); + + let world = WORLD_STMT.execute(&cli).await?.leak(); + let fortune = FORTUNE_STMT.execute(&cli).await?.leak(); + + let mut updates = vec![Statement::default()]; + + for update in (1..=500).map(update_query).into_iter() { + let stmt = Statement::named(&update, &[]).execute(&cli).await?.leak(); + updates.push(stmt); + } + + Ok(Client { + cli, + shared: Default::default(), + world, + fortune, + updates: updates.into_boxed_slice(), + }) +} + +impl Client { + pub async fn get_world(&self) -> HandleResult { + let id = self.shared.borrow_mut().0.gen_id(); + let mut res = self.world.bind([id]).query(&self.cli).await?; + let row = res.try_next().await?.ok_or("request World does not exist")?; + Ok(World::new(row.get(0), row.get(1))) + } + + pub async fn get_worlds(&self, num: u16) -> HandleResult> { + let len = num as usize; + + let mut res = { + let (ref mut rng, ref mut buf) = *self.shared.borrow_mut(); + let mut pipe = Pipeline::with_capacity_from_buf(len, buf); + (0..num).try_for_each(|_| self.world.bind([rng.gen_id()]).query_mut(&mut pipe))?; + pipe.query(&self.cli)? + }; + + let mut worlds = Vec::with_capacity(len); + + while let Some(mut item) = res.try_next().await? { + while let Some(row) = item.try_next().await? { + worlds.push(World::new(row.get(0), row.get(1))) + } + } + + Ok(worlds) + } + + pub async fn update(&self, num: u16) -> HandleResult> { + let len = num as usize; + + let mut params = Vec::with_capacity(len); + + let mut res = { + let (ref mut rng, ref mut buf) = *self.shared.borrow_mut(); + let mut pipe = Pipeline::with_capacity_from_buf(len + 1, buf); + (0..num).try_for_each(|_| { + let w_id = rng.gen_id(); + let r_id = rng.gen_id(); + params.push([w_id, r_id]); + self.world.bind([w_id]).query_mut(&mut pipe) + })?; + self.updates[len] + .bind(sort_update_params(¶ms)) + .query_mut(&mut pipe)?; + pipe.query(&self.cli)? + }; + + let mut worlds = Vec::with_capacity(len); + + let mut r_ids = params.into_iter(); + + while let Some(mut item) = res.try_next().await? { + while let Some(row) = item.try_next().await? { + let r_id = r_ids.next().unwrap()[1]; + worlds.push(World::new(row.get(0), r_id)) + } + } + + Ok(worlds) + } + + pub async fn tell_fortune(&self) -> HandleResult { + let mut items = Vec::with_capacity(32); + items.push(Fortune::new(0, "Additional fortune added at request time.")); + + let mut res = self.fortune.query(&self.cli).await?; + + while let Some(row) = res.try_next().await? { + items.push(Fortune::new(row.get(0), row.get::(1))); + } + + items.sort_by(|it, next| it.message.cmp(&next.message)); + + Ok(Fortunes::new(items)) + } +} diff --git a/frameworks/Rust/xitca-web/src/db_util.rs b/frameworks/Rust/xitca-web/src/db_util.rs new file mode 100644 index 00000000000..19879333427 --- /dev/null +++ b/frameworks/Rust/xitca-web/src/db_util.rs @@ -0,0 +1,53 @@ +use xitca_io::bytes::BytesMut; +use xitca_postgres::{ + statement::{Statement, StatementNamed}, + types::Type, +}; + +use crate::util::{bulk_update_gen, Rand}; + +pub(super) type Shared = (Rand, BytesMut); + +pub(super) const FORTUNE_STMT: StatementNamed = Statement::named("SELECT * FROM fortune", &[]); +pub(super) const WORLD_STMT: StatementNamed = Statement::named("SELECT * FROM world WHERE id=$1", &[Type::INT4]); + +pub(super) fn update_query(num: usize) -> Box { + bulk_update_gen(|query| { + use std::fmt::Write; + (1..=num).fold((1, query), |(idx, query), _| { + write!(query, "(${}::int,${}::int),", idx, idx + 1).unwrap(); + (idx + 2, query) + }); + }) + .into_boxed_str() +} + +pub(super) fn sort_update_params(params: &[[i32; 2]]) -> impl ExactSizeIterator { + let mut params = params.to_owned(); + params.sort_by(|a, b| a[0].cmp(&b[0])); + + struct ParamIter(I); + + impl Iterator for ParamIter + where + I: Iterator, + { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + } + + // impl depends on compiler optimization to flat Vec<[T]> to Vec when inferring + // it's size hint. possible to cause runtime panic. + impl ExactSizeIterator for ParamIter where I: Iterator {} + + ParamIter(params.into_iter().flatten()) +} diff --git a/frameworks/Rust/xitca-web/src/main.rs b/frameworks/Rust/xitca-web/src/main.rs index 710ff577586..b7389fbb821 100755 --- a/frameworks/Rust/xitca-web/src/main.rs +++ b/frameworks/Rust/xitca-web/src/main.rs @@ -5,18 +5,22 @@ mod util; use xitca_http::{ h1::RequestBody, http::{header::SERVER, StatusCode}, - util::service::{ - route::get, - router::{Router, RouterError}, + util::{ + middleware::context::{Context, ContextBuilder}, + service::{ + route::get, + router::{Router, RouterError}, + }, }, HttpServiceBuilder, }; use xitca_service::{fn_service, Service, ServiceExt}; +use db::Client; use ser::{error_response, IntoResponse, Message, Request, Response}; -use util::{context_mw, HandleResult, QueryParse, SERVER_HEADER_VALUE}; +use util::{HandleResult, QueryParse, State, SERVER_HEADER_VALUE}; -type Ctx<'a> = util::Ctx<'a, Request>; +type Ctx<'a> = Context<'a, Request, State>; fn main() -> std::io::Result<()> { let service = Router::new() @@ -27,7 +31,7 @@ fn main() -> std::io::Result<()> { .insert("/queries", get(fn_service(queries))) .insert("/updates", get(fn_service(updates))) .enclosed_fn(middleware) - .enclosed(context_mw()) + .enclosed(ContextBuilder::new(|| async { db::create().await.map(State::new) })) .enclosed(HttpServiceBuilder::h1().io_uring()); xitca_server::Builder::new() .bind("xitca-web", "0.0.0.0:8080", service)? diff --git a/frameworks/Rust/xitca-web/src/main_axum.rs b/frameworks/Rust/xitca-web/src/main_axum.rs deleted file mode 100644 index 02fdfba8a20..00000000000 --- a/frameworks/Rust/xitca-web/src/main_axum.rs +++ /dev/null @@ -1,150 +0,0 @@ -//! show case of axum running on proper thread per core server with io-uring enabled. - -#[global_allocator] -static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; - -mod db; -mod ser; -mod util; - -use std::sync::Arc; - -use axum::{ - extract::{Json, Query, State}, - http::{ - header::{HeaderValue, SERVER}, - StatusCode, - }, - response::{Html, IntoResponse, Response}, - routing::{get, Router}, -}; -use tower_http::set_header::SetResponseHeaderLayer; - -use crate::{db::Client, ser::Num, tower_compat::TowerHttp}; - -fn main() -> std::io::Result<()> { - let service = TowerHttp::service(|| async { - let cli = db::create().await?; - let service = Router::new() - .route("/plaintext", get(plain_text)) - .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( - SERVER, - HeaderValue::from_static("A"), - )); - Ok(service) - }); - xitca_server::Builder::new() - .bind("xitca-axum", "0.0.0.0:8080", service)? - .build() - .wait() -} - -async fn plain_text() -> &'static str { - "Hello, World!" -} - -async fn json() -> impl IntoResponse { - Json(ser::Message::new()) -} - -async fn db(State(cli): State>) -> impl IntoResponse { - cli.get_world().await.map(Json).map_err(Error) -} - -async fn fortunes(State(cli): State>) -> 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>, Query(Num(num)): Query) -> impl IntoResponse { - cli.get_worlds(num).await.map(Json).map_err(Error) -} - -async fn updates(State(cli): State>, Query(Num(num)): Query) -> impl IntoResponse { - cli.update(num).await.map(Json).map_err(Error) -} - -struct Error(util::Error); - -impl IntoResponse for Error { - fn into_response(self) -> Response { - let mut res = self.0.to_string().into_response(); - *res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - res - } -} - -// compat module between xitca-http and axum. -mod tower_compat { - use core::{cell::RefCell, fmt, future::Future, marker::PhantomData}; - - use std::net::SocketAddr; - - use http_body::Body; - use xitca_http::{ - bytes::Bytes, - h1::RequestBody, - http::{Request, RequestExt, Response}, - HttpServiceBuilder, - }; - use xitca_io::net::io_uring::TcpStream; - use xitca_service::{fn_build, middleware::UncheckedReady, ready::ReadyService, Service, ServiceExt}; - use xitca_web::service::tower_http_compat::{CompatReqBody, CompatResBody}; - - pub struct TowerHttp { - service: RefCell, - _p: PhantomData, - } - - impl TowerHttp { - pub fn service( - func: F, - ) -> impl Service, Error = impl fmt::Debug> - where - F: Fn() -> Fut + Send + Sync + Clone, - Fut: Future>, - S: tower::Service, ()>>, Response = Response>, - S::Error: fmt::Debug, - B: Body + Send + 'static, - { - fn_build(move |_| { - let func = func.clone(); - async move { - func().await.map(|service| TowerHttp { - service: RefCell::new(service), - _p: PhantomData, - }) - } - }) - .enclosed(UncheckedReady) - .enclosed(HttpServiceBuilder::h1().io_uring()) - } - } - - impl Service>> for TowerHttp - where - S: tower::Service, ()>>, Response = Response>, - { - type Response = Response>; - type Error = S::Error; - - async fn call(&self, req: Request>) -> Result { - let (parts, ext) = req.into_parts(); - let req = Request::from_parts(parts, CompatReqBody::new(ext, ())); - let fut = self.service.borrow_mut().call(req); - let (parts, body) = fut.await?.into_parts(); - Ok(Response::from_parts(parts, CompatResBody::new(body))) - } - } -} diff --git a/frameworks/Rust/xitca-web/src/main_iou.rs b/frameworks/Rust/xitca-web/src/main_iou.rs index f66eb8778e6..7dcf6d1a719 100644 --- a/frameworks/Rust/xitca-web/src/main_iou.rs +++ b/frameworks/Rust/xitca-web/src/main_iou.rs @@ -1,9 +1,12 @@ -// used as reference of if/how moving from epoll to io-uring(or mixture of the two) make sense for -// network io. +// reference of if/how moving from epoll to io-uring(or mixture of the two) make sense for network io. +// with comment on explaining why some practice are unrealistic +// custom global memory allocator don't affect real world performance in noticeable amount. +// in real world they should be used for reason like security, debug/profiling capability etc. #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; +#[path = "db_unrealistic.rs"] mod db; mod ser; mod util; @@ -11,53 +14,138 @@ mod util; use std::{convert::Infallible, io}; use xitca_http::{ - body::ResponseBody, - http::{self, header::SERVER, StatusCode}, - HttpServiceBuilder, + bytes::BufMutWriter, + h1::dispatcher_uring_unreal::{Dispatcher, Request, Response}, + http::StatusCode, }; -use xitca_service::{fn_service, ServiceExt}; +use xitca_io::net::io_uring::TcpStream; +use xitca_service::Service; -use self::{ - ser::{error_response, IntoResponse, Message, Request}, - util::{context_mw, Ctx, QueryParse, SERVER_HEADER_VALUE}, -}; +use self::{ser::Message, util::State}; fn main() -> io::Result<()> { - let service = fn_service(handler) - .enclosed(context_mw()) - .enclosed(HttpServiceBuilder::h1().io_uring()); - xitca_server::Builder::new() - .bind("xitca-iou", "0.0.0.0:8080", service)? - .build() - .wait() + let addr = "0.0.0.0:8080".parse().unwrap(); + + let cores = std::thread::available_parallelism().map(|num| num.get()).unwrap_or(56); + + let handle = core::iter::repeat_with(|| { + std::thread::spawn(move || { + tokio_uring::start(async { + let socket = tokio::net::TcpSocket::new_v4()?; + socket.set_reuseaddr(true)?; + // unrealistic due to following reason: + // 1. this only works good on unix system. + // 2. no resource distribution adjustment between sockets on different threads. causing uneven workload + // where some threads are idle while others busy. resulting in overall increased latency + socket.set_reuseport(true)?; + socket.bind(addr)?; + let listener = socket.listen(1024)?; + + let client = db::create().await.unwrap(); + + // unrealistic http dispatcher. no spec check. no security feature. + let service = Dispatcher::new(handler, State::new(client)); + + loop { + match listener.accept().await { + Ok((stream, _)) => { + let stream = stream.into_std()?; + let stream = TcpStream::from_std(stream); + let service = service.clone(); + tokio::task::spawn_local(async move { + let _ = service.call(stream).await; + }); + } + Err(e) => return Err(e), + }; + } + }) + }) + }) + .take(cores) + .collect::>(); + + // unrealistic due to no signal handling, not shutdown handling. when killing this process all resources that + // need clean async shutdown will be leaked. + for handle in handle { + handle.join().unwrap()?; + } + + Ok(()) } -async fn handler(ctx: Ctx<'_, Request>) -> Result, Infallible> { - let (req, state) = ctx.into_parts(); - let mut res = match req.uri().path() { - "/plaintext" => req.text_response().unwrap(), - "/json" => req.json_response(state, &Message::new()).unwrap(), +async fn handler<'h>(req: Request<'h, '_>, res: Response<'h>, state: &State) -> Response<'h, 3> { + // unrealistic due to no http method check + match req.path.unwrap_or("404") { + // unrealistic due to no dynamic path matching + "/plaintext" => { + // unrealistic due to no body streaming and no post processing. violating middleware feature of xitca-web + res.status(StatusCode::OK) + .header("content-type", "text/plain") + .header("server", "X") + // unrealistic content length header. + .header("content-length", "13") + .body_writer(|buf| Ok::<_, Infallible>(buf.extend_from_slice(b"Hello, World!"))) + .unwrap() + } + "/json" => res + .status(StatusCode::OK) + .header("content-type", "application/json") + .header("server", "X") + // unrealistic content length header. + .header("content-length", "27") + .body_writer(|buf| serde_json::to_writer(BufMutWriter(buf), &Message::new())) + .unwrap(), + // all database related categories are unrealistic. please reference db_unrealistic module for detail. + "/fortunes" => { + use sailfish::TemplateOnce; + let fortunes = state.client.tell_fortune().await.unwrap().render_once().unwrap(); + res.status(StatusCode::OK) + .header("content-type", "text/html; charset=utf-8") + .header("server", "X") + .body(fortunes.as_bytes()) + } "/db" => { + // unrealistic due to no error handling. any db/serialization error will cause process crash. + // the same goes for all following unwraps on database related functions. let world = state.client.get_world().await.unwrap(); - req.json_response(state, &world).unwrap() + json_response(res, state, &world) } - "/queries" => { - let num = req.uri().query().parse_query(); + p if p.starts_with("/queries") => { + let num = path_param(p); let worlds = state.client.get_worlds(num).await.unwrap(); - req.json_response(state, &worlds).unwrap() + json_response(res, state, &worlds) } - "/updates" => { - let num = req.uri().query().parse_query(); + p if p.starts_with("/updates") => { + let num = path_param(p); let worlds = state.client.update(num).await.unwrap(); - req.json_response(state, &worlds).unwrap() - } - "/fortunes" => { - use sailfish::TemplateOnce; - let fortunes = state.client.tell_fortune().await.unwrap().render_once().unwrap(); - req.html_response(fortunes).unwrap() + json_response(res, state, &worlds) } - _ => error_response(StatusCode::NOT_FOUND), + _ => res.status(StatusCode::NOT_FOUND).header("server", "X").body(&[]), + } +} + +fn json_response<'r, DB, T>(res: Response<'r>, state: &State, val: &T) -> Response<'r, 3> +where + T: serde::Serialize, +{ + let buf = &mut *state.write_buf.borrow_mut(); + serde_json::to_writer(BufMutWriter(buf), val).unwrap(); + let res = res + .status(StatusCode::OK) + .header("content-type", "application/json") + .header("server", "X") + .body(buf.as_ref()); + buf.clear(); + res +} + +fn path_param(query: &str) -> u16 { + use atoi::FromRadix10; + let q = if let Some(pos) = query.find("?q") { + u16::from_radix_10(query.split_at(pos + 3).1.as_ref()).0 + } else { + 1 }; - res.headers_mut().insert(SERVER, SERVER_HEADER_VALUE); - Ok(res.map(Into::into)) + q.clamp(1, 500) } diff --git a/frameworks/Rust/xitca-web/src/main_orm.rs b/frameworks/Rust/xitca-web/src/main_orm.rs new file mode 100644 index 00000000000..86e8037ac2e --- /dev/null +++ b/frameworks/Rust/xitca-web/src/main_orm.rs @@ -0,0 +1,67 @@ +mod db_diesel_async; +mod schema; +mod ser; +mod util; + +use serde::Serialize; +use xitca_web::{ + codegen::route, + handler::{html::Html, json::Json, query::Query, state::StateRef, text::Text}, + http::{header::SERVER, WebResponse}, + route::get, + App, +}; + +use db_diesel_async::Pool; +use ser::Num; +use util::{HandleResult, SERVER_HEADER_VALUE}; + +fn main() -> std::io::Result<()> { + App::new() + .with_async_state(db_diesel_async::create) + .at("/plaintext", get(Text("Hello, World!"))) + .at("/json", get(Json(ser::Message::new()))) + .at_typed(db) + .at_typed(fortunes) + .at_typed(queries) + .at_typed(updates) + .map(header) + .serve() + .disable_vectored_write() + .bind("0.0.0.0:8080")? + .run() + .wait() +} + +fn header(mut res: WebResponse) -> WebResponse { + res.headers_mut().insert(SERVER, SERVER_HEADER_VALUE); + res +} + +#[route("/db", method = get)] +async fn db(StateRef(pool): StateRef<'_, Pool>) -> HandleResult> { + pool.get_world().await.map(Json) +} + +#[route("/fortunes", method = get)] +async fn fortunes(StateRef(pool): StateRef<'_, Pool>) -> HandleResult> { + use sailfish::TemplateOnce; + let html = pool.tell_fortune().await?.render_once()?; + Ok(Html(html)) +} + +#[route("/queries", method = get)] +async fn queries( + Query(Num(num)): Query, + StateRef(pool): StateRef<'_, Pool>, +) -> HandleResult> { + pool.get_worlds(num).await.map(Json) +} + +#[route("/updates", method = get)] +async fn updates( + Query(Num(num)): Query, + StateRef(pool): StateRef<'_, Pool>, +) -> HandleResult> { + pool.update(num).await.map(Json) +} diff --git a/frameworks/Rust/xitca-web/src/ser.rs b/frameworks/Rust/xitca-web/src/ser.rs index 53dcff13cf0..3c630c54bc6 100644 --- a/frameworks/Rust/xitca-web/src/ser.rs +++ b/frameworks/Rust/xitca-web/src/ser.rs @@ -33,7 +33,7 @@ impl Message { pub struct Num(pub u16); -#[cfg_attr(feature = "pg-orm", derive(diesel::Queryable))] +#[cfg_attr(any(feature = "pg-orm", feature = "pg-orm-async"), derive(diesel::Queryable))] pub struct World { pub id: i32, pub randomnumber: i32, @@ -46,7 +46,7 @@ impl World { } } -#[cfg_attr(feature = "pg-orm", derive(diesel::Queryable))] +#[cfg_attr(any(feature = "pg-orm", feature = "pg-orm-async"), derive(diesel::Queryable))] pub struct Fortune { pub id: i32, pub message: Cow<'static, str>, @@ -62,16 +62,41 @@ impl Fortune { } } -// TODO: use another template engine with faster compile time.(preferably with no proc macro) -#[cfg_attr( - feature = "template", - derive(sailfish::TemplateOnce), - template(path = "fortune.stpl", rm_whitespace = true) -)] pub struct Fortunes { items: Vec, } +// this is roughly the code generated by sailfish::TemplateOnce macro. +// using the macro does not have any perf cost and this piece of code is expanded manually to speed up compile time of +// bench to reduce resource usage of bench runner +#[cfg(feature = "template")] +impl sailfish::TemplateOnce for Fortunes { + fn render_once(self) -> sailfish::RenderResult { + use sailfish::runtime::{Buffer, Render}; + + const PREFIX: &str = "\n\nFortunes\n\n\n\n"; + const SUFFIX: &str = "\n
idmessage
\n\n"; + + let mut buf = Buffer::with_capacity(1236); + + buf.push_str(PREFIX); + for item in self.items { + buf.push_str(""); + Render::render_escaped(&item.id, &mut buf)?; + buf.push_str(""); + Render::render_escaped(&item.message, &mut buf)?; + buf.push_str(""); + } + buf.push_str(SUFFIX); + + Ok(buf.into_string()) + } + + fn render_once_to(self, _: &mut sailfish::runtime::Buffer) -> Result<(), sailfish::runtime::RenderError> { + unimplemented!("") + } +} + impl Fortunes { #[inline] pub const fn new(items: Vec) -> Self { diff --git a/frameworks/Rust/xitca-web/src/util.rs b/frameworks/Rust/xitca-web/src/util.rs index 62888fb6c26..9183d067f5d 100755 --- a/frameworks/Rust/xitca-web/src/util.rs +++ b/frameworks/Rust/xitca-web/src/util.rs @@ -54,6 +54,15 @@ pub struct State { pub write_buf: RefCell, } +impl State { + pub fn new(client: DB) -> Self { + Self { + client, + write_buf: Default::default(), + } + } +} + #[cfg(not(target_arch = "wasm32"))] mod non_wasm { use rand::{rngs::SmallRng, Rng, SeedableRng}; @@ -72,37 +81,6 @@ mod non_wasm { self.0.gen_range(1..=10000) } } - - #[cfg(feature = "pg")] - mod pg_state { - use core::{cell::RefCell, future::Future, pin::Pin}; - - use xitca_http::{ - bytes::BytesMut, - util::middleware::context::{Context, ContextBuilder}, - }; - - use crate::{ - db::{self, Client}, - util::{HandleResult, State}, - }; - - pub type Ctx<'a, Req> = Context<'a, Req, State>; - - pub fn context_mw() -> ContextBuilder Pin>>>>> { - ContextBuilder::new(|| { - Box::pin(async { - db::create().await.map(|client| State { - client, - write_buf: RefCell::new(BytesMut::new()), - }) - }) as _ - }) - } - } - - #[cfg(feature = "pg")] - pub use pg_state::*; } #[cfg(not(target_arch = "wasm32"))] diff --git a/frameworks/Rust/xitca-web/xitca-web-axum.dockerfile b/frameworks/Rust/xitca-web/xitca-web-axum.dockerfile deleted file mode 100644 index 3c6271834ea..00000000000 --- a/frameworks/Rust/xitca-web/xitca-web-axum.dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM rust:1.81 - -ADD ./ /xitca-web -WORKDIR /xitca-web - -RUN cargo build --release --bin xitca-web-axum --features axum,io-uring,perf,pg-sync,template - -EXPOSE 8080 - -CMD ./target/release/xitca-web-axum diff --git a/frameworks/Rust/xitca-web/xitca-web-orm.dockerfile b/frameworks/Rust/xitca-web/xitca-web-orm.dockerfile new file mode 100644 index 00000000000..06e40825b00 --- /dev/null +++ b/frameworks/Rust/xitca-web/xitca-web-orm.dockerfile @@ -0,0 +1,10 @@ +FROM rust:1.81 + +ADD ./ /xitca-web +WORKDIR /xitca-web + +RUN cargo build --release --bin xitca-web-orm --features pg-orm-async,template,web-codegen + +EXPOSE 8080 + +CMD ./target/release/xitca-web-orm