From 593fcc08ea0d54cfa825c22a672c492606234219 Mon Sep 17 00:00:00 2001 From: bobozhengsir Date: Wed, 25 Oct 2023 15:46:34 +0800 Subject: [PATCH] feat(volo-http): optimize code by afit & rpitit --- Cargo.lock | 224 ++++++----------------------- examples/src/http/http.rs | 39 ----- volo-http/Cargo.toml | 16 +-- volo-http/src/dispatch.rs | 41 +++--- volo-http/src/extract.rs | 22 +-- volo-http/src/handler.rs | 45 +++--- volo-http/src/layer.rs | 28 ++-- volo-http/src/lib.rs | 4 +- volo-http/src/request.rs | 36 +++-- volo-http/src/route.rs | 293 ++++++++++++++------------------------ volo-http/src/server.rs | 5 +- 11 files changed, 222 insertions(+), 531 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2dc49f59..ca4e00fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,9 +179,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bit-set" @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" dependencies = [ "clap_builder", "clap_derive", @@ -270,9 +270,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" dependencies = [ "anstream", "anstyle", @@ -283,9 +283,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck 0.4.1", "proc-macro2", @@ -295,9 +295,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -317,7 +317,6 @@ dependencies = [ ] [[package]] -<<<<<<< HEAD name = "concurrent-queue" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -327,8 +326,6 @@ dependencies = [ ] [[package]] -======= ->>>>>>> add graceful shutdown name = "core-foundation" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -393,11 +390,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", -<<<<<<< HEAD "hashbrown 0.14.2", -======= - "hashbrown 0.14.1", ->>>>>>> add graceful shutdown "lock_api", "once_cell", "parking_lot_core 0.9.9", @@ -496,7 +489,6 @@ dependencies = [ [[package]] name = "event-listener" -<<<<<<< HEAD version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" @@ -509,9 +501,6 @@ dependencies = [ [[package]] name = "event-listener-strategy" version = "0.1.0" -======= -version = "2.5.3" ->>>>>>> add graceful shutdown source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15c97b4e30ea7e4b7e7b429d6e2d8510433ba8cee4e70dfb3243794e539d29fd" dependencies = [ @@ -525,17 +514,9 @@ version = "0.0.0" dependencies = [ "anyhow", "async-stream", -<<<<<<< HEAD -======= - "async-trait", "bytes", "http", -<<<<<<< HEAD - "hyper 1.0.0-rc.4", ->>>>>>> init -======= "hyper 1.0.0-rc.3", ->>>>>>> downgrade hyper version "lazy_static", "metainfo", "motore", @@ -751,15 +732,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -<<<<<<< HEAD version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" -======= -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" ->>>>>>> add graceful shutdown [[package]] name = "heck" @@ -982,11 +957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", -<<<<<<< HEAD "hashbrown 0.14.2", -======= - "hashbrown 0.14.1", ->>>>>>> add graceful shutdown ] [[package]] @@ -1126,18 +1097,6 @@ name = "memchr" version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" -<<<<<<< HEAD -======= - -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] ->>>>>>> add graceful shutdown [[package]] name = "memoffset" @@ -1183,9 +1142,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", @@ -1485,15 +1444,9 @@ dependencies = [ [[package]] name = "pilota-build" -<<<<<<< HEAD version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db92e95e898bc2793893d613b15afd72d6db9fa08874a15a439ae1e7d4f73d51" -======= -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c58d5b9c1797d6d37ce6dea975dfbf2ec3d12137a43451a0394600055932b8f" ->>>>>>> add graceful shutdown dependencies = [ "anyhow", "dashmap", @@ -1606,11 +1559,7 @@ checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" dependencies = [ "bit-set", "bit-vec", -<<<<<<< HEAD "bitflags 2.4.1", -======= - "bitflags 2.4.0", ->>>>>>> add graceful shutdown "lazy_static", "num-traits", "rand", @@ -1772,7 +1721,6 @@ dependencies = [ [[package]] name = "regex" -<<<<<<< HEAD version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" @@ -1781,16 +1729,6 @@ dependencies = [ "memchr", "regex-automata 0.4.3", "regex-syntax 0.8.2", -======= -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.1", - "regex-syntax 0.8.0", ->>>>>>> add graceful shutdown ] [[package]] @@ -1804,7 +1742,6 @@ dependencies = [ [[package]] name = "regex-automata" -<<<<<<< HEAD version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" @@ -1812,15 +1749,6 @@ dependencies = [ "aho-corasick", "memchr", "regex-syntax 0.8.2", -======= -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.0", ->>>>>>> add graceful shutdown ] [[package]] @@ -1837,15 +1765,9 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "regex-syntax" -<<<<<<< HEAD version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -======= -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" ->>>>>>> add graceful shutdown [[package]] name = "reqwest" @@ -1853,7 +1775,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", @@ -1889,17 +1811,16 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.20" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" dependencies = [ "cc", + "getrandom", "libc", - "once_cell", "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys", ] [[package]] @@ -1925,15 +1846,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -<<<<<<< HEAD version = "0.38.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" -======= -version = "0.38.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" ->>>>>>> add graceful shutdown dependencies = [ "bitflags 2.4.1", "errno", @@ -1944,9 +1859,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" dependencies = [ "log", "ring", @@ -1960,14 +1875,14 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", ] [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", "untrusted", @@ -2043,9 +1958,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", "untrusted", @@ -2079,15 +1994,9 @@ dependencies = [ [[package]] name = "serde_json" -<<<<<<< HEAD version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" -======= -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" ->>>>>>> init dependencies = [ "itoa", "ryu", @@ -2096,9 +2005,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] @@ -2189,9 +2098,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.5.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "strsim" @@ -2276,30 +2185,18 @@ dependencies = [ [[package]] name = "thiserror" -<<<<<<< HEAD version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" -======= -version = "1.0.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" ->>>>>>> add graceful shutdown dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -<<<<<<< HEAD version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" -======= -version = "1.0.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" ->>>>>>> add graceful shutdown dependencies = [ "proc-macro2", "quote", @@ -2409,21 +2306,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "2ef75d881185fd2df4a040793927c153d863651108a93c7e17a9e591baa95cc6" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.20.4", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -2435,20 +2332,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.0.2", -<<<<<<< HEAD "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "380f9e8120405471f7c9ad1860a713ef5ece6a670c7eae39225e477340f32fc4" dependencies = [ "indexmap 2.0.2", -======= ->>>>>>> add graceful shutdown "serde", "serde_spanned", "toml_datetime", @@ -2522,12 +2416,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -2596,9 +2490,9 @@ checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "update-informer" @@ -2620,7 +2514,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64 0.21.4", + "base64 0.21.5", "flate2", "log", "once_cell", @@ -2686,35 +2580,6 @@ dependencies = [ "tracing", ] -[[package]] -<<<<<<< HEAD -name = "volo" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4fcea6f3ec3afaf72af11044f85dc4f21fd8d75b80aa37ec7200bbd793dd16" -dependencies = [ - "async-broadcast", - "async-trait", - "dashmap", - "faststr", - "futures", - "lazy_static", - "libc", - "metainfo", - "motore", - "mur3", - "nix", - "once_cell", - "pin-project", - "rand", - "socket2 0.5.4", - "thiserror", - "tokio", - "tokio-stream", - "tower", - "tracing", -] - [[package]] name = "volo-build" version = "0.8.0" @@ -2815,7 +2680,6 @@ dependencies = [ name = "volo-http" version = "0.0.0" dependencies = [ - "async-trait", "bytes", "futures-util", "http", @@ -3099,15 +2963,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -<<<<<<< HEAD version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" -======= -version = "0.5.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" ->>>>>>> add graceful shutdown dependencies = [ "memchr", ] diff --git a/examples/src/http/http.rs b/examples/src/http/http.rs index e00b5690..56b2f564 100644 --- a/examples/src/http/http.rs +++ b/examples/src/http/http.rs @@ -8,34 +8,8 @@ use serde::{Deserialize, Serialize}; use volo_http::{ handler::HandlerService, request::Json, -<<<<<<< HEAD - route::{Route, Router, Server, ServiceLayerExt}, -<<<<<<< HEAD -======= -======= -use http::{Response, StatusCode}; -======= -use http::{Method, Response, StatusCode, Uri}; ->>>>>>> handler, extractor (#221) -use hyper::body::Incoming; -use motore::service::service_fn; -======= ->>>>>>> layer (#224) -use serde::{Deserialize, Serialize}; -use volo_http::{ - handler::HandlerService, - request::Json, -<<<<<<< HEAD - route::{Route, Router}, ->>>>>>> init -======= - route::{Route, Router, Server, ServiceLayerExt}, ->>>>>>> layer (#224) -======= route::{Route, Router, ServiceLayerExt}, server::Server, ->>>>>>> add graceful shutdown ->>>>>>> de495fd... add graceful shutdown HttpContext, }; @@ -113,23 +87,10 @@ async fn main() { .post(HandlerService::new(test)) .build(), ) -<<<<<<< HEAD -======= -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> handler, extractor (#221) -======= ->>>>>>> de495fd... add graceful shutdown - .layer(TimeoutLayer::new(Some(std::time::Duration::from_secs(1)))) - .serve(SocketAddr::from(([127, 0, 0, 1], 3000))) - .await - .unwrap(); -======= .layer(TimeoutLayer::new(Some(std::time::Duration::from_secs(1)))); let addr: SocketAddr = "[::]:9091".parse().unwrap(); let addr = volo::net::Address::from(addr); Server::new(app).run(addr).await.unwrap(); ->>>>>>> add graceful shutdown } diff --git a/volo-http/Cargo.toml b/volo-http/Cargo.toml index 09ff2432..259fc2f0 100644 --- a/volo-http/Cargo.toml +++ b/volo-http/Cargo.toml @@ -13,13 +13,13 @@ categories = ["asynchronous", "network-programming", "web-programming"] keywords = ["async", "http"] [dependencies] -volo = { version = "0.5", path = "../volo" } +volo = { version = "0.8", path = "../volo" } hyper = { version = "=1.0.0-rc.3", features = ["server", "http1", "http2"] } tokio = { version = "1", features = ["full"] } http-body-util = "=0.1.0-rc.2" http = { version = "0.2" } matchit = { version = "0.7" } -motore = { version = "0.3" } +motore.workspace = true tracing.workspace = true futures-util.workspace = true pin-project-lite = "0.2" @@ -28,19 +28,7 @@ serde_json = "1" thiserror.workspace = true mime = "0.3" serde = "1" -async-trait.workspace = true -<<<<<<< HEAD -======= -<<<<<<< HEAD -======= ->>>>>>> init -======= -async-trait.workspace = true ->>>>>>> handler, extractor (#221) -======= parking_lot.workspace = true ->>>>>>> add graceful shutdown ->>>>>>> de495fd... add graceful shutdown [dev-dependencies] serde = { version = "1", features = ["derive"] } diff --git a/volo-http/src/dispatch.rs b/volo-http/src/dispatch.rs index e593cd57..89be3936 100644 --- a/volo-http/src/dispatch.rs +++ b/volo-http/src/dispatch.rs @@ -1,4 +1,4 @@ -use std::{future::Future, marker::PhantomData}; +use std::marker::PhantomData; use http::Response; use hyper::body::Incoming; @@ -41,34 +41,27 @@ where S::Error: std::error::Error + Send + Sync + 'static, OB: Into, IB: FromRequest + Send, - for<'cx> ::FromFut<'cx>: std::marker::Send, { type Response = Response; type Error = DynError; - type Future<'cx> = impl Future> + Send + 'cx - where - HttpContext: 'cx, - Self: 'cx; - - fn call<'cx, 's>(&'s self, cx: &'cx mut HttpContext, req: Incoming) -> Self::Future<'cx> - where - 's: 'cx, - { - async move { - match IB::from(&*cx, req).await { - Ok(body) => self - .inner - .call(cx, body) - .await - .map(|resp| { - let (parts, body) = resp.into_parts(); - Response::from_parts(parts, body.into()) - }) - .map_err(|e| Box::new(e) as DynError), - Err(response) => Ok(response), - } + async fn call<'s, 'cx>( + &'s self, + cx: &'cx mut HttpContext, + req: Incoming, + ) -> Result { + match IB::from(&*cx, req).await { + Ok(body) => self + .inner + .call(cx, body) + .await + .map(|resp| { + let (parts, body) = resp.into_parts(); + Response::from_parts(parts, body.into()) + }) + .map_err(|e| Box::new(e) as DynError), + Err(response) => Ok(response), } } } diff --git a/volo-http/src/extract.rs b/volo-http/src/extract.rs index f7350f46..c2c58c4a 100644 --- a/volo-http/src/extract.rs +++ b/volo-http/src/extract.rs @@ -1,34 +1,38 @@ +use futures_util::Future; use http::{Method, Response, Uri}; use crate::{response::IntoResponse, HttpContext}; -#[async_trait::async_trait] pub trait FromContext: Sized { type Rejection: IntoResponse; - async fn from_context(context: &HttpContext) -> Result; + fn from_context( + context: &HttpContext, + ) -> impl Future> + Send; } -#[async_trait::async_trait] + impl FromContext for Option where T: FromContext, { type Rejection = Response<()>; // Infallible - async fn from_context(context: &HttpContext) -> Result { - Ok(T::from_context(context).await.ok()) + fn from_context( + context: &HttpContext, + ) -> impl Future> + Send { + async move { Ok(T::from_context(context).await.ok()) } } } -#[async_trait::async_trait] impl FromContext for Uri { type Rejection = Response<()>; // Infallible - async fn from_context(context: &HttpContext) -> Result { - Ok(context.uri.clone()) + fn from_context( + context: &HttpContext, + ) -> impl Future> + Send { + async move { Ok(context.uri.clone()) } } } -#[async_trait::async_trait] impl FromContext for Method { type Rejection = Response<()>; diff --git a/volo-http/src/handler.rs b/volo-http/src/handler.rs index aaf88fb9..961f7628 100644 --- a/volo-http/src/handler.rs +++ b/volo-http/src/handler.rs @@ -22,10 +22,7 @@ where } } pub trait Handler { - type Future<'r>: Future> + Send + 'r - where - Self: 'r; - fn call(self, context: &mut HttpContext, req: Incoming) -> Self::Future<'_>; + fn call(self, context: &mut HttpContext, req: Incoming) -> impl Future> + Send; } macro_rules! impl_handler { @@ -41,23 +38,18 @@ macro_rules! impl_handler { for<'r> $last: FromRequest + Send + 'r, Res: IntoResponse, { - type Future<'r> = impl Future> + Send + 'r - where Self: 'r; - - fn call(self, context: &mut HttpContext, req: Incoming) -> Self::Future<'_> { - async move { - $( - let $ty = match $ty::from_context(context).await { - Ok(value) => value, - Err(rejection) => return rejection.into_response(), - }; - )* - let $last = match $last::from(context, req).await { + async fn call(self, context: &mut HttpContext, req: Incoming) -> Response { + $( + let $ty = match $ty::from_context(context).await { Ok(value) => value, - Err(rejection) => return rejection, + Err(rejection) => return rejection.into_response(), }; - self($($ty,)* $last).await.into_response() - } + )* + let $last = match $last::from(context, req).await { + Ok(value) => value, + Err(rejection) => return rejection, + }; + self($($ty,)* $last).await.into_response() } } }; @@ -109,15 +101,12 @@ where { type Response = Response; type Error = http::Error; - type Future<'cx> = impl Future> + Send + 'cx - where - HttpContext: 'cx, - Self: 'cx; - fn call<'cx, 's>(&'s self, cx: &'cx mut HttpContext, req: Incoming) -> Self::Future<'cx> - where - 's: 'cx, - { - async move { Ok(self.h.clone().call(cx, req).await) } + async fn call<'s, 'cx>( + &'s self, + cx: &'cx mut HttpContext, + req: Incoming, + ) -> Result { + Ok(self.h.clone().call(cx, req).await) } } diff --git a/volo-http/src/layer.rs b/volo-http/src/layer.rs index 7c4c4e96..5b04772f 100644 --- a/volo-http/src/layer.rs +++ b/volo-http/src/layer.rs @@ -1,5 +1,3 @@ -use std::future::Future; - use http::{Method, Request, Response, StatusCode}; use http_body_util::Full; use hyper::body::{Bytes, Incoming}; @@ -79,27 +77,17 @@ where type Error = S::Error; - type Future<'cx> = impl Future> + Send + 'cx - where - HttpContext: 'cx, - Self: 'cx; - - fn call<'cx, 's>( + async fn call<'s, 'cx>( &'s self, cx: &'cx mut HttpContext, req: Request, - ) -> Self::Future<'cx> - where - 's: 'cx, - { - async move { - if let Err(status) = (self.f)(cx, &req) { - return Ok(Response::builder() - .status(status) - .body(Full::new(Bytes::new())) - .unwrap()); - } - self.service.call(cx, req).await + ) -> Result { + if let Err(status) = (self.f)(cx, &req) { + return Ok(Response::builder() + .status(status) + .body(Full::new(Bytes::new())) + .unwrap()); } + self.service.call(cx, req).await } } diff --git a/volo-http/src/lib.rs b/volo-http/src/lib.rs index df0c05b8..e80f2c97 100644 --- a/volo-http/src/lib.rs +++ b/volo-http/src/lib.rs @@ -63,7 +63,9 @@ where version: parts.version, headers: parts.headers, extensions: parts.extensions, - params: Params { inner: Vec::with_capacity(0) }, + params: Params { + inner: Vec::with_capacity(0), + }, }; s.call(&mut cx, req).await } diff --git a/volo-http/src/request.rs b/volo-http/src/request.rs index 03f58c2f..8b30aecf 100644 --- a/volo-http/src/request.rs +++ b/volo-http/src/request.rs @@ -12,22 +12,20 @@ use crate::{ }; pub trait FromRequest: Sized { - type FromFut<'cx>: Future>> + Send + 'cx - where - Self: 'cx; - - fn from(cx: &HttpContext, body: Incoming) -> Self::FromFut<'_>; + fn from( + cx: &HttpContext, + body: Incoming, + ) -> impl Future>> + Send; } impl FromRequest for T where T: FromContext, { - type FromFut<'cx> = impl Future>> + Send + 'cx - where - Self: 'cx; - - fn from(cx: &HttpContext, _body: Incoming) -> Self::FromFut<'_> { + fn from( + cx: &HttpContext, + _body: Incoming, + ) -> impl Future>> + Send { async move { match T::from_context(cx).await { Ok(value) => Ok(value), @@ -38,11 +36,10 @@ where } impl FromRequest for Incoming { - type FromFut<'cx> = impl Future>> + Send + 'cx - where - Self: 'cx; - - fn from(_cx: &HttpContext, body: Incoming) -> Self::FromFut<'_> { + fn from( + _cx: &HttpContext, + body: Incoming, + ) -> impl Future>> + Send { async { Ok(body) } } } @@ -50,11 +47,10 @@ impl FromRequest for Incoming { pub struct Json(pub T); impl FromRequest for Json { - type FromFut<'cx> = impl Future>> + Send + 'cx - where - Self: 'cx; - - fn from(cx: &HttpContext, body: Incoming) -> Self::FromFut<'_> { + fn from( + cx: &HttpContext, + body: Incoming, + ) -> impl Future>> + Send { async move { if !json_content_type(&cx.headers) { return Err(Response::builder() diff --git a/volo-http/src/route.rs b/volo-http/src/route.rs index e8070851..b7a5ac03 100644 --- a/volo-http/src/route.rs +++ b/volo-http/src/route.rs @@ -1,18 +1,7 @@ -use std::future::Future; - use http::{Method, Response, StatusCode}; use http_body_util::Full; -<<<<<<< HEAD -use hyper::{ - body::{Body, Bytes, Incoming}, - server::conn::http1, -}; -use motore::layer::Layer; -use tokio::net::TcpListener; -======= use hyper::body::{Bytes, Incoming}; use motore::layer::Layer; ->>>>>>> add graceful shutdown use crate::{ dispatch::DispatchService, request::FromRequest, response::RespBody, DynError, HttpContext, @@ -25,49 +14,24 @@ pub struct Router { inner: matchit::Router, } -<<<<<<< HEAD -======= -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= -impl Router { - pub fn build() -> RouterBuilder { - Default::default() - } -} - ->>>>>>> init -======= ->>>>>>> layer (#224) ->>>>>>> 9636f60... downgrade hyper version -impl motore::Service<(), (HttpContextInner, Incoming)> for Router { -======= impl motore::Service for Router { ->>>>>>> downgrade hyper version type Response = Response; type Error = DynError; - type Future<'cx> = impl Future> + Send + 'cx - where - HttpContext: 'cx, - Self: 'cx; - - fn call<'cx, 's>(&'s self, cx: &'cx mut HttpContext, req: Incoming) -> Self::Future<'cx> - where - 's: 'cx, - { - async move { - if let Ok(matched) = self.inner.at(cx.uri.path()) { - cx.params = matched.params.into(); - matched.value.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body(Full::new(Bytes::new()).into()) - .unwrap()) - } + async fn call<'s, 'cx>( + &'s self, + cx: &'cx mut HttpContext, + req: Incoming, + ) -> Result { + if let Ok(matched) = self.inner.at(cx.uri.path()) { + cx.params = matched.params.into(); + matched.value.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body(Full::new(Bytes::new()).into()) + .unwrap()) } } } @@ -108,51 +72,6 @@ impl ServiceLayerExt for S { } } -<<<<<<< HEAD -#[async_trait::async_trait] -pub trait Server { - async fn serve(self, addr: SocketAddr) -> Result<(), DynError>; -} -#[async_trait::async_trait] -impl Server for S -where - S: motore::Service> - + Clone - + Send - + Sync - + 'static, - OB: Body + Send + 'static, - ::Data: Send, - >::Error: Into, -{ - async fn serve(self, addr: SocketAddr) -> Result<(), DynError> { - let listener = TcpListener::bind(addr).await?; - - let service = self; - loop { - let s = service.clone(); - let (stream, peer) = listener.accept().await?; - - tokio::task::spawn(async move { - if let Err(err) = http1::Builder::new() - .serve_connection( - stream, - MotoreService { - peer: peer.into(), - inner: s, - }, - ) - .await - { - tracing::warn!("error serving connection: {:?}", err); - } - }); - } - } -} - -======= ->>>>>>> add graceful shutdown #[derive(Default, Clone)] pub struct Route { options: Option, @@ -181,112 +100,106 @@ impl motore::Service for Route { type Error = DynError; - type Future<'cx> = impl Future> + Send + 'cx - where - HttpContext: 'cx, - Self: 'cx; - - fn call<'cx, 's>(&'s self, cx: &'cx mut HttpContext, req: Incoming) -> Self::Future<'cx> - where - 's: 'cx, - { - async move { - match cx.method { - Method::GET => { - if let Some(service) = &self.get { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + async fn call<'s, 'cx>( + &'s self, + cx: &'cx mut HttpContext, + req: Incoming, + ) -> Result { + match cx.method { + Method::GET => { + if let Some(service) = &self.get { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::POST => { - if let Some(service) = &self.post { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::POST => { + if let Some(service) = &self.post { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::PUT => { - if let Some(service) = &self.put { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::PUT => { + if let Some(service) = &self.put { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::DELETE => { - if let Some(service) = &self.delete { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::DELETE => { + if let Some(service) = &self.delete { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::HEAD => { - if let Some(service) = &self.head { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::HEAD => { + if let Some(service) = &self.head { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::OPTIONS => { - if let Some(service) = &self.options { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::OPTIONS => { + if let Some(service) = &self.options { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::CONNECT => { - if let Some(service) = &self.connect { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::CONNECT => { + if let Some(service) = &self.connect { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::PATCH => { - if let Some(service) = &self.patch { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::PATCH => { + if let Some(service) = &self.patch { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - Method::TRACE => { - if let Some(service) = &self.trace { - service.call(cx, req).await - } else { - Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("".into()) - .unwrap()) - } + } + Method::TRACE => { + if let Some(service) = &self.trace { + service.call(cx, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("".into()) + .unwrap()) } - _ => Ok(Response::builder() - .status(StatusCode::METHOD_NOT_ALLOWED) - .body("".into()) - .unwrap()), } + _ => Ok(Response::builder() + .status(StatusCode::METHOD_NOT_ALLOWED) + .body("".into()) + .unwrap()), } } } diff --git a/volo-http/src/server.rs b/volo-http/src/server.rs index 219bf911..95d33673 100644 --- a/volo-http/src/server.rs +++ b/volo-http/src/server.rs @@ -9,8 +9,7 @@ use hyper::{ server::conn::http1, }; use motore::BoxError; -use tokio::sync::Notify; -use tracing::{info, trace, warn}; +use tracing::{info, trace}; use volo::net::{incoming::Incoming, MakeIncoming}; use crate::{DynError, HttpContext, MotoreService}; @@ -138,7 +137,7 @@ where exit_mark.store(true, Ordering::Relaxed); drop(rx); let _ = tx.send(()); - tx.closed().await; + let _ = tokio::time::timeout(Duration::from_secs(5), tx.closed()).await; Ok(()) } }