From f05a8881e8354adea013be77a4225742125a0288 Mon Sep 17 00:00:00 2001 From: Pure White Date: Fri, 1 Sep 2023 12:48:58 +0800 Subject: [PATCH 01/10] fix: multiplex panic (#222) --- Cargo.lock | 2 +- volo-thrift/Cargo.toml | 2 +- volo-thrift/src/codec/default/mod.rs | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 208a4f51..36ba64ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2629,7 +2629,7 @@ version = "0.3.0" [[package]] name = "volo-thrift" -version = "0.7.1" +version = "0.7.2" dependencies = [ "anyhow", "async-trait", diff --git a/volo-thrift/Cargo.toml b/volo-thrift/Cargo.toml index f993817f..5e1143b7 100644 --- a/volo-thrift/Cargo.toml +++ b/volo-thrift/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "volo-thrift" -version = "0.7.1" +version = "0.7.2" edition.workspace = true homepage.workspace = true repository.workspace = true diff --git a/volo-thrift/src/codec/default/mod.rs b/volo-thrift/src/codec/default/mod.rs index 59a0850a..e2ecc0bf 100644 --- a/volo-thrift/src/codec/default/mod.rs +++ b/volo-thrift/src/codec/default/mod.rs @@ -134,6 +134,7 @@ impl Encoder cx.stats_mut().set_write_size(real_size); let write_result = (|| async { + self.linked_bytes.reset(); // then we reserve the size of the message in the linked bytes self.linked_bytes.reserve(malloc_size); // after that, we encode the message into the linked bytes @@ -160,8 +161,6 @@ impl Encoder // put write end here so we can also record the time of encode error cx.stats_mut().record_write_end_at(); - // finally, don't forget to reset the linked bytes - self.linked_bytes.reset(); match write_result { Ok(()) => Ok(()), Err(mut e) => { From ee94d931bd0a7b9fc526756caa48b44f2d6d0598 Mon Sep 17 00:00:00 2001 From: Pure White Date: Fri, 15 Sep 2023 00:03:36 +0800 Subject: [PATCH 02/10] feat: log more information on error --- Cargo.lock | 419 +++++++++--------- volo-thrift/Cargo.toml | 2 +- volo-thrift/src/codec/default/mod.rs | 2 +- volo-thrift/src/context.rs | 2 + volo-thrift/src/transport/multiplex/client.rs | 4 +- volo-thrift/src/transport/multiplex/server.rs | 8 +- volo-thrift/src/transport/pingpong/server.rs | 10 +- .../transport/pingpong/thrift_transport.rs | 9 +- volo/Cargo.toml | 2 +- volo/src/context.rs | 3 +- 10 files changed, 230 insertions(+), 231 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36ba64ef..f82a7a57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -43,24 +43,23 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -82,9 +81,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys", @@ -92,9 +91,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "async-broadcast" @@ -108,13 +107,13 @@ dependencies = [ [[package]] name = "async-recursion" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -136,18 +135,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -158,9 +157,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -179,9 +178,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "bit-set" @@ -206,9 +205,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "bumpalo" @@ -224,18 +223,18 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -248,32 +247,31 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets", ] [[package]] name = "clap" -version = "4.3.21" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" +checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.21" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", @@ -284,21 +282,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" @@ -377,9 +375,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.5.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", "hashbrown 0.14.0", @@ -443,9 +441,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -471,9 +469,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -524,9 +522,9 @@ checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "faststr" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2081e2d954d6a9ea1764b68f04286a2add012625cb6c96599da67016538d873a" +checksum = "284eac9300ad17d2492e1e87219768b8ab97fb2c74a61cdbc0ced31d3f711159" dependencies = [ "bytes", "serde", @@ -540,9 +538,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "miniz_oxide", @@ -629,7 +627,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -684,15 +682,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -746,6 +744,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "http" version = "0.2.9" @@ -776,9 +783,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -932,7 +939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.7", + "rustix 0.38.13", "windows-sys", ] @@ -945,6 +952,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -968,9 +984,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libm" @@ -1003,9 +1019,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "lock_api" @@ -1019,9 +1035,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "matchers" @@ -1040,9 +1056,9 @@ checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memoffset" @@ -1138,16 +1154,15 @@ checksum = "97af489e1e21b68de4c390ecca6703318bc1aa16e9733bcb62c089b73c6fbb1b" [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", "pin-utils", - "static_assertions", ] [[package]] @@ -1217,14 +1232,14 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -1321,12 +1336,12 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap 2.0.0", ] [[package]] @@ -1359,7 +1374,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -1396,16 +1411,16 @@ dependencies = [ [[package]] name = "pilota-build" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "802844684949a4f8fda3d0e3f591b3af56ac44a187f347e19c6375b082de2729" +checksum = "8151d64b6ecf41e035e151391b374810572f574c5ab272fa31b5222ff4476748" dependencies = [ "anyhow", "dashmap", "faststr", "fxhash", "heck 0.4.1", - "itertools", + "itertools 0.10.5", "lazy_static", "normpath", "paste", @@ -1421,7 +1436,7 @@ dependencies = [ "scoped-tls", "serde", "serde_yaml", - "syn 2.0.28", + "syn 2.0.33", "toml", "tracing", "tracing-subscriber", @@ -1453,14 +1468,14 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "pin-project-lite" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c516611246607d0c04186886dbb3a754368ef82c79e9827a802c6d836dd111c" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1496,9 +1511,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -1567,9 +1582,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1666,14 +1681,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.6", - "regex-syntax 0.7.4", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", ] [[package]] @@ -1687,13 +1702,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.4", + "regex-syntax 0.7.5", ] [[package]] @@ -1704,17 +1719,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -1743,7 +1758,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.22.6", + "webpki-roots 0.25.2", "winreg", ] @@ -1799,26 +1814,26 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.7" +version = "0.38.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.5", + "linux-raw-sys 0.4.7", "windows-sys", ] [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki 0.101.3", + "rustls-webpki 0.101.5", "sct", ] @@ -1828,14 +1843,14 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.100.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" dependencies = [ "ring", "untrusted", @@ -1843,9 +1858,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.3" +version = "0.101.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" dependencies = [ "ring", "untrusted", @@ -1937,29 +1952,29 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -2020,15 +2035,15 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -2051,9 +2066,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys", @@ -2065,12 +2080,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.10.0" @@ -2090,9 +2099,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" dependencies = [ "proc-macro2", "quote", @@ -2101,14 +2110,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.7", + "rustix 0.38.13", "windows-sys", ] @@ -2133,22 +2142,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -2178,11 +2187,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -2191,7 +2199,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.9", + "socket2 0.5.4", "tokio-macros", "windows-sys", ] @@ -2214,7 +2222,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -2255,9 +2263,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -2276,9 +2284,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.0.0", "serde", @@ -2340,7 +2348,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", ] [[package]] @@ -2402,9 +2410,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -2453,12 +2461,12 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "flate2", "log", "once_cell", "rustls", - "rustls-webpki 0.100.1", + "rustls-webpki 0.100.3", "serde", "serde_json", "url", @@ -2467,9 +2475,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -2496,7 +2504,7 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "volo" -version = "0.5.4" +version = "0.5.5" dependencies = [ "async-broadcast", "async-trait", @@ -2512,7 +2520,7 @@ dependencies = [ "once_cell", "pin-project", "rand", - "socket2 0.5.3", + "socket2 0.5.4", "thiserror", "tokio", "tokio-stream", @@ -2528,7 +2536,7 @@ dependencies = [ "async-trait", "dirs", "heck 0.4.1", - "itertools", + "itertools 0.11.0", "lazy_static", "nom", "normpath", @@ -2555,7 +2563,7 @@ dependencies = [ "clap", "colored", "heck 0.4.1", - "itertools", + "itertools 0.11.0", "lazy_static", "log", "normpath", @@ -2629,7 +2637,7 @@ version = "0.3.0" [[package]] name = "volo-thrift" -version = "0.7.2" +version = "0.7.3" dependencies = [ "anyhow", "async-trait", @@ -2664,9 +2672,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -2708,7 +2716,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", "wasm-bindgen-shared", ] @@ -2742,7 +2750,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.33", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2763,43 +2771,31 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" dependencies = [ - "webpki", + "rustls-webpki 0.100.3", ] [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.1", -] +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix 0.38.13", ] [[package]] @@ -2853,9 +2849,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -2868,60 +2864,61 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.4" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] diff --git a/volo-thrift/Cargo.toml b/volo-thrift/Cargo.toml index 5e1143b7..c29a9ed3 100644 --- a/volo-thrift/Cargo.toml +++ b/volo-thrift/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "volo-thrift" -version = "0.7.2" +version = "0.7.3" edition.workspace = true homepage.workspace = true repository.workspace = true diff --git a/volo-thrift/src/codec/default/mod.rs b/volo-thrift/src/codec/default/mod.rs index e2ecc0bf..6d14a6ca 100644 --- a/volo-thrift/src/codec/default/mod.rs +++ b/volo-thrift/src/codec/default/mod.rs @@ -165,7 +165,7 @@ impl Encoder Ok(()) => Ok(()), Err(mut e) => { let msg = format!( - ", rpcinfo: {:?}, encode real size: {}, malloc size: {}", + ", cx: {:?}, encode real size: {}, malloc size: {}", cx.rpc_info(), real_size, malloc_size diff --git a/volo-thrift/src/context.rs b/volo-thrift/src/context.rs index a480a4c7..6e773677 100644 --- a/volo-thrift/src/context.rs +++ b/volo-thrift/src/context.rs @@ -187,6 +187,7 @@ pub struct ServerCxInner { pub common_stats: CommonStats, } +#[derive(Debug)] pub struct ClientContext(pub(crate) RpcCx); newtype_impl_context!(ClientContext, Config, 0); @@ -243,6 +244,7 @@ thread_local! { pub(crate) static SERVER_CONTEXT_CACHE: std::cell::RefCell> = std::cell::RefCell::new(Vec::with_capacity(128)); } +#[derive(Debug)] pub struct ServerContext(pub(crate) RpcCx); impl Default for ServerContext { diff --git a/volo-thrift/src/transport/multiplex/client.rs b/volo-thrift/src/transport/multiplex/client.rs index 3617bb4f..6e2f6d67 100644 --- a/volo-thrift/src/transport/multiplex/client.rs +++ b/volo-thrift/src/transport/multiplex/client.rs @@ -158,8 +158,8 @@ where return Err(Error::Transport(pilota::thrift::TransportError::new( TransportErrorKind::EndOfFile, format!( - "an unexpected end of file from server, rpcinfo: {:?}", - cx.rpc_info + "an unexpected end of file from server, cx: {:?}", + cx ), ))); } diff --git a/volo-thrift/src/transport/multiplex/server.rs b/volo-thrift/src/transport/multiplex/server.rs index 235b0c9a..331c0f4b 100644 --- a/volo-thrift/src/transport/multiplex/server.rs +++ b/volo-thrift/src/transport/multiplex/server.rs @@ -54,7 +54,7 @@ pub async fn serve( Some((mi, mut cx, msg)) => { if let Err(e) = metainfo::METAINFO.scope(RefCell::new(mi), encoder.encode::(&mut cx, msg)).await { // log it - error!("[VOLO] server send response error: {:?}, rpcinfo: {:?}, peer_addr: {:?}", e, cx.rpc_info, peer_addr); + error!("[VOLO] server send response error: {:?}, cx: {:?}, peer_addr: {:?}", e, cx, peer_addr); stat_tracer.iter().for_each(|f| f(&cx)); return; } @@ -73,7 +73,7 @@ pub async fn serve( Some((mut cx, msg)) => { if let Err(e) = encoder.encode::(&mut cx, msg).await { // log it - error!("[VOLO] server send error error: {:?}, rpcinfo: {:?}, peer_addr: {:?}", e, cx.rpc_info, peer_addr); + error!("[VOLO] server send error error: {:?}, cx: {:?}, peer_addr: {:?}", e, cx, peer_addr); } stat_tracer.iter().for_each(|f| f(&cx)); return; @@ -111,9 +111,9 @@ pub async fn serve( // receives a message msg = decoder.decode(&mut cx) => { tracing::debug!( - "[VOLO] received message: {:?}, rpcinfo: {:?}, peer_addr: {:?}", + "[VOLO] received message: {:?}, cx: {:?}, peer_addr: {:?}", msg.as_ref().map(|msg| msg.as_ref().map(|msg| &msg.meta)), - cx.rpc_info, + cx, peer_addr ); match msg { diff --git a/volo-thrift/src/transport/pingpong/server.rs b/volo-thrift/src/transport/pingpong/server.rs index c21cbb1d..6e2789b8 100644 --- a/volo-thrift/src/transport/pingpong/server.rs +++ b/volo-thrift/src/transport/pingpong/server.rs @@ -66,9 +66,9 @@ pub async fn serve( out = decoder.decode(&mut cx) => out }; debug!( - "[VOLO] received message: {:?}, rpcinfo: {:?}, peer_addr: {:?}", + "[VOLO] received message: {:?}, cx: {:?}, peer_addr: {:?}", msg.as_ref().map(|msg| msg.as_ref().map(|msg| &msg.meta)), - cx.rpc_info, + cx, peer_addr ); @@ -100,7 +100,7 @@ pub async fn serve( result }.instrument(span_provider.on_encode(tracing_cx)).await { // log it - error!("[VOLO] server send response error: {:?}, rpcinfo: {:?}, peer_addr: {:?}", e, cx.rpc_info, peer_addr); + error!("[VOLO] server send response error: {:?}, cx: {:?}, peer_addr: {:?}", e, cx, peer_addr); stat_tracer.iter().for_each(|f| f(&cx)); return Err(()); } @@ -114,13 +114,13 @@ pub async fn serve( return Err(()); } Err(e) => { - error!("[VOLO] pingpong server decode error: {:?}, peer_addr: {:?}", e, peer_addr); + error!("[VOLO] pingpong server decode error: {:?}, cx: {:?}, peer_addr: {:?}", e, cx, peer_addr); cx.msg_type = Some(TMessageType::Exception); if !matches!(e, Error::Transport(_)) { let msg = ThriftMessage::mk_server_resp(&cx, Err::(e)) .unwrap(); if let Err(e) = encoder.encode(&mut cx, msg).await { - error!("[VOLO] server send error error: {:?}, rpcinfo: {:?}, peer_addr: {:?}", e, cx.rpc_info, peer_addr); + error!("[VOLO] server send error error: {:?}, cx: {:?}, peer_addr: {:?}", e, cx, peer_addr); } } stat_tracer.iter().for_each(|f| f(&cx)); diff --git a/volo-thrift/src/transport/pingpong/thrift_transport.rs b/volo-thrift/src/transport/pingpong/thrift_transport.rs index c0691d04..3cba2171 100644 --- a/volo-thrift/src/transport/pingpong/thrift_transport.rs +++ b/volo-thrift/src/transport/pingpong/thrift_transport.rs @@ -2,7 +2,6 @@ use std::sync::atomic::AtomicUsize; use pin_project::pin_project; use tokio::io::{AsyncRead, AsyncWrite}; -use volo::context::Context; use crate::{ codec::{Decoder, Encoder, MakeCodec}, @@ -92,7 +91,7 @@ where ) -> Result>, Error> { let thrift_msg = self.decoder.decode(cx).await.map_err(|e| { let mut e = e; - e.append_msg(&format!(", rpcinfo: {:?}", cx.rpc_info())); + e.append_msg(&format!(", cx: {:?}", cx)); tracing::error!("[VOLO] transport[{}] decode error: {}", self.id, e); e })?; @@ -100,15 +99,15 @@ where if let Some(ThriftMessage { meta, .. }) = &thrift_msg { if meta.seq_id != cx.seq_id { tracing::error!( - "[VOLO] transport[{}] seq_id not match: {} != {}, rpcinfo: {:?}", + "[VOLO] transport[{}] seq_id not match: {} != {}, cx: {:?}", self.id, meta.seq_id, cx.seq_id, - cx.rpc_info(), + cx, ); return Err(Error::Application(ApplicationError::new( ApplicationErrorKind::BAD_SEQUENCE_ID, - format!("seq_id not match, rpcinfo: {:?}", cx.rpc_info()), + format!("seq_id not match, cx: {:?}", cx), ))); } }; diff --git a/volo/Cargo.toml b/volo/Cargo.toml index f1be90fd..1665c4f9 100644 --- a/volo/Cargo.toml +++ b/volo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "volo" -version = "0.5.4" +version = "0.5.5" edition.workspace = true homepage.workspace = true repository.workspace = true diff --git a/volo/src/context.rs b/volo/src/context.rs index 5e1506f3..bd4950c5 100644 --- a/volo/src/context.rs +++ b/volo/src/context.rs @@ -37,13 +37,14 @@ macro_rules! newtype_impl_context { const DEFAULT_MAP_CAPACITY: usize = 10; +#[derive(Debug)] pub struct RpcCx { pub rpc_info: RpcInfo, pub inner: I, pub extensions: Extensions, } -#[derive(Default)] +#[derive(Default, Debug)] pub struct Extensions(TypeMap); impl std::ops::Deref for Extensions { From 5b06e2cb94e6ef94d600cb91969c9f7526f58940 Mon Sep 17 00:00:00 2001 From: Yanhao Date: Thu, 21 Sep 2023 13:51:26 +0800 Subject: [PATCH 03/10] support shutdown hooks (#228) * support shutdown hooks * fix: cargo fmt --- volo-thrift/src/server.rs | 28 +++++++++++++++++++ volo-thrift/src/transport/multiplex/client.rs | 5 +--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/volo-thrift/src/server.rs b/volo-thrift/src/server.rs index 865f3e12..42b94500 100644 --- a/volo-thrift/src/server.rs +++ b/volo-thrift/src/server.rs @@ -4,6 +4,7 @@ use std::{ time::Duration, }; +use futures::future::BoxFuture; use motore::{ layer::{Identity, Layer, Stack}, service::Service, @@ -42,6 +43,7 @@ pub struct Server { #[cfg(feature = "multiplex")] multiplex: bool, span_provider: SP, + shutdown_hooks: Vec BoxFuture<'static, ()>>>, _marker: PhantomData, } @@ -66,12 +68,25 @@ impl #[cfg(feature = "multiplex")] multiplex: false, span_provider: DefaultProvider {}, + shutdown_hooks: Vec::new(), _marker: PhantomData, } } } impl Server { + /// Register shutdown hook. + /// + /// Hook functions will be called just before volo's own gracefull existing code starts, + /// in reverse order of registration. + pub fn register_shutdown_hook( + mut self, + hook: impl FnOnce() -> BoxFuture<'static, ()> + 'static, + ) -> Self { + self.shutdown_hooks.push(Box::new(hook)); + self + } + /// Adds a new inner layer to the server. /// /// The layer's `Service` should be `Send + Sync + Clone + 'static`. @@ -92,6 +107,7 @@ impl Server { #[cfg(feature = "multiplex")] multiplex: self.multiplex, span_provider: self.span_provider, + shutdown_hooks: self.shutdown_hooks, _marker: PhantomData, } } @@ -116,6 +132,7 @@ impl Server { #[cfg(feature = "multiplex")] multiplex: self.multiplex, span_provider: self.span_provider, + shutdown_hooks: self.shutdown_hooks, _marker: PhantomData, } } @@ -144,6 +161,7 @@ impl Server { #[cfg(feature = "multiplex")] multiplex: self.multiplex, span_provider: self.span_provider, + shutdown_hooks: self.shutdown_hooks, _marker: PhantomData, } } @@ -291,6 +309,14 @@ impl Server { } } + if !self.shutdown_hooks.is_empty() { + info!("[VOLO] call shutdown hooks"); + + for hook in self.shutdown_hooks { + (hook)().await; + } + } + // received signal, graceful shutdown now info!("[VOLO] received signal, gracefully exiting now"); *exit_flag.write() = true; @@ -330,6 +356,7 @@ impl Server { stat_tracer: self.stat_tracer, multiplex, span_provider: self.span_provider, + shutdown_hooks: self.shutdown_hooks, _marker: PhantomData, } } @@ -343,6 +370,7 @@ impl Server { #[cfg(feature = "multiplex")] multiplex: self.multiplex, span_provider: provider, + shutdown_hooks: self.shutdown_hooks, _marker: PhantomData, } } diff --git a/volo-thrift/src/transport/multiplex/client.rs b/volo-thrift/src/transport/multiplex/client.rs index 6e2f6d67..e1068df9 100644 --- a/volo-thrift/src/transport/multiplex/client.rs +++ b/volo-thrift/src/transport/multiplex/client.rs @@ -157,10 +157,7 @@ where if !oneway { return Err(Error::Transport(pilota::thrift::TransportError::new( TransportErrorKind::EndOfFile, - format!( - "an unexpected end of file from server, cx: {:?}", - cx - ), + format!("an unexpected end of file from server, cx: {:?}", cx), ))); } } From b5ffc70a5aa335851f5da0eac86ea17111a01bcf Mon Sep 17 00:00:00 2001 From: Gwo Tzu-Hsing Date: Fri, 25 Aug 2023 14:54:24 +0800 Subject: [PATCH 04/10] init --- Cargo.lock | 99 ++++++++++++- examples/Cargo.toml | 10 ++ examples/src/http/http.rs | 63 +++++++++ rust-toolchain.toml | 2 +- volo-http/Cargo.toml | 20 ++- volo-http/src/dispatch.rs | 74 ++++++++++ volo-http/src/layer.rs | 105 ++++++++++++++ volo-http/src/lib.rs | 75 ++++++++++ volo-http/src/param.rs | 51 +++++++ volo-http/src/request.rs | 93 ++++++++++++ volo-http/src/response.rs | 79 +++++++++++ volo-http/src/route.rs | 287 ++++++++++++++++++++++++++++++++++++++ 12 files changed, 948 insertions(+), 10 deletions(-) create mode 100644 examples/src/http/http.rs create mode 100644 volo-http/src/dispatch.rs create mode 100644 volo-http/src/layer.rs create mode 100644 volo-http/src/param.rs create mode 100644 volo-http/src/request.rs create mode 100644 volo-http/src/response.rs create mode 100644 volo-http/src/route.rs diff --git a/Cargo.lock b/Cargo.lock index f82a7a57..6bc344d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -501,9 +501,14 @@ dependencies = [ "anyhow", "async-stream", "async-trait", + "bytes", + "http", + "hyper 1.0.0-rc.4", "lazy_static", "metainfo", + "motore", "pilota", + "serde", "tokio", "tokio-stream", "tracing", @@ -511,6 +516,7 @@ dependencies = [ "volo", "volo-gen", "volo-grpc", + "volo-http", "volo-thrift", ] @@ -775,6 +781,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ef12f041acdd397010e5fb6433270c147d3b8b2d0a840cd7fff8e531dca5c8" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body 1.0.0-rc.2", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -805,7 +834,7 @@ dependencies = [ "futures-util", "h2", "http", - "http-body", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -817,6 +846,27 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.0.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d280a71f348bcc670fc55b02b63c53a04ac0bf2daff2980795aeaf53edae10e6" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body 1.0.0-rc.2", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "tracing", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.1" @@ -825,7 +875,7 @@ checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", "http", - "hyper", + "hyper 0.14.27", "rustls", "tokio", "tokio-rustls", @@ -837,12 +887,30 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.27", "pin-project-lite", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.0.0" +source = "git+https://github.com/hyperium/hyper-util.git#f898015fc9eca9f459ddac521db278d904099e89" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "hyper 1.0.0-rc.4", + "once_cell", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1736,8 +1804,8 @@ dependencies = [ "futures-util", "h2", "http", - "http-body", - "hyper", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "ipnet", "js-sys", @@ -2609,8 +2677,8 @@ dependencies = [ "h2", "hex", "http", - "http-body", - "hyper", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-timeout", "matchit", "metainfo", @@ -2630,6 +2698,23 @@ dependencies = [ [[package]] name = "volo-http" version = "0.0.0" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body-util", + "hyper 1.0.0-rc.4", + "hyper-util", + "matchit", + "mime", + "motore", + "pin-project-lite", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] [[package]] name = "volo-macros" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 96c07038..7a0695a6 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -62,6 +62,10 @@ path = "src/unknown/thrift_server.rs" name = "unknown-thrift-client" path = "src/unknown/thrift_client.rs" +[[bin]] +name = "http" +path = "src/http/http.rs" + [dependencies] anyhow.workspace = true @@ -78,5 +82,11 @@ pilota.workspace = true volo = { path = "../volo" } volo-grpc = { path = "../volo-grpc" } volo-thrift = { path = "../volo-thrift" } +volo-http = { path = "../volo-http" } volo-gen = { path = "./volo-gen" } +bytes.workspace = true +http.workspace = true +hyper = { version = "1.0.0-rc.4", features = ["server", "http1", "http2"] } +motore.workspace = true +serde.workspace = true diff --git a/examples/src/http/http.rs b/examples/src/http/http.rs new file mode 100644 index 00000000..b8c883f0 --- /dev/null +++ b/examples/src/http/http.rs @@ -0,0 +1,63 @@ +use std::{convert::Infallible, net::SocketAddr}; + +use bytes::Bytes; +use http::{Response, StatusCode}; +use hyper::body::Incoming; +use motore::service::service_fn; +use serde::{Deserialize, Serialize}; +use volo_http::{ + request::Json, + route::{Route, Router}, + HttpContext, +}; + +async fn hello( + _cx: &mut HttpContext, + _request: Incoming, +) -> Result, Infallible> { + Ok(Response::new("hello, world")) +} + +async fn echo(cx: &mut HttpContext, _request: Incoming) -> Result, Infallible> { + if let Some(echo) = cx.params.get("echo") { + return Ok(Response::new(echo.clone())); + } + Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Bytes::new()) + .unwrap()) +} + +#[derive(Serialize, Deserialize, Debug)] +struct Person { + name: String, + age: u8, + phones: Vec, +} + +async fn json( + _cx: &mut HttpContext, + Json(request): Json, +) -> Result, Infallible> { + let first_phone = request + .phones + .get(0) + .map(|p| p.as_str()) + .unwrap_or("no number"); + println!( + "{} is {} years old, {}'s first phone number is {}", + request.name, request.age, request.name, first_phone + ); + Ok(Response::new(())) +} + +#[tokio::main(flavor = "multi_thread")] +async fn main() { + Router::build() + .route("/", Route::builder().get(service_fn(hello)).build()) + .route("/:echo", Route::builder().get(service_fn(echo)).build()) + .route("/user", Route::builder().post(service_fn(json)).build()) + .serve(SocketAddr::from(([127, 0, 0, 1], 3000))) + .await + .unwrap(); +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8e47c085..e396fef6 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] # TODO: we can remove this toolchain file when TAIT hits stable. # Related issue: https://github.com/rust-lang/rust/issues/63063. -channel = "nightly" +channel = "nightly-2023-06-20" diff --git a/volo-http/Cargo.toml b/volo-http/Cargo.toml index 1f384e27..898f86fb 100644 --- a/volo-http/Cargo.toml +++ b/volo-http/Cargo.toml @@ -12,6 +12,22 @@ readme = "README.md" categories = ["asynchronous", "network-programming", "web-programming"] keywords = ["async", "http"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +hyper = { version = "1.0.0-rc.4", features = ["server", "http1", "http2"] } +tokio = { version = "1", features = ["full"] } +http-body-util = "0.1.0-rc.3" +http = { version = "0.2" } +hyper-util = { git = "https://github.com/hyperium/hyper-util.git" } +matchit = { version = "0.7" } +motore = { version = "0.3" } +tracing.workspace = true +futures-util.workspace = true +pin-project-lite = "0.2" +bytes.workspace = true +serde_json = "1" +thiserror.workspace = true +mime = "0.3" +serde = "1" + +[dev-dependencies] +serde = { version = "1", features = ["derive"] } diff --git a/volo-http/src/dispatch.rs b/volo-http/src/dispatch.rs new file mode 100644 index 00000000..e593cd57 --- /dev/null +++ b/volo-http/src/dispatch.rs @@ -0,0 +1,74 @@ +use std::{future::Future, marker::PhantomData}; + +use http::Response; +use hyper::body::Incoming; + +use crate::{request::FromRequest, response::RespBody, DynError, HttpContext}; + +pub(crate) struct DispatchService { + inner: S, + _marker: PhantomData<(IB, OB)>, +} + +impl DispatchService { + pub(crate) fn new(service: S) -> Self { + Self { + inner: service, + _marker: PhantomData, + } + } +} + +impl Clone for DispatchService +where + S: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + _marker: PhantomData, + } + } +} + +unsafe impl Send for DispatchService where S: Send {} + +unsafe impl Sync for DispatchService where S: Sync {} + +impl motore::Service for DispatchService +where + S: motore::Service> + Send + Sync + 'static, + 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), + } + } + } +} diff --git a/volo-http/src/layer.rs b/volo-http/src/layer.rs new file mode 100644 index 00000000..7c4c4e96 --- /dev/null +++ b/volo-http/src/layer.rs @@ -0,0 +1,105 @@ +use std::future::Future; + +use http::{Method, Request, Response, StatusCode}; +use http_body_util::Full; +use hyper::body::{Bytes, Incoming}; + +use crate::HttpContext; + +pub trait Layer { + type Service: motore::Service>; + + fn layer(self, inner: S) -> Self::Service; +} + +pub trait LayerExt { + fn method( + self, + method: Method, + ) -> FilterLayer) -> Result<(), StatusCode>>> + where + Self: Sized, + { + self.filter(Box::new( + move |cx: &mut HttpContext, _: &Request| { + if cx.method == method { + Ok(()) + } else { + Err(StatusCode::METHOD_NOT_ALLOWED) + } + }, + )) + } + + fn filter(self, f: F) -> FilterLayer + where + Self: Sized, + F: Fn(&mut HttpContext, &Request) -> Result<(), StatusCode>, + { + FilterLayer { f } + } +} + +pub struct FilterLayer { + f: F, +} + +impl Layer for FilterLayer +where + S: motore::Service, Response = Response>> + + Send + + Sync + + 'static, + F: Fn(&mut HttpContext, &Request) -> Result<(), StatusCode> + Send + Sync, +{ + type Service = Filter; + + fn layer(self, inner: S) -> Self::Service { + Filter { + service: inner, + f: self.f, + } + } +} + +pub struct Filter { + service: S, + f: F, +} + +impl motore::Service> for Filter +where + S: motore::Service, Response = Response>> + + Send + + Sync + + 'static, + F: Fn(&mut HttpContext, &Request) -> Result<(), StatusCode> + Send + Sync, +{ + type Response = S::Response; + + type Error = S::Error; + + type Future<'cx> = impl Future> + Send + 'cx + where + HttpContext: 'cx, + Self: 'cx; + + fn call<'cx, 's>( + &'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 + } + } +} diff --git a/volo-http/src/lib.rs b/volo-http/src/lib.rs index 8b137891..c076c34c 100644 --- a/volo-http/src/lib.rs +++ b/volo-http/src/lib.rs @@ -1 +1,76 @@ +#![feature(impl_trait_in_assoc_type)] +pub(crate) mod dispatch; +pub mod layer; +pub mod param; +pub mod request; +pub mod response; +pub mod route; + +use std::{future::Future, net::SocketAddr}; + +use http::{Extensions, HeaderMap, HeaderValue, Method, Uri, Version}; +use hyper::{ + body::{Body, Incoming}, + Request, Response, +}; +use param::Params; + +pub type DynError = Box; + +pub struct HttpContextInner { + pub(crate) peer: SocketAddr, + + pub(crate) method: Method, + pub(crate) uri: Uri, + pub(crate) version: Version, + pub(crate) headers: HeaderMap, + pub(crate) extensions: Extensions, +} + +pub struct HttpContext { + pub peer: SocketAddr, + pub method: Method, + pub uri: Uri, + pub version: Version, + pub headers: HeaderMap, + pub extensions: Extensions, + + pub params: Params, +} + +#[derive(Clone)] +pub struct MotoreService { + peer: SocketAddr, + inner: S, +} + +impl hyper::service::Service> for MotoreService +where + OB: Body, + S: motore::Service<(), (HttpContextInner, Incoming), Response = Response> + Clone, + S::Error: Into, +{ + type Response = S::Response; + + type Error = S::Error; + + type Future = impl Future>; + + fn call(&self, req: Request) -> Self::Future { + let s = self.inner.clone(); + let peer = self.peer; + async move { + let (parts, req) = req.into_parts(); + let cx = HttpContextInner { + peer, + method: parts.method, + uri: parts.uri, + version: parts.version, + headers: parts.headers, + extensions: parts.extensions, + }; + s.call(&mut (), (cx, req)).await + } + } +} diff --git a/volo-http/src/param.rs b/volo-http/src/param.rs new file mode 100644 index 00000000..34d27614 --- /dev/null +++ b/volo-http/src/param.rs @@ -0,0 +1,51 @@ +use std::slice::Iter; + +use bytes::{BufMut, Bytes, BytesMut}; + +pub struct Params { + inner: Vec<(Bytes, Bytes)>, +} + +impl From> for Params { + fn from(params: matchit::Params) -> Self { + let mut inner = Vec::with_capacity(params.len()); + let mut capacity = 0; + for (k, v) in params.iter() { + capacity += k.len(); + capacity += v.len(); + } + + let mut buf = BytesMut::with_capacity(capacity); + + for (k, v) in params.iter() { + buf.put(k.as_bytes()); + let k = buf.split().freeze(); + buf.put(v.as_bytes()); + let v = buf.split().freeze(); + inner.push((k, v)); + } + + Self { inner } + } +} + +impl Params { + pub fn len(&self) -> usize { + self.inner.len() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn iter(&self) -> Iter<'_, (Bytes, Bytes)> { + self.inner.iter() + } + + pub fn get>(&self, k: K) -> Option<&Bytes> { + self.iter() + .filter(|(ik, _)| ik.as_ref() == k.as_ref()) + .map(|(_, v)| v) + .next() + } +} diff --git a/volo-http/src/request.rs b/volo-http/src/request.rs new file mode 100644 index 00000000..7891728b --- /dev/null +++ b/volo-http/src/request.rs @@ -0,0 +1,93 @@ +use bytes::Bytes; +use futures_util::Future; +use http::{header, HeaderMap, Response, StatusCode}; +use http_body_util::BodyExt; +use hyper::body::Incoming; +use serde::de::DeserializeOwned; + +use crate::{response::RespBody, HttpContext}; + +pub trait FromRequest: Sized { + type FromFut<'cx>: Future>> + Send + 'cx + where + Self: 'cx; + + fn from(cx: &HttpContext, body: Incoming) -> Self::FromFut<'_>; +} + +impl FromRequest for Incoming { + type FromFut<'cx> = impl Future>> + Send + 'cx + where + Self: 'cx; + + fn from(_cx: &HttpContext, body: Incoming) -> Self::FromFut<'_> { + async { Ok(body) } + } +} + +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<'_> { + async move { + if !json_content_type(&cx.headers) { + return Err(Response::builder() + .status(StatusCode::UNSUPPORTED_MEDIA_TYPE) + .body(Bytes::new().into()) + .unwrap()); + } + + match body.collect().await { + Ok(body) => { + let body = body.to_bytes(); + match serde_json::from_slice::(body.as_ref()) { + Ok(t) => Ok(Self(t)), + Err(e) => { + tracing::warn!("json serialization error {e}"); + Err(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Bytes::new().into()) + .unwrap()) + } + } + } + Err(e) => { + tracing::warn!("collect body error: {e}"); + Err(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Bytes::new().into()) + .unwrap()) + } + } + } + } +} + +fn json_content_type(headers: &HeaderMap) -> bool { + let content_type = if let Some(content_type) = headers.get(header::CONTENT_TYPE) { + content_type + } else { + return false; + }; + + let content_type = if let Ok(content_type) = content_type.to_str() { + content_type + } else { + return false; + }; + + let mime = if let Ok(mime) = content_type.parse::() { + mime + } else { + return false; + }; + + let is_json_content_type = mime.type_() == "application" + && (mime.subtype() == "json" || mime.suffix().map_or(false, |name| name == "json")); + + is_json_content_type +} diff --git a/volo-http/src/response.rs b/volo-http/src/response.rs new file mode 100644 index 00000000..76505198 --- /dev/null +++ b/volo-http/src/response.rs @@ -0,0 +1,79 @@ +use std::{ + pin::Pin, + task::{Context, Poll}, +}; + +use futures_util::{ready, stream}; +use http_body_util::{Full, StreamBody}; +use hyper::body::{Body, Bytes, Frame}; +use pin_project_lite::pin_project; + +use crate::DynError; + +pin_project! { + #[project = RespBodyProj] + pub enum RespBody { + Stream { + #[pin] inner: StreamBody, DynError>> + Send + Sync>>>, + }, + Full { + #[pin] inner: Full, + }, + } +} + +impl Body for RespBody { + type Data = Bytes; + + type Error = DynError; + + fn poll_frame( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll, Self::Error>>> { + match self.project() { + RespBodyProj::Stream { inner } => inner.poll_frame(cx), + RespBodyProj::Full { inner } => { + Poll::Ready(ready!(inner.poll_frame(cx)).map(|result| Ok(result.unwrap()))) + } + } + } +} + +impl From> for RespBody { + fn from(value: Full) -> Self { + Self::Full { inner: value } + } +} + +impl From for RespBody { + fn from(value: Bytes) -> Self { + Self::Full { + inner: Full::new(value), + } + } +} + +impl From for RespBody { + fn from(value: String) -> Self { + Self::Full { + inner: Full::new(value.into()), + } + } +} + +impl From<&'static str> for RespBody { + fn from(value: &'static str) -> Self { + Self::Full { + inner: Full::new(value.into()), + } + } +} + +impl From<()> for RespBody { + fn from(_: ()) -> Self { + Self::Full { + inner: Full::new(Bytes::new()), + } + } +} diff --git a/volo-http/src/route.rs b/volo-http/src/route.rs new file mode 100644 index 00000000..c039a2b9 --- /dev/null +++ b/volo-http/src/route.rs @@ -0,0 +1,287 @@ +use std::{future::Future, net::SocketAddr}; + +use http::{Method, Response, StatusCode}; +use http_body_util::Full; +use hyper::{ + body::{Bytes, Incoming}, + server::conn::http1, +}; +use hyper_util::rt::TokioIo; +use tokio::net::TcpListener; + +use crate::{ + dispatch::DispatchService, request::FromRequest, response::RespBody, DynError, HttpContext, + HttpContextInner, MotoreService, +}; + +pub type DynService = motore::BoxCloneService, DynError>; + +#[derive(Clone)] +pub struct Router { + inner: matchit::Router, +} + +impl Router { + pub fn build() -> RouterBuilder { + Default::default() + } +} + +impl motore::Service<(), (HttpContextInner, Incoming)> for Router { + type Response = Response; + + type Error = DynError; + + type Future<'cx> = impl Future> + Send + 'cx + where + HttpContextInner: 'cx, + Self: 'cx; + + fn call<'cx, 's>( + &'s self, + _cx: &'cx mut (), + cxreq: (HttpContextInner, Incoming), + ) -> Self::Future<'cx> + where + 's: 'cx, + { + async move { + let (cx, req) = cxreq; + if let Ok(matched) = self.inner.at(cx.uri.path()) { + let mut context = HttpContext { + peer: cx.peer, + method: cx.method, + uri: cx.uri.clone(), + version: cx.version, + headers: cx.headers, + extensions: cx.extensions, + params: matched.params.into(), + }; + matched.value.call(&mut context, req).await + } else { + Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body(Full::new(Bytes::new()).into()) + .unwrap()) + } + } + } +} + +#[derive(Default)] +pub struct RouterBuilder { + routes: matchit::Router, +} + +impl RouterBuilder { + pub fn new() -> Self { + Default::default() + } + + pub fn route(mut self, uri: R, route: S) -> Self + where + R: Into, + S: motore::Service, Error = DynError> + + Send + + Sync + + Clone + + 'static, + { + if let Err(e) = self.routes.insert(uri, motore::BoxCloneService::new(route)) { + panic!("routing error: {e}"); + } + self + } + + pub async fn serve(self, addr: SocketAddr) -> Result<(), DynError> { + let listener = TcpListener::bind(addr).await?; + let router = Router { inner: self.routes }; + + loop { + let s = router.clone(); + let (stream, peer) = listener.accept().await?; + + let io = TokioIo::new(stream); + + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, MotoreService { peer, inner: s }) + .await + { + tracing::warn!("error serving connection: {:?}", err); + } + }); + } + } +} + +#[derive(Default, Clone)] +pub struct Route { + options: Option, + get: Option, + post: Option, + put: Option, + delete: Option, + head: Option, + trace: Option, + connect: Option, + patch: Option, +} + +impl Route { + pub fn new() -> Self { + Default::default() + } + + pub fn builder() -> RouteBuilder { + RouteBuilder { route: Self::new() } + } +} + +impl motore::Service for Route { + 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 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::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::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::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::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()), + } + } + } +} + +macro_rules! impl_method_register { + ($( $method:ident ),*) => { + $( + pub fn $method(mut self, handler: S) -> Self + where + S: motore::Service> + + Send + + Sync + + Clone + + 'static, + S::Error: std::error::Error + Send + Sync, + OB: Into + 'static, + IB: FromRequest + Send + 'static, + { + self.route.$method = Some(motore::BoxCloneService::new(DispatchService::new(handler))); + self + } + )+ + }; +} + +pub struct RouteBuilder { + route: Route, +} + +impl RouteBuilder { + impl_method_register!(options, get, post, put, delete, head, trace, connect, patch); + + pub fn build(self) -> Route { + self.route + } +} From 2ffbbc54a0c7e7c147e24b914a2be0a747a13927 Mon Sep 17 00:00:00 2001 From: Zheng Li <875543533@qq.com> Date: Wed, 6 Sep 2023 15:54:30 +0800 Subject: [PATCH 05/10] handler, extractor (#221) * handler, extractor --- Cargo.lock | 1 + examples/src/http/http.rs | 25 +++++++- volo-http/Cargo.toml | 1 + volo-http/src/extract.rs | 38 ++++++++++++ volo-http/src/handler.rs | 123 ++++++++++++++++++++++++++++++++++++++ volo-http/src/lib.rs | 2 + volo-http/src/request.rs | 24 +++++++- volo-http/src/response.rs | 60 +++++++++++++++++++ 8 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 volo-http/src/extract.rs create mode 100644 volo-http/src/handler.rs diff --git a/Cargo.lock b/Cargo.lock index 6bc344d3..bf3dacaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2699,6 +2699,7 @@ dependencies = [ name = "volo-http" version = "0.0.0" dependencies = [ + "async-trait", "bytes", "futures-util", "http", diff --git a/examples/src/http/http.rs b/examples/src/http/http.rs index b8c883f0..fd99e1a9 100644 --- a/examples/src/http/http.rs +++ b/examples/src/http/http.rs @@ -1,11 +1,12 @@ use std::{convert::Infallible, net::SocketAddr}; use bytes::Bytes; -use http::{Response, StatusCode}; +use http::{Method, Response, StatusCode, Uri}; use hyper::body::Incoming; use motore::service::service_fn; use serde::{Deserialize, Serialize}; use volo_http::{ + handler::HandlerService, request::Json, route::{Route, Router}, HttpContext, @@ -51,12 +52,34 @@ async fn json( Ok(Response::new(())) } +async fn test( + u: Uri, + m: Method, + Json(request): Json, +) -> Result<&'static str, (StatusCode, &'static str)> { + println!("{u:?}"); + println!("{m:?}"); + println!("{request:?}"); + if u.to_string().ends_with("a") { + Ok("a") // http://localhost:3000/test?a=a + } else { + Err((StatusCode::BAD_REQUEST, "b")) // http://localhost:3000/test?a=bb + } +} + #[tokio::main(flavor = "multi_thread")] async fn main() { Router::build() .route("/", Route::builder().get(service_fn(hello)).build()) .route("/:echo", Route::builder().get(service_fn(echo)).build()) .route("/user", Route::builder().post(service_fn(json)).build()) + .route( + "/test", + Route::builder() + .get(HandlerService::new(test)) + .post(HandlerService::new(test)) + .build(), + ) .serve(SocketAddr::from(([127, 0, 0, 1], 3000))) .await .unwrap(); diff --git a/volo-http/Cargo.toml b/volo-http/Cargo.toml index 898f86fb..6f56dce4 100644 --- a/volo-http/Cargo.toml +++ b/volo-http/Cargo.toml @@ -28,6 +28,7 @@ serde_json = "1" thiserror.workspace = true mime = "0.3" serde = "1" +async-trait.workspace = true [dev-dependencies] serde = { version = "1", features = ["derive"] } diff --git a/volo-http/src/extract.rs b/volo-http/src/extract.rs new file mode 100644 index 00000000..f7350f46 --- /dev/null +++ b/volo-http/src/extract.rs @@ -0,0 +1,38 @@ +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; +} +#[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()) + } +} + +#[async_trait::async_trait] +impl FromContext for Uri { + type Rejection = Response<()>; // Infallible + + async fn from_context(context: &HttpContext) -> Result { + Ok(context.uri.clone()) + } +} + +#[async_trait::async_trait] +impl FromContext for Method { + type Rejection = Response<()>; + + async fn from_context(context: &HttpContext) -> Result { + Ok(context.method.clone()) + } +} diff --git a/volo-http/src/handler.rs b/volo-http/src/handler.rs new file mode 100644 index 00000000..aaf88fb9 --- /dev/null +++ b/volo-http/src/handler.rs @@ -0,0 +1,123 @@ +use std::{future::Future, marker::PhantomData}; + +use http::Response; +use hyper::body::Incoming; + +use crate::{ + extract::FromContext, + request::FromRequest, + response::{IntoResponse, RespBody}, + HttpContext, +}; + +impl Clone for HandlerService +where + H: Clone, +{ + fn clone(&self) -> Self { + Self { + h: self.h.clone(), + _mark: PhantomData, + } + } +} +pub trait Handler { + type Future<'r>: Future> + Send + 'r + where + Self: 'r; + fn call(self, context: &mut HttpContext, req: Incoming) -> Self::Future<'_>; +} + +macro_rules! impl_handler { + ( + [$($ty:ident),*], $last:ident + ) => { + #[allow(non_snake_case, unused_mut, unused_variables)] + impl Handler<($($ty,)* $last,)> for F + where + F: FnOnce($($ty,)* $last) -> Fut + Clone + Send, + Fut: Future + Send, + $( for<'r> $ty: FromContext + Send + 'r, )* + 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 { + Ok(value) => value, + Err(rejection) => return rejection, + }; + self($($ty,)* $last).await.into_response() + } + } + } + }; +} + +impl_handler!([], T1); +impl_handler!([T1], T2); +impl_handler!([T1, T2], T3); +impl_handler!([T1, T2, T3], T4); +impl_handler!([T1, T2, T3, T4], T5); +impl_handler!([T1, T2, T3, T4, T5], T6); +impl_handler!([T1, T2, T3, T4, T5, T6], T7); +impl_handler!([T1, T2, T3, T4, T5, T6, T7], T8); +impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8], T9); +impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10); +impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11); +impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12); +impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13); +impl_handler!( + [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], + T14 +); +impl_handler!( + [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], + T15 +); +impl_handler!( + [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], + T16 +); + +pub struct HandlerService { + h: H, + _mark: PhantomData, +} + +impl HandlerService { + pub fn new(h: H) -> Self { + Self { + h, + _mark: PhantomData, + } + } +} + +impl motore::Service for HandlerService +where + for<'r> H: Handler + Clone + Send + Sync + 'r, +{ + 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) } + } +} diff --git a/volo-http/src/lib.rs b/volo-http/src/lib.rs index c076c34c..bd5d3551 100644 --- a/volo-http/src/lib.rs +++ b/volo-http/src/lib.rs @@ -1,6 +1,8 @@ #![feature(impl_trait_in_assoc_type)] pub(crate) mod dispatch; +pub mod extract; +pub mod handler; pub mod layer; pub mod param; pub mod request; diff --git a/volo-http/src/request.rs b/volo-http/src/request.rs index 7891728b..03f58c2f 100644 --- a/volo-http/src/request.rs +++ b/volo-http/src/request.rs @@ -5,7 +5,11 @@ use http_body_util::BodyExt; use hyper::body::Incoming; use serde::de::DeserializeOwned; -use crate::{response::RespBody, HttpContext}; +use crate::{ + extract::FromContext, + response::{IntoResponse, RespBody}, + HttpContext, +}; pub trait FromRequest: Sized { type FromFut<'cx>: Future>> + Send + 'cx @@ -15,6 +19,24 @@ pub trait FromRequest: Sized { fn from(cx: &HttpContext, body: Incoming) -> Self::FromFut<'_>; } +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<'_> { + async move { + match T::from_context(cx).await { + Ok(value) => Ok(value), + Err(rejection) => Err(rejection.into_response()), + } + } + } +} + impl FromRequest for Incoming { type FromFut<'cx> = impl Future>> + Send + 'cx where diff --git a/volo-http/src/response.rs b/volo-http/src/response.rs index 76505198..dd3acf85 100644 --- a/volo-http/src/response.rs +++ b/volo-http/src/response.rs @@ -4,6 +4,7 @@ use std::{ }; use futures_util::{ready, stream}; +use http::{Response, StatusCode}; use http_body_util::{Full, StreamBody}; use hyper::body::{Body, Bytes, Frame}; use pin_project_lite::pin_project; @@ -77,3 +78,62 @@ impl From<()> for RespBody { } } } + +pub trait IntoResponse { + fn into_response(self) -> Response; +} + +impl IntoResponse for Response +where + T: Into, +{ + fn into_response(self) -> Response { + let (parts, body) = self.into_parts(); + Response::from_parts(parts, body.into()) + } +} + +impl IntoResponse for T +where + T: Into, +{ + fn into_response(self) -> Response { + Response::builder() + .status(StatusCode::OK) + .body(self.into()) + .unwrap() + } +} + +impl IntoResponse for Result +where + R: IntoResponse, + E: IntoResponse, +{ + fn into_response(self) -> Response { + match self { + Ok(value) => value.into_response(), + Err(err) => err.into_response(), + } + } +} + +impl IntoResponse for (StatusCode, T) +where + T: IntoResponse, +{ + fn into_response(self) -> Response { + let mut resp = self.1.into_response(); + *resp.status_mut() = self.0; + resp + } +} + +impl IntoResponse for StatusCode { + fn into_response(self) -> Response { + Response::builder() + .status(self) + .body(String::new().into()) + .unwrap() + } +} From c43d4287bd1d33ee69a8d9e2585cdcbb8c10051f Mon Sep 17 00:00:00 2001 From: Zheng Li <875543533@qq.com> Date: Mon, 11 Sep 2023 14:22:57 +0800 Subject: [PATCH 06/10] layer (#224) --- examples/src/http/http.rs | 15 +++++++--- volo-http/src/route.rs | 58 +++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/examples/src/http/http.rs b/examples/src/http/http.rs index fd99e1a9..c84686c8 100644 --- a/examples/src/http/http.rs +++ b/examples/src/http/http.rs @@ -3,12 +3,12 @@ use std::{convert::Infallible, net::SocketAddr}; use bytes::Bytes; use http::{Method, Response, StatusCode, Uri}; use hyper::body::Incoming; -use motore::service::service_fn; +use motore::{service::service_fn, timeout::TimeoutLayer}; use serde::{Deserialize, Serialize}; use volo_http::{ handler::HandlerService, request::Json, - route::{Route, Router}, + route::{Route, Router, Server, ServiceLayerExt}, HttpContext, }; @@ -69,8 +69,14 @@ async fn test( #[tokio::main(flavor = "multi_thread")] async fn main() { - Router::build() - .route("/", Route::builder().get(service_fn(hello)).build()) + Router::new() + .route( + "/", + Route::builder() + .get(service_fn(hello)) + .build() + .layer(TimeoutLayer::new(Some(std::time::Duration::from_secs(1)))), + ) .route("/:echo", Route::builder().get(service_fn(echo)).build()) .route("/user", Route::builder().post(service_fn(json)).build()) .route( @@ -80,6 +86,7 @@ async fn main() { .post(HandlerService::new(test)) .build(), ) + .layer(TimeoutLayer::new(Some(std::time::Duration::from_secs(1)))) .serve(SocketAddr::from(([127, 0, 0, 1], 3000))) .await .unwrap(); diff --git a/volo-http/src/route.rs b/volo-http/src/route.rs index c039a2b9..d7a5764c 100644 --- a/volo-http/src/route.rs +++ b/volo-http/src/route.rs @@ -3,10 +3,11 @@ use std::{future::Future, net::SocketAddr}; use http::{Method, Response, StatusCode}; use http_body_util::Full; use hyper::{ - body::{Bytes, Incoming}, + body::{Body, Bytes, Incoming}, server::conn::http1, }; use hyper_util::rt::TokioIo; +use motore::layer::Layer; use tokio::net::TcpListener; use crate::{ @@ -16,17 +17,11 @@ use crate::{ pub type DynService = motore::BoxCloneService, DynError>; -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Router { inner: matchit::Router, } -impl Router { - pub fn build() -> RouterBuilder { - Default::default() - } -} - impl motore::Service<(), (HttpContextInner, Incoming)> for Router { type Response = Response; @@ -68,12 +63,7 @@ impl motore::Service<(), (HttpContextInner, Incoming)> for Router { } } -#[derive(Default)] -pub struct RouterBuilder { - routes: matchit::Router, -} - -impl RouterBuilder { +impl Router { pub fn new() -> Self { Default::default() } @@ -87,18 +77,50 @@ impl RouterBuilder { + Clone + 'static, { - if let Err(e) = self.routes.insert(uri, motore::BoxCloneService::new(route)) { + if let Err(e) = self.inner.insert(uri, motore::BoxCloneService::new(route)) { panic!("routing error: {e}"); } self } +} + +pub trait ServiceLayerExt: Sized { + fn layer(self, l: L) -> L::Service + where + L: Layer; +} + +impl ServiceLayerExt for S { + fn layer(self, l: L) -> L::Service + where + L: Layer, + { + Layer::layer(l, self) + } +} - pub async fn serve(self, addr: SocketAddr) -> Result<(), DynError> { +#[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<(), (HttpContextInner, Incoming), Response = Response> + + 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 router = Router { inner: self.routes }; + let service = self; loop { - let s = router.clone(); + let s = service.clone(); let (stream, peer) = listener.accept().await?; let io = TokioIo::new(stream); From d8886632a0f8419aa5fcd68610a1ca2213b67fd7 Mon Sep 17 00:00:00 2001 From: bobozhengsir Date: Thu, 14 Sep 2023 16:52:51 +0800 Subject: [PATCH 07/10] downgrade hyper version --- Cargo.lock | 72 ++++++++++++++++++++++++------------------ examples/Cargo.toml | 2 +- volo-http/Cargo.toml | 6 ++-- volo-http/src/lib.rs | 30 +++++++----------- volo-http/src/param.rs | 2 +- volo-http/src/route.rs | 40 +++++++++-------------- 6 files changed, 73 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf3dacaa..9c747c3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,7 +503,7 @@ dependencies = [ "async-trait", "bytes", "http", - "hyper 1.0.0-rc.4", + "hyper 1.0.0-rc.3", "lazy_static", "metainfo", "motore", @@ -513,7 +513,7 @@ dependencies = [ "tokio-stream", "tracing", "tracing-subscriber", - "volo", + "volo 0.5.4", "volo-gen", "volo-grpc", "volo-http", @@ -793,9 +793,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.0-rc.3" +version = "0.1.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ef12f041acdd397010e5fb6433270c147d3b8b2d0a840cd7fff8e531dca5c8" +checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10" dependencies = [ "bytes", "futures-util", @@ -848,12 +848,13 @@ dependencies = [ [[package]] name = "hyper" -version = "1.0.0-rc.4" +version = "1.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d280a71f348bcc670fc55b02b63c53a04ac0bf2daff2980795aeaf53edae10e6" +checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092" dependencies = [ "bytes", "futures-channel", + "futures-core", "futures-util", "h2", "http", @@ -893,24 +894,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "hyper-util" -version = "0.0.0" -source = "git+https://github.com/hyperium/hyper-util.git#f898015fc9eca9f459ddac521db278d904099e89" -dependencies = [ - "futures-channel", - "futures-util", - "http", - "hyper 1.0.0-rc.4", - "once_cell", - "pin-project-lite", - "socket2 0.4.9", - "tokio", - "tower", - "tower-service", - "tracing", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -2596,6 +2579,35 @@ dependencies = [ "tracing", ] +[[package]] +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", +>>>>>>> downgrade hyper version + "thiserror", + "tokio", + "tokio-stream", + "tower", + "tracing", +] + [[package]] name = "volo-build" version = "0.6.2" @@ -2619,7 +2631,7 @@ dependencies = [ "syn 1.0.109", "tempfile", "url_path", - "volo", + "volo 0.5.4", "walkdir", ] @@ -2655,7 +2667,7 @@ dependencies = [ "futures", "pilota", "tokio", - "volo", + "volo 0.5.4", "volo-build", "volo-grpc", "volo-thrift", @@ -2692,7 +2704,7 @@ dependencies = [ "tower", "tracing", "tracing-subscriber", - "volo", + "volo 0.5.4", ] [[package]] @@ -2704,8 +2716,7 @@ dependencies = [ "futures-util", "http", "http-body-util", - "hyper 1.0.0-rc.4", - "hyper-util", + "hyper 1.0.0-rc.3", "matchit", "mime", "motore", @@ -2715,6 +2726,7 @@ dependencies = [ "thiserror", "tokio", "tracing", + "volo 0.5.5", ] [[package]] @@ -2744,7 +2756,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "volo", + "volo 0.5.4", ] [[package]] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 7a0695a6..d3a0d111 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -87,6 +87,6 @@ volo-http = { path = "../volo-http" } volo-gen = { path = "./volo-gen" } bytes.workspace = true http.workspace = true -hyper = { version = "1.0.0-rc.4", features = ["server", "http1", "http2"] } +hyper = { version = "1.0.0-rc.3", features = ["server", "http1", "http2"] } motore.workspace = true serde.workspace = true diff --git a/volo-http/Cargo.toml b/volo-http/Cargo.toml index 6f56dce4..d629fa00 100644 --- a/volo-http/Cargo.toml +++ b/volo-http/Cargo.toml @@ -13,11 +13,11 @@ categories = ["asynchronous", "network-programming", "web-programming"] keywords = ["async", "http"] [dependencies] -hyper = { version = "1.0.0-rc.4", features = ["server", "http1", "http2"] } +volo = { version = "0.5" } +hyper = { version = "=1.0.0-rc.3", features = ["server", "http1", "http2"] } tokio = { version = "1", features = ["full"] } -http-body-util = "0.1.0-rc.3" +http-body-util = "=0.1.0-rc.2" http = { version = "0.2" } -hyper-util = { git = "https://github.com/hyperium/hyper-util.git" } matchit = { version = "0.7" } motore = { version = "0.3" } tracing.workspace = true diff --git a/volo-http/src/lib.rs b/volo-http/src/lib.rs index bd5d3551..0aed4cee 100644 --- a/volo-http/src/lib.rs +++ b/volo-http/src/lib.rs @@ -9,7 +9,7 @@ pub mod request; pub mod response; pub mod route; -use std::{future::Future, net::SocketAddr}; +use std::future::Future; use http::{Extensions, HeaderMap, HeaderValue, Method, Uri, Version}; use hyper::{ @@ -17,21 +17,12 @@ use hyper::{ Request, Response, }; use param::Params; +use volo::net::Address; pub type DynError = Box; -pub struct HttpContextInner { - pub(crate) peer: SocketAddr, - - pub(crate) method: Method, - pub(crate) uri: Uri, - pub(crate) version: Version, - pub(crate) headers: HeaderMap, - pub(crate) extensions: Extensions, -} - pub struct HttpContext { - pub peer: SocketAddr, + pub peer: Address, pub method: Method, pub uri: Uri, pub version: Version, @@ -43,14 +34,14 @@ pub struct HttpContext { #[derive(Clone)] pub struct MotoreService { - peer: SocketAddr, - inner: S, + pub peer: Address, + pub inner: S, } impl hyper::service::Service> for MotoreService where OB: Body, - S: motore::Service<(), (HttpContextInner, Incoming), Response = Response> + Clone, + S: motore::Service> + Clone, S::Error: Into, { type Response = S::Response; @@ -59,20 +50,21 @@ where type Future = impl Future>; - fn call(&self, req: Request) -> Self::Future { + fn call(&mut self, req: Request) -> Self::Future { let s = self.inner.clone(); - let peer = self.peer; + let peer = self.peer.clone(); async move { let (parts, req) = req.into_parts(); - let cx = HttpContextInner { + let mut cx = HttpContext { peer, method: parts.method, uri: parts.uri, version: parts.version, headers: parts.headers, extensions: parts.extensions, + params: Params { inner: Vec::with_capacity(0) }, }; - s.call(&mut (), (cx, req)).await + s.call(&mut cx, req).await } } } diff --git a/volo-http/src/param.rs b/volo-http/src/param.rs index 34d27614..f86cf760 100644 --- a/volo-http/src/param.rs +++ b/volo-http/src/param.rs @@ -3,7 +3,7 @@ use std::slice::Iter; use bytes::{BufMut, Bytes, BytesMut}; pub struct Params { - inner: Vec<(Bytes, Bytes)>, + pub(crate) inner: Vec<(Bytes, Bytes)>, } impl From> for Params { diff --git a/volo-http/src/route.rs b/volo-http/src/route.rs index d7a5764c..361e0d3c 100644 --- a/volo-http/src/route.rs +++ b/volo-http/src/route.rs @@ -6,13 +6,12 @@ use hyper::{ body::{Body, Bytes, Incoming}, server::conn::http1, }; -use hyper_util::rt::TokioIo; use motore::layer::Layer; use tokio::net::TcpListener; use crate::{ dispatch::DispatchService, request::FromRequest, response::RespBody, DynError, HttpContext, - HttpContextInner, MotoreService, + MotoreService, }; pub type DynService = motore::BoxCloneService, DynError>; @@ -22,37 +21,24 @@ pub struct Router { inner: matchit::Router, } -impl motore::Service<(), (HttpContextInner, Incoming)> for Router { +impl motore::Service for Router { type Response = Response; type Error = DynError; type Future<'cx> = impl Future> + Send + 'cx where - HttpContextInner: 'cx, + HttpContext: 'cx, Self: 'cx; - fn call<'cx, 's>( - &'s self, - _cx: &'cx mut (), - cxreq: (HttpContextInner, Incoming), - ) -> Self::Future<'cx> + fn call<'cx, 's>(&'s self, cx: &'cx mut HttpContext, req: Incoming) -> Self::Future<'cx> where 's: 'cx, { async move { - let (cx, req) = cxreq; if let Ok(matched) = self.inner.at(cx.uri.path()) { - let mut context = HttpContext { - peer: cx.peer, - method: cx.method, - uri: cx.uri.clone(), - version: cx.version, - headers: cx.headers, - extensions: cx.extensions, - params: matched.params.into(), - }; - matched.value.call(&mut context, req).await + cx.params = matched.params.into(); + matched.value.call(cx, req).await } else { Ok(Response::builder() .status(StatusCode::NOT_FOUND) @@ -106,14 +92,14 @@ pub trait Server { #[async_trait::async_trait] impl Server for S where - S: motore::Service<(), (HttpContextInner, Incoming), Response = Response> + S: motore::Service> + Clone + Send + Sync + 'static, OB: Body + Send + 'static, ::Data: Send, - >::Error: Into, + >::Error: Into, { async fn serve(self, addr: SocketAddr) -> Result<(), DynError> { let listener = TcpListener::bind(addr).await?; @@ -123,11 +109,15 @@ where let s = service.clone(); let (stream, peer) = listener.accept().await?; - let io = TokioIo::new(stream); - tokio::task::spawn(async move { if let Err(err) = http1::Builder::new() - .serve_connection(io, MotoreService { peer, inner: s }) + .serve_connection( + stream, + MotoreService { + peer: peer.into(), + inner: s, + }, + ) .await { tracing::warn!("error serving connection: {:?}", err); From 4d55b295465bac85889c8dc4fae37d4e74ffe5e8 Mon Sep 17 00:00:00 2001 From: bobozhengsir Date: Wed, 11 Oct 2023 16:36:51 +0800 Subject: [PATCH 08/10] add graceful shutdown --- Cargo.lock | 372 +++++++++++++++++--------------------- examples/src/http/http.rs | 15 +- volo-http/Cargo.toml | 3 +- volo-http/src/lib.rs | 1 + volo-http/src/route.rs | 51 +----- volo-http/src/server.rs | 153 ++++++++++++++++ 6 files changed, 336 insertions(+), 259 deletions(-) create mode 100644 volo-http/src/server.rs diff --git a/Cargo.lock b/Cargo.lock index 9c747c3a..70504c2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -57,15 +57,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys", @@ -113,7 +113,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -135,7 +135,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -146,7 +146,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -211,15 +211,15 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -247,9 +247,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.3" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", @@ -289,7 +289,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -315,6 +315,16 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -330,16 +340,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -380,7 +380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core 0.9.8", @@ -469,25 +469,14 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "event-listener" version = "2.5.3" @@ -513,7 +502,7 @@ dependencies = [ "tokio-stream", "tracing", "tracing-subscriber", - "volo 0.5.4", + "volo", "volo-gen", "volo-grpc", "volo-http", @@ -522,9 +511,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "faststr" @@ -633,7 +622,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -719,9 +708,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "heck" @@ -740,9 +729,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -939,12 +928,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.1", ] [[package]] @@ -966,17 +955,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -990,7 +968,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.13", + "rustix", "windows-sys", ] @@ -1035,15 +1013,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linked-hash-map" @@ -1064,15 +1042,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" @@ -1101,15 +1073,15 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -1247,9 +1219,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", @@ -1283,7 +1255,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -1392,7 +1364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.0", + "indexmap 2.0.2", ] [[package]] @@ -1425,7 +1397,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -1462,9 +1434,9 @@ dependencies = [ [[package]] name = "pilota-build" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8151d64b6ecf41e035e151391b374810572f574c5ab272fa31b5222ff4476748" +checksum = "6c58d5b9c1797d6d37ce6dea975dfbf2ec3d12137a43451a0394600055932b8f" dependencies = [ "anyhow", "dashmap", @@ -1487,7 +1459,7 @@ dependencies = [ "scoped-tls", "serde", "serde_yaml", - "syn 2.0.33", + "syn 2.0.38", "toml", "tracing", "tracing-subscriber", @@ -1519,7 +1491,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -1562,28 +1534,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" dependencies = [ "bit-set", - "bitflags 1.3.2", - "byteorder", + "bit-vec", + "bitflags 2.4.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.6.29", + "regex-syntax 0.7.5", "rusty-fork", "tempfile", "unarray", @@ -1681,9 +1653,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1691,14 +1663,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -1732,14 +1702,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", - "regex-syntax 0.7.5", + "regex-automata 0.4.1", + "regex-syntax 0.8.0", ] [[package]] @@ -1753,13 +1723,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.8.0", ] [[package]] @@ -1774,11 +1744,17 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +[[package]] +name = "regex-syntax" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" + [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64 0.21.4", "bytes", @@ -1802,6 +1778,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-rustls", "tower-service", @@ -1809,7 +1786,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.2", + "webpki-roots", "winreg", ] @@ -1851,28 +1828,14 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.37.23" +version = "0.38.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys", -] - -[[package]] -name = "rustix" -version = "0.38.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.7", + "linux-raw-sys", "windows-sys", ] @@ -1884,7 +1847,7 @@ checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", - "rustls-webpki 0.101.5", + "rustls-webpki", "sct", ] @@ -1899,19 +1862,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.100.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.5" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ "ring", "untrusted", @@ -1997,9 +1950,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" @@ -2018,7 +1971,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -2059,7 +2012,7 @@ version = "0.9.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.2", "itoa", "ryu", "serde", @@ -2068,9 +2021,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2101,9 +2054,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "socket2" @@ -2150,15 +2103,36 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.8.0" @@ -2168,47 +2142,47 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.13", + "rustix", "windows-sys", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.37.23", + "rustix", "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -2238,9 +2212,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -2273,7 +2247,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -2299,9 +2273,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -2339,7 +2313,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.2", "serde", "serde_spanned", "toml_datetime", @@ -2399,7 +2373,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", ] [[package]] @@ -2508,20 +2482,20 @@ dependencies = [ [[package]] name = "ureq" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" +checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ "base64 0.21.4", "flate2", "log", "once_cell", "rustls", - "rustls-webpki 0.100.3", + "rustls-webpki", "serde", "serde_json", "url", - "webpki-roots 0.23.1", + "webpki-roots", ] [[package]] @@ -2580,6 +2554,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "volo" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2600,7 +2575,6 @@ dependencies = [ "pin-project", "rand", "socket2 0.5.4", ->>>>>>> downgrade hyper version "thiserror", "tokio", "tokio-stream", @@ -2631,7 +2605,7 @@ dependencies = [ "syn 1.0.109", "tempfile", "url_path", - "volo 0.5.4", + "volo", "walkdir", ] @@ -2667,7 +2641,7 @@ dependencies = [ "futures", "pilota", "tokio", - "volo 0.5.4", + "volo", "volo-build", "volo-grpc", "volo-thrift", @@ -2704,7 +2678,7 @@ dependencies = [ "tower", "tracing", "tracing-subscriber", - "volo 0.5.4", + "volo", ] [[package]] @@ -2720,13 +2694,14 @@ dependencies = [ "matchit", "mime", "motore", + "parking_lot 0.12.1", "pin-project-lite", "serde", "serde_json", "thiserror", "tokio", "tracing", - "volo 0.5.5", + "volo", ] [[package]] @@ -2756,7 +2731,7 @@ dependencies = [ "thiserror", "tokio", "tracing", - "volo 0.5.4", + "volo", ] [[package]] @@ -2814,7 +2789,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -2848,7 +2823,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2869,15 +2844,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.3", -] - [[package]] name = "webpki-roots" version = "0.25.2" @@ -2893,7 +2859,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.13", + "rustix", ] [[package]] @@ -2914,9 +2880,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -3004,9 +2970,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" dependencies = [ "memchr", ] diff --git a/examples/src/http/http.rs b/examples/src/http/http.rs index c84686c8..56b2f564 100644 --- a/examples/src/http/http.rs +++ b/examples/src/http/http.rs @@ -8,7 +8,8 @@ use serde::{Deserialize, Serialize}; use volo_http::{ handler::HandlerService, request::Json, - route::{Route, Router, Server, ServiceLayerExt}, + route::{Route, Router, ServiceLayerExt}, + server::Server, HttpContext, }; @@ -69,7 +70,7 @@ async fn test( #[tokio::main(flavor = "multi_thread")] async fn main() { - Router::new() + let app = Router::new() .route( "/", Route::builder() @@ -86,8 +87,10 @@ async fn main() { .post(HandlerService::new(test)) .build(), ) - .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(); } diff --git a/volo-http/Cargo.toml b/volo-http/Cargo.toml index d629fa00..f3bcd0b9 100644 --- a/volo-http/Cargo.toml +++ b/volo-http/Cargo.toml @@ -13,7 +13,7 @@ categories = ["asynchronous", "network-programming", "web-programming"] keywords = ["async", "http"] [dependencies] -volo = { version = "0.5" } +volo = { version = "0.5", 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" @@ -29,6 +29,7 @@ thiserror.workspace = true mime = "0.3" serde = "1" async-trait.workspace = true +parking_lot.workspace = true [dev-dependencies] serde = { version = "1", features = ["derive"] } diff --git a/volo-http/src/lib.rs b/volo-http/src/lib.rs index 0aed4cee..df0c05b8 100644 --- a/volo-http/src/lib.rs +++ b/volo-http/src/lib.rs @@ -8,6 +8,7 @@ pub mod param; pub mod request; pub mod response; pub mod route; +pub mod server; use std::future::Future; diff --git a/volo-http/src/route.rs b/volo-http/src/route.rs index 361e0d3c..2b68da9e 100644 --- a/volo-http/src/route.rs +++ b/volo-http/src/route.rs @@ -1,17 +1,12 @@ -use std::{future::Future, net::SocketAddr}; +use std::future::Future; use http::{Method, Response, StatusCode}; use http_body_util::Full; -use hyper::{ - body::{Body, Bytes, Incoming}, - server::conn::http1, -}; +use hyper::body::{Bytes, Incoming}; use motore::layer::Layer; -use tokio::net::TcpListener; use crate::{ dispatch::DispatchService, request::FromRequest, response::RespBody, DynError, HttpContext, - MotoreService, }; pub type DynService = motore::BoxCloneService, DynError>; @@ -85,48 +80,6 @@ impl ServiceLayerExt for S { } } -#[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); - } - }); - } - } -} - #[derive(Default, Clone)] pub struct Route { options: Option, diff --git a/volo-http/src/server.rs b/volo-http/src/server.rs new file mode 100644 index 00000000..07411e8c --- /dev/null +++ b/volo-http/src/server.rs @@ -0,0 +1,153 @@ +use std::{ + sync::{atomic::Ordering, Arc}, + time::Duration, +}; + +use http::Response; +use hyper::{ + body::{Body, Incoming as BodyIncoming}, + server::conn::http1, +}; +use motore::BoxError; +use tokio::sync::Notify; +use tracing::{info, trace, warn}; +use volo::net::{incoming::Incoming, MakeIncoming}; + +use crate::{DynError, HttpContext, MotoreService}; + +#[derive(Clone)] +pub struct Server { + app: App, +} + +impl Server +where + OB: Body + Send + 'static, + OB::Data: Send, + App: motore::Service> + + Clone + + Send + + Sync + + 'static, + App::Error: Into, +{ + pub fn new(app: App) -> Self { + Self { app: app } + } + + pub async fn run(self, mk_incoming: MI) -> Result<(), BoxError> { + let mut incoming = mk_incoming.make_incoming().await?; + info!("[VOLO-HTTP] server start at: {:?}", incoming); + + let conn_cnt = Arc::new(std::sync::atomic::AtomicUsize::new(0)); + let gconn_cnt = conn_cnt.clone(); + let (exit_notify, exit_flag, exit_mark) = ( + Arc::new(Notify::const_new()), + Arc::new(parking_lot::RwLock::new(false)), + Arc::new(std::sync::atomic::AtomicBool::default()), + ); + + let exit_flag_inner = exit_flag.clone(); + + let service = self; + let handler = tokio::spawn(async move { + let exit_flag = exit_flag_inner.clone(); + loop { + if *exit_flag.read() { + break Ok(()); + } + match incoming.accept().await { + Ok(Some(conn)) => { + let peer = conn.info.peer_addr.clone().unwrap(); + trace!("[VOLO] accept connection from: {:?}", peer); + + conn_cnt.fetch_add(1, Ordering::Relaxed); + + let s = service.clone(); + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(conn, MotoreService { peer, inner: s.app }) + .await + { + warn!("error serving connection: {:?}", err); + } + }); + } + Ok(None) => break Ok(()), + Err(e) => break Err(Box::new(e)), + } + } + }); + + #[cfg(target_family = "unix")] + { + // graceful shutdown + let mut sigint = + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::interrupt())?; + let mut sighup = + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::hangup())?; + let mut sigterm = + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())?; + + // graceful shutdown handler + tokio::select! { + _ = sigint.recv() => {} + _ = sighup.recv() => {} + _ = sigterm.recv() => {} + res = handler => { + match res { + Ok(res) => { + match res { + Ok(()) => {} + Err(e) => return Err(Box::new(e)) + }; + } + Err(e) => return Err(Box::new(e)), + } + } + } + } + + // graceful shutdown handler for windows + #[cfg(target_family = "windows")] + tokio::select! { + _ = tokio::signal::ctrl_c() => {} + res = handler => { + match res { + Ok(res) => { + match res { + Ok(()) => {} + Err(e) => return Err(Box::new(e)) + }; + } + Err(e) => return Err(Box::new(e)), + } + } + } + + // received signal, graceful shutdown now + info!("[VOLO] received signal, gracefully exiting now"); + *exit_flag.write() = true; + exit_mark.store(true, Ordering::Relaxed); + + // Now we won't accept new connections. + // And we want to send crrst reply to the peers in the short future. + if gconn_cnt.load(Ordering::Relaxed) != 0 { + tokio::time::sleep(Duration::from_secs(2)).await; + } + exit_notify.notify_waiters(); + + // wait for all connections to be closed + for _ in 0..28 { + if gconn_cnt.load(Ordering::Relaxed) == 0 { + break; + } + trace!( + "[VOLO] gracefully exiting, remaining connection count: {}", + gconn_cnt.load(Ordering::Relaxed) + ); + tokio::time::sleep(Duration::from_secs(1)).await; + } + Ok(()) + } +} From 01c8a54e0f967a68320832424760e10305ece206 Mon Sep 17 00:00:00 2001 From: bobozhengsir Date: Fri, 13 Oct 2023 14:52:19 +0800 Subject: [PATCH 09/10] rebase main --- Cargo.lock | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70504c2d..1a835823 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2553,35 +2553,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.6.2" From e5396bc86d117f049ed1d7cf2b54352286f37576 Mon Sep 17 00:00:00 2001 From: bobozhengsir Date: Mon, 16 Oct 2023 17:00:22 +0800 Subject: [PATCH 10/10] fix graceful shutdown --- volo-http/src/server.rs | 65 ++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/volo-http/src/server.rs b/volo-http/src/server.rs index 07411e8c..219bf911 100644 --- a/volo-http/src/server.rs +++ b/volo-http/src/server.rs @@ -39,21 +39,17 @@ where let mut incoming = mk_incoming.make_incoming().await?; info!("[VOLO-HTTP] server start at: {:?}", incoming); - let conn_cnt = Arc::new(std::sync::atomic::AtomicUsize::new(0)); - let gconn_cnt = conn_cnt.clone(); - let (exit_notify, exit_flag, exit_mark) = ( - Arc::new(Notify::const_new()), - Arc::new(parking_lot::RwLock::new(false)), - Arc::new(std::sync::atomic::AtomicBool::default()), - ); + let (tx, rx) = tokio::sync::watch::channel(()); + let exit_mark = Arc::new(std::sync::atomic::AtomicBool::default()); - let exit_flag_inner = exit_flag.clone(); + let exit_mark_inner = exit_mark.clone(); + let rx_inner = rx.clone(); let service = self; let handler = tokio::spawn(async move { - let exit_flag = exit_flag_inner.clone(); + let exit_mark = exit_mark_inner.clone(); loop { - if *exit_flag.read() { + if exit_mark.load(Ordering::Relaxed) { break Ok(()); } match incoming.accept().await { @@ -61,15 +57,27 @@ where let peer = conn.info.peer_addr.clone().unwrap(); trace!("[VOLO] accept connection from: {:?}", peer); - conn_cnt.fetch_add(1, Ordering::Relaxed); - let s = service.clone(); + let mut watch = rx_inner.clone(); tokio::task::spawn(async move { - if let Err(err) = http1::Builder::new() - .serve_connection(conn, MotoreService { peer, inner: s.app }) - .await - { - warn!("error serving connection: {:?}", err); + let mut http_conn = http1::Builder::new() + .serve_connection(conn, MotoreService { peer, inner: s.app }); + tokio::select! { + _ = watch.changed() => { + tracing::trace!("[VOLO] closing a pending connection"); + // Graceful shutdown. + hyper::server::conn::http1::Connection::graceful_shutdown(Pin::new(&mut http_conn)); + // Continue to poll this connection until shutdown can finish. + let result = http_conn.await; + if let Err(err) = result { + tracing::debug!("[VOLO] connection error: {:?}", err); + } + } + result = &mut http_conn => { + if let Err(err) = result { + tracing::debug!("[VOLO] connection error: {:?}", err); + } + }, } }); } @@ -127,27 +135,10 @@ where // received signal, graceful shutdown now info!("[VOLO] received signal, gracefully exiting now"); - *exit_flag.write() = true; exit_mark.store(true, Ordering::Relaxed); - - // Now we won't accept new connections. - // And we want to send crrst reply to the peers in the short future. - if gconn_cnt.load(Ordering::Relaxed) != 0 { - tokio::time::sleep(Duration::from_secs(2)).await; - } - exit_notify.notify_waiters(); - - // wait for all connections to be closed - for _ in 0..28 { - if gconn_cnt.load(Ordering::Relaxed) == 0 { - break; - } - trace!( - "[VOLO] gracefully exiting, remaining connection count: {}", - gconn_cnt.load(Ordering::Relaxed) - ); - tokio::time::sleep(Duration::from_secs(1)).await; - } + drop(rx); + let _ = tx.send(()); + tx.closed().await; Ok(()) } }