From 41f65857c8a7fd0f51593c95ba53960769ae9646 Mon Sep 17 00:00:00 2001 From: zajko Date: Mon, 18 Dec 2023 15:19:38 +0100 Subject: [PATCH] Changing internal structure of EventListener so it can be unit teste (#225) Co-authored-by: Jakub Zajkowski --- .../workflows/ci-casper-event-sidecar-rs.yml | 3 +- Cargo.lock | 709 ++++++++++-------- listener/src/connection_manager.rs | 62 +- listener/src/connection_tasks.rs | 2 +- listener/src/connections_builder.rs | 108 +++ listener/src/lib.rs | 211 ++---- listener/src/sse_connector.rs | 71 +- rust-toolchain.toml | 2 +- sidecar/src/event_stream_server/sse_server.rs | 62 +- sidecar/src/event_stream_server/tests.rs | 2 +- sidecar/src/main.rs | 69 +- sidecar/src/rest_server/errors.rs | 50 +- sidecar/src/tests/performance_tests.rs | 48 +- 13 files changed, 783 insertions(+), 616 deletions(-) create mode 100644 listener/src/connections_builder.rs diff --git a/.github/workflows/ci-casper-event-sidecar-rs.yml b/.github/workflows/ci-casper-event-sidecar-rs.yml index 6514fc68..e6deff05 100644 --- a/.github/workflows/ci-casper-event-sidecar-rs.yml +++ b/.github/workflows/ci-casper-event-sidecar-rs.yml @@ -45,7 +45,8 @@ jobs: # Hope to get to here: # run: cargo audit --deny warnings # RUSTSEC-2022-0093 - that is an issue that comes form casper-types, need to update that depenency as soon as a new release is made - run: cargo audit --ignore RUSTSEC-2022-0093 + # RUSTSEC-2023-0071 - there is a transitive audit issue via sqlx. There is no fix for that yet, we should update dependencies once a fix is presented + run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2023-0071 - name: test run: cargo test diff --git a/Cargo.lock b/Cargo.lock index 0abf8cc7..ac55cc8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72832d73be48bac96a5d7944568f305d829ed55b0ce3b483647089dfaf6cf704" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom", @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", @@ -124,30 +124,30 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -206,9 +206,9 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -217,9 +217,9 @@ version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -240,6 +240,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix", + "rand 0.8.5", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -368,9 +378,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -384,9 +394,9 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecount" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1a12477b7237a01c11a80a51278165f9ba0edd28fa6db00a65ab230320dc58c" +checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" [[package]] name = "byteorder" @@ -469,7 +479,7 @@ dependencies = [ "hex_fmt", "http", "hyper", - "indexmap 2.0.2", + "indexmap 2.1.0", "itertools 0.10.5", "jsonschema", "once_cell", @@ -483,7 +493,7 @@ dependencies = [ "sea-query", "serde", "serde_json", - "sqlx 0.7.2", + "sqlx 0.7.3", "tabled", "tempfile", "thiserror", @@ -585,9 +595,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -595,9 +605,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -607,21 +617,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -631,11 +641,10 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] @@ -654,9 +663,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -664,15 +673,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -688,9 +697,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" @@ -771,9 +780,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -788,9 +797,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ "powerfmt", ] @@ -801,7 +810,7 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", ] @@ -891,9 +900,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "ecdsa" @@ -971,12 +980,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1036,14 +1045,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -1096,9 +1105,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1121,9 +1130,9 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -1136,9 +1145,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -1146,15 +1155,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -1185,38 +1194,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -1242,9 +1251,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "js-sys", @@ -1255,9 +1264,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "group" @@ -1272,9 +1281,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -1282,7 +1291,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1297,11 +1306,11 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.4", + "ahash 0.8.6", "allocator-api2", ] @@ -1311,7 +1320,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.2", + "hashbrown 0.14.3", ] [[package]] @@ -1414,9 +1423,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1425,9 +1434,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1491,9 +1500,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1512,12 +1521,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "serde", ] @@ -1527,9 +1536,9 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -1567,17 +1576,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix 0.38.20", - "windows-sys 0.48.0", -] - [[package]] name = "iso8601" version = "0.6.1" @@ -1598,18 +1596,18 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" @@ -1622,9 +1620,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1635,7 +1633,7 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978" dependencies = [ - "ahash 0.8.4", + "ahash 0.8.6", "anyhow", "base64 0.21.5", "bytecount", @@ -1682,9 +1680,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libm" @@ -1692,11 +1690,22 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "libsqlite3-sys" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ "cc", "pkg-config", @@ -1711,9 +1720,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" @@ -1791,9 +1800,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -1836,6 +1845,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -1919,7 +1939,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", ] @@ -1988,9 +2008,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -2000,9 +2020,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -2019,9 +2039,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2032,9 +2052,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" dependencies = [ "cc", "libc", @@ -2166,9 +2186,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pg-embed" @@ -2204,9 +2224,9 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2286,7 +2306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", "version_check", @@ -2298,7 +2318,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "version_check", ] @@ -2314,9 +2334,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -2331,7 +2351,7 @@ dependencies = [ "byteorder", "hex", "lazy_static", - "rustix 0.36.16", + "rustix 0.36.17", ] [[package]] @@ -2353,9 +2373,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", @@ -2365,7 +2385,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax 0.7.5", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -2409,7 +2429,7 @@ version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", ] [[package]] @@ -2511,15 +2531,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -2531,12 +2542,12 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] @@ -2549,7 +2560,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] @@ -2560,15 +2571,9 @@ checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -2632,9 +2637,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", "getrandom", @@ -2646,21 +2651,19 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ - "byteorder", "const-oid", "digest 0.10.7", "num-bigint-dig", "num-integer", - "num-iter", "num-traits", "pkcs1", "pkcs8", "rand_core 0.6.4", - "signature 2.1.0", + "signature 2.2.0", "spki", "subtle", "zeroize", @@ -2683,11 +2686,11 @@ version = "6.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "rust-embed-utils", "shellexpand", - "syn 2.0.38", + "syn 2.0.41", "walkdir", ] @@ -2709,9 +2712,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.36.16" +version = "0.36.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6da3636faa25820d8648e0e31c5d519bbb01f72fdf57131f0f5f7da5fed36eab" +checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed" dependencies = [ "bitflags 1.3.2", "errno", @@ -2723,15 +2726,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.20" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", ] [[package]] @@ -2748,9 +2751,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64 0.21.5", ] @@ -2775,9 +2778,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -2816,7 +2819,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791c2c848cff1abaeae34fef7e70da5f93171d9eea81ce0fe969a1df627a61a8" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "serde_derive_internals", "syn 1.0.109", @@ -2836,19 +2839,19 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] name = "sea-query" -version = "0.30.2" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3e6bba153bb198646c8762c48414942a38db27d142e44735a133cabddcc820" +checksum = "41558fa9bb5f4d73952dac0b9d9c2ce23966493fc9ee0008037b01d709838a68" dependencies = [ "inherent", "sea-query-derive", @@ -2861,9 +2864,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc" dependencies = [ "heck", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", "thiserror", ] @@ -2892,9 +2895,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -2910,13 +2913,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -2925,18 +2928,18 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "itoa", "ryu", "serde", @@ -3028,9 +3031,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -3047,9 +3050,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" @@ -3088,9 +3091,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -3098,11 +3101,11 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools 0.11.0", + "itertools 0.12.0", "nom", "unicode_categories", ] @@ -3119,12 +3122,12 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" dependencies = [ - "sqlx-core 0.7.2", - "sqlx-macros 0.7.2", + "sqlx-core 0.7.3", + "sqlx-macros 0.7.3", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", @@ -3136,7 +3139,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", "atoi 1.0.0", "base64 0.13.1", "bitflags 1.3.2", @@ -3185,11 +3188,11 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.8.4", + "ahash 0.8.6", "atoi 2.0.0", "byteorder", "bytes", @@ -3205,7 +3208,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.0.2", + "indexmap 2.1.0", "log", "memchr", "native-tls", @@ -3234,7 +3237,7 @@ dependencies = [ "either", "heck", "once_cell", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "sha2 0.10.8", "sqlx-core 0.6.3", @@ -3245,34 +3248,35 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "sqlx-core 0.7.2", + "sqlx-core 0.7.3", "sqlx-macros-core", "syn 1.0.109", ] [[package]] name = "sqlx-macros-core" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" dependencies = [ + "atomic-write-file", "dotenvy", "either", "heck", "hex", "once_cell", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "serde", "serde_json", "sha2 0.10.8", - "sqlx-core 0.7.2", + "sqlx-core 0.7.3", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", @@ -3284,9 +3288,9 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" dependencies = [ "atoi 2.0.0", "base64 0.21.5", @@ -3317,7 +3321,7 @@ dependencies = [ "sha1", "sha2 0.10.8", "smallvec", - "sqlx-core 0.7.2", + "sqlx-core 0.7.3", "stringprep", "thiserror", "tracing", @@ -3326,9 +3330,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" dependencies = [ "atoi 2.0.0", "base64 0.21.5", @@ -3356,7 +3360,7 @@ dependencies = [ "sha1", "sha2 0.10.8", "smallvec", - "sqlx-core 0.7.2", + "sqlx-core 0.7.3", "stringprep", "thiserror", "tracing", @@ -3376,9 +3380,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" dependencies = [ "atoi 2.0.0", "flume", @@ -3391,9 +3395,10 @@ dependencies = [ "log", "percent-encoding", "serde", - "sqlx-core 0.7.2", + "sqlx-core 0.7.3", "tracing", "url", + "urlencoding", ] [[package]] @@ -3435,7 +3440,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "rustversion", "syn 1.0.109", @@ -3464,18 +3469,18 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.38" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "unicode-ident", ] @@ -3521,7 +3526,7 @@ checksum = "beca1b4eaceb4f2755df858b88d9b9315b7ccfd1ffd0d7a48a52602301f01a57" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", "syn 1.0.109", ] @@ -3539,14 +3544,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", - "rustix 0.38.20", + "redox_syscall 0.4.1", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -3565,9 +3570,9 @@ version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3645,9 +3650,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -3664,13 +3669,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3720,9 +3725,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3787,9 +3792,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -3804,20 +3809,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -3829,9 +3834,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" @@ -3887,9 +3892,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -3944,15 +3949,21 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -3971,7 +3982,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82b1bc5417102a73e8464c686eef947bdfb99fcdfc0a4f228e81afa9526470a" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_json", "utoipa-gen", @@ -3984,9 +3995,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d96dcd6fc96f3df9b3280ef480770af1b7c5d14bc55192baa9b067976d920c" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] @@ -4006,9 +4017,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" [[package]] name = "valuable" @@ -4045,7 +4056,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", ] @@ -4117,9 +4128,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4127,24 +4138,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -4154,9 +4165,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote 1.0.33", "wasm-bindgen-macro-support", @@ -4164,22 +4175,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-streams" @@ -4196,9 +4207,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4210,7 +4221,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.5", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -4288,6 +4299,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -4318,6 +4338,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -4330,6 +4365,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -4342,6 +4383,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -4354,6 +4401,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -4366,6 +4419,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -4378,6 +4437,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -4390,6 +4455,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -4402,6 +4473,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winreg" version = "0.50.0" @@ -4420,11 +4497,13 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "xattr" -version = "1.0.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +checksum = "a7dae5072fe1f8db8f8d29059189ac175196e410e40ba42d5d4684ae2f750995" dependencies = [ "libc", + "linux-raw-sys 0.4.12", + "rustix 0.38.28", ] [[package]] @@ -4444,29 +4523,29 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.11" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c19fae0c8a9efc6a8281f2e623db8af1db9e57852e04cde3e754dd2dc29340f" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.11" +version = "0.7.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc56589e9ddd1f1c28d4b4b5c773ce232910a6bb67a70133d61c9e347585efe9" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -4477,9 +4556,9 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.70", "quote 1.0.33", - "syn 2.0.38", + "syn 2.0.41", ] [[package]] diff --git a/listener/src/connection_manager.rs b/listener/src/connection_manager.rs index 83a8a1c6..60965b09 100644 --- a/listener/src/connection_manager.rs +++ b/listener/src/connection_manager.rs @@ -4,6 +4,7 @@ use crate::{ SseEvent, }; use anyhow::Error; +use async_trait::async_trait; use casper_event_types::{ metrics, sse_data::{deserialize, SseData}, @@ -21,16 +22,27 @@ use tokio::sync::mpsc::Sender; use tokio_stream::StreamExt; use tracing::{error, trace, warn}; +const API_VERSION: &str = "ApiVersion"; const FETCHING_FROM_STREAM_FAILED: &str = "fetching_from_stream_failed"; +const FIRST_EVENT_EMPTY: &str = "First event was empty"; +const ERROR_WHEN_TRYING_TO_SEND_MESSAGE: &str = + "Error when trying to send message in ConnectionManager#handle_event"; const DESERIALIZATION_ERROR: &str = "deserialization_error"; const EVENT_WITHOUT_ID: &str = "event_without_id"; const SENDING_FAILED: &str = "sending_downstream_failed"; const API_VERSION_SENDING_FAILED: &str = "api_version_sending_failed"; const API_VERSION_DESERIALIZATION_FAILED: &str = "api_version_deserialization_failed"; const API_VERSION_EXPECTED: &str = "api_version_expected"; +const OTHER_TYPE_OF_MESSAGE_WHEN_API_VERSION_EXPECTED: &str = + "When trying to deserialize ApiVersion got other type of message"; + +#[async_trait] +pub trait ConnectionManager: Sync + Send { + async fn start_handling(&mut self) -> Result<(), ConnectionManagerError>; +} /// Implementation of a connection to a single sse endpoint of a node. -pub(super) struct ConnectionManager { +pub struct DefaultConnectionManager { connector: Box, bind_address: Url, current_event_id: Option, @@ -60,7 +72,7 @@ impl Display for ConnectionManagerError { } /// Builder for [ConnectionManager] -pub struct ConnectionManagerBuilder { +pub struct DefaultConnectionManagerBuilder { /// Address of the node pub(super) bind_address: Url, /// Maximum attempts the connection manager will try to (initially) connect. @@ -89,8 +101,14 @@ pub struct ConnectionManagerBuilder { pub(super) no_message_timeout: Duration, } -impl ConnectionManagerBuilder { - pub(super) fn build(self) -> ConnectionManager { +#[async_trait::async_trait] +impl ConnectionManager for DefaultConnectionManager { + async fn start_handling(&mut self) -> Result<(), ConnectionManagerError> { + self.do_start_handling().await + } +} +impl DefaultConnectionManagerBuilder { + pub(super) fn build(self) -> DefaultConnectionManager { trace!("Creating connection manager for: {}", self.bind_address); let connector = Box::new(SseConnection { max_attempts: self.max_attempts, @@ -100,7 +118,7 @@ impl ConnectionManagerBuilder { sleep_between_keepalive_checks: self.sleep_between_keep_alive_checks, no_message_timeout: self.no_message_timeout, }); - ConnectionManager { + DefaultConnectionManager { connector, bind_address: self.bind_address, current_event_id: self.start_from_event_id, @@ -112,12 +130,9 @@ impl ConnectionManagerBuilder { } } -impl ConnectionManager { +impl DefaultConnectionManager { /// Start handling traffic from nodes endpoint. This function is blocking, it will return a /// ConnectionManagerError result if something went wrong while processing. - pub(super) async fn start_handling(&mut self) -> Result<(), ConnectionManagerError> { - self.do_start_handling().await - } async fn connect( &mut self, @@ -184,7 +199,7 @@ impl ConnectionManager { Err(parse_error) => { // ApiVersion events have no ID so parsing "" to u32 will fail. // This gate saves displaying a warning for a trivial error. - if !event.data.contains("ApiVersion") { + if !event.data.contains(API_VERSION) { count_error(EVENT_WITHOUT_ID); warn!("Parse Error: {}", parse_error); } @@ -208,7 +223,8 @@ impl ConnectionManager { async fn handle_event(&mut self, event: Event) -> Result<(), Error> { match deserialize(&event.data) { Err(serde_error) => { - count_error(DESERIALIZATION_ERROR); + let reason = format!("{}:{}", DESERIALIZATION_ERROR, self.filter); + count_error(&reason); let error_message = format!("Serde Error: {}", serde_error); error!(error_message); return Err(Error::msg(error_message)); @@ -229,9 +245,7 @@ impl ConnectionManager { ); self.sse_event_sender.send(sse_event).await.map_err(|_| { count_error(SENDING_FAILED); - Error::msg( - "Error when trying to send message in ConnectionManager#handle_event", - ) + Error::msg(ERROR_WHEN_TRYING_TO_SEND_MESSAGE) })?; } } @@ -246,12 +260,12 @@ impl ConnectionManager { // We want to see if the first message got from a connection is ApiVersion. That is the protocols guarantee. // If it's not - something went very wrong and we shouldn't consider this connection valid match receiver.next().await { - None => Err(recoverable_error(Error::msg("First event was empty"))), + None => Err(recoverable_error(Error::msg(FIRST_EVENT_EMPTY))), Some(Err(error)) => Err(failed_to_get_first_event(error)), Some(Ok(event)) => { let payload_size = event.data.len(); self.observe_bytes(payload_size); - if event.data.contains("ApiVersion") { + if event.data.contains(API_VERSION) { self.try_handle_api_version_message(&event, receiver).await } else { Err(expected_first_message_to_be_api_version(event.data)) @@ -279,15 +293,13 @@ impl ConnectionManager { ); self.sse_event_sender.send(sse_event).await.map_err(|_| { count_error(API_VERSION_SENDING_FAILED); - non_recoverable_error(Error::msg( - "Error when trying to send message in ConnectionManager#handle_event", - )) + non_recoverable_error(Error::msg(ERROR_WHEN_TRYING_TO_SEND_MESSAGE)) })? } Ok(_sse_data) => { count_error(API_VERSION_EXPECTED); return Err(non_recoverable_error(Error::msg( - "When trying to deserialize ApiVersion got other type of message", + OTHER_TYPE_OF_MESSAGE_WHEN_API_VERSION_EXPECTED, ))); } Err(x) => { @@ -347,9 +359,9 @@ fn count_error(reason: &str) { } #[cfg(test)] -mod tests { +pub mod tests { use crate::{ - connection_manager::{ConnectionManager, ConnectionManagerError}, + connection_manager::{ConnectionManagerError, DefaultConnectionManager, FIRST_EVENT_EMPTY}, sse_connector::{tests::MockSseConnection, StreamConnector}, SseEvent, }; @@ -375,7 +387,7 @@ mod tests { let (mut connection_manager, _, _) = build_manager(connector); let res = connection_manager.do_start_handling().await; if let Err(ConnectionManagerError::InitialConnectionError { error }) = res { - assert_eq!(error.to_string(), "First event was empty"); + assert_eq!(error.to_string(), FIRST_EVENT_EMPTY); } else { unreachable!(); } @@ -453,14 +465,14 @@ mod tests { fn build_manager( connector: Box, ) -> ( - ConnectionManager, + DefaultConnectionManager, Receiver, Receiver<(Filter, u32)>, ) { let bind_address = Url::parse("http://localhost:123").unwrap(); let (data_tx, data_rx) = channel(100); let (event_id_tx, event_id_rx) = channel(100); - let manager = ConnectionManager { + let manager = DefaultConnectionManager { connector, bind_address, current_event_id: None, diff --git a/listener/src/connection_tasks.rs b/listener/src/connection_tasks.rs index 48b33661..31b96242 100644 --- a/listener/src/connection_tasks.rs +++ b/listener/src/connection_tasks.rs @@ -9,7 +9,7 @@ use tokio::sync::Notify; /// failure to connect to any filter should cause all connections to fail without reading any events /// from the stream(s). #[derive(Clone)] -pub(super) struct ConnectionTasks { +pub struct ConnectionTasks { /// The total number filters to which the [ConnectionManager](super::ConnectionManager) is attempting to connect. total: usize, /// The number of filters to which successful connections have been established. diff --git a/listener/src/connections_builder.rs b/listener/src/connections_builder.rs new file mode 100644 index 00000000..7ff8e326 --- /dev/null +++ b/listener/src/connections_builder.rs @@ -0,0 +1,108 @@ +use anyhow::Error; +use async_trait::async_trait; +use casper_event_types::Filter; +use casper_types::ProtocolVersion; +use std::{collections::HashMap, net::IpAddr, sync::Arc, time::Duration}; +use tokio::sync::{mpsc::Sender, Mutex}; +use url::Url; + +use crate::{ + connection_manager::{ConnectionManager, DefaultConnectionManagerBuilder}, + connection_tasks::ConnectionTasks, + FilterWithEventId, SseEvent, +}; + +#[async_trait] +pub trait ConnectionsBuilder: Sync + Send { + async fn build_connections( + &self, + last_event_id_for_filter: Arc>>, + last_seen_event_id_sender: FilterWithEventId, + node_build_version: ProtocolVersion, + ) -> Result>, Error>; +} + +pub struct DefaultConnectionsBuilder { + pub sleep_between_keep_alive_checks: Duration, + pub no_message_timeout: Duration, + pub max_connection_attempts: usize, + pub connection_timeout: Duration, + pub sse_event_sender: Sender, + pub ip_address: IpAddr, + pub sse_port: u16, + pub allow_partial_connection: bool, +} + +#[async_trait] +impl ConnectionsBuilder for DefaultConnectionsBuilder { + async fn build_connections( + &self, + last_event_id_for_filter: Arc>>, + last_seen_event_id_sender: FilterWithEventId, + node_build_version: ProtocolVersion, + ) -> Result>, Error> { + let mut connections = HashMap::new(); + let filters = filters_from_version(node_build_version); + let maybe_tasks = + (!self.allow_partial_connection).then(|| ConnectionTasks::new(filters.len())); + let guard = last_event_id_for_filter.lock().await; + + for filter in filters { + let start_from_event_id = guard.get(&filter).copied().or(Some(0)); + let connection = self + .build_connection( + maybe_tasks.clone(), + start_from_event_id, + filter.clone(), + last_seen_event_id_sender.clone(), + ) + .await?; + connections.insert(filter, connection); + } + drop(guard); + Ok(connections) + } +} + +impl DefaultConnectionsBuilder { + async fn build_connection( + &self, + maybe_tasks: Option, + start_from_event_id: Option, + filter: Filter, + last_seen_event_id_sender: FilterWithEventId, + ) -> Result, Error> { + let bind_address_for_filter = self.filtered_sse_url(&filter)?; + let builder = DefaultConnectionManagerBuilder { + bind_address: bind_address_for_filter, + max_attempts: self.max_connection_attempts, + sse_data_sender: self.sse_event_sender.clone(), + maybe_tasks, + connection_timeout: self.connection_timeout, + start_from_event_id, + filter, + current_event_id_sender: last_seen_event_id_sender, + sleep_between_keep_alive_checks: self.sleep_between_keep_alive_checks, + no_message_timeout: self.no_message_timeout, + }; + Ok(Box::new(builder.build())) + } + + fn filtered_sse_url(&self, filter: &Filter) -> Result { + let url_str = format!("http://{}:{}/{}", self.ip_address, self.sse_port, filter); + Url::parse(&url_str).map_err(Error::from) + } +} + +fn filters_from_version(_build_version: ProtocolVersion) -> Vec { + vec![Filter::Main, Filter::Sigs, Filter::Deploys] +} + +pub struct ConnectionConfig { + pub sleep_between_keep_alive_checks: Duration, + pub no_message_timeout: Duration, + pub max_connection_attempts: usize, + pub connection_timeout: Duration, + pub ip_address: IpAddr, + pub sse_port: u16, +} diff --git a/listener/src/lib.rs b/listener/src/lib.rs index a879594b..14c8e07e 100644 --- a/listener/src/lib.rs +++ b/listener/src/lib.rs @@ -4,15 +4,16 @@ mod connection_manager; mod connection_tasks; +pub mod connections_builder; mod keep_alive_monitor; mod sse_connector; mod types; -use crate::connection_manager::ConnectionManagerBuilder; use anyhow::{anyhow, Context, Error}; use casper_event_types::{metrics, Filter}; use casper_types::ProtocolVersion; use connection_manager::{ConnectionManager, ConnectionManagerError}; use connection_tasks::ConnectionTasks; +use connections_builder::{ConnectionsBuilder, DefaultConnectionsBuilder}; use once_cell::sync::Lazy; use serde_json::Value; use std::{collections::HashMap, str::FromStr, sync::Arc, time::Duration}; @@ -30,6 +31,7 @@ use url::Url; const BUILD_VERSION_KEY: &str = "build_version"; pub static MINIMAL_NODE_VERSION: Lazy = Lazy::new(|| ProtocolVersion::from_parts(1, 5, 2)); +const MAX_CONNECTION_ATTEMPTS_REACHED: &str = "Max connection attempts reached"; pub struct EventListenerBuilder { pub node: NodeConnectionInterface, @@ -45,18 +47,25 @@ pub struct EventListenerBuilder { type FilterWithEventId = Sender<(Filter, u32)>; type CurrentFilterToIdHolder = Arc>>; impl EventListenerBuilder { - pub fn build(&self) -> EventListener { - EventListener { + pub fn build(&self) -> Result { + let connections_builder = Arc::new(DefaultConnectionsBuilder { + sleep_between_keep_alive_checks: self.sleep_between_keep_alive_checks, + no_message_timeout: self.no_message_timeout, + max_connection_attempts: self.max_connection_attempts, + connection_timeout: self.connection_timeout, + sse_event_sender: self.sse_event_sender.clone(), + ip_address: self.node.ip_address, + sse_port: self.node.sse_port, + allow_partial_connection: self.allow_partial_connection, + }); + Ok(EventListener { node_build_version: ProtocolVersion::from_parts(1, 0, 0), node: self.node.clone(), max_connection_attempts: self.max_connection_attempts, delay_between_attempts: self.delay_between_attempts, allow_partial_connection: self.allow_partial_connection, - sse_event_sender: self.sse_event_sender.clone(), - connection_timeout: self.connection_timeout, - sleep_between_keep_alive_checks: self.sleep_between_keep_alive_checks, - no_message_timeout: self.no_message_timeout, - } + connections_builder, + }) } } @@ -73,19 +82,12 @@ pub struct EventListener { /// If set to false, the listener needs to connect to all endpoints a node should expose in a given `node_build_version` for the listener to start processing data. /// If set to true the listen will proceed after connecting to at least one connection. allow_partial_connection: bool, - /// Channel to which data from the node is pushed - sse_event_sender: Sender, - /// Maximum duration we will wait to establish a connection to the node - connection_timeout: Duration, - /// Time the KeepAliveMonitor wait between checks - sleep_between_keep_alive_checks: Duration, - /// Time of inactivity of a node connection that is allowed by KeepAliveMonitor - no_message_timeout: Duration, + connections_builder: Arc, } /// Helper enum determining in what state connection to a node is in. /// It's used to named different situations in which the connection can be. -enum EventListenerStatus { +pub enum EventListenerStatus { /// Event Listener has not yet started to attempt the connection Preparing, /// Event Listener started establishing relevant sse connections to filters of the node @@ -104,13 +106,7 @@ enum EventListenerStatus { } impl EventListenerStatus { - fn log_status_for_event_listener(&self, event_listener: &EventListener) { - let node_address = event_listener.node.ip_address.to_string(); - let sse_port = event_listener.node.sse_port; - EventListenerStatus::log_status(self, node_address.as_str(), sse_port); - } - - fn log_status(&self, node_address: &str, sse_port: u16) { + pub fn log_status(&self, node_address: &str, sse_port: u16) { let status = match self { EventListenerStatus::Preparing => 0, EventListenerStatus::Connecting => 1, @@ -146,13 +142,6 @@ impl EventListener { pub fn get_node_interface(&self) -> NodeConnectionInterface { self.node.clone() } - fn filtered_sse_url(&self, filter: &Filter) -> Result { - let url_str = format!( - "http://{}:{}/{}", - self.node.ip_address, self.node.sse_port, filter - ); - Url::parse(&url_str).map_err(Error::from) - } async fn fetch_build_version( &self, @@ -166,7 +155,7 @@ impl EventListener { match self.fetch_build_version_from_status().await { Ok(version) => { validate_version(&version).map_err(|err| { - EventListenerStatus::IncompatibleVersion.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::IncompatibleVersion, self); err })?; let new_node_build_version = version; @@ -186,7 +175,7 @@ impl EventListener { self.node.ip_address ); if current_attempt >= self.max_connection_attempts { - EventListenerStatus::Defunct.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::Defunct, self); return Err(BuildVersionFetchError::Error(Error::msg( "Unable to retrieve build version from node status", ))); @@ -198,45 +187,43 @@ impl EventListener { /// Spins up the connections and starts pushing data from node pub async fn stream_aggregated_events(&mut self) -> Result<(), Error> { - EventListenerStatus::Preparing.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::Preparing, self); let (last_event_id_for_filter, last_seen_event_id_sender) = self.start_last_event_id_registry(self.node.ip_address.to_string(), self.node.sse_port); - EventListenerStatus::Connecting.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::Connecting, self); let mut current_attempt = 1; while current_attempt <= self.max_connection_attempts { + if current_attempt > 1 { + sleep(self.delay_between_attempts).await; + } match self.get_version(current_attempt).await { GetVersionResult::Ok(Some(protocol_version)) => { self.node_build_version = protocol_version; - current_attempt = 1 + current_attempt = 1 // Restart counter if the nodes version changed } GetVersionResult::Retry => { - sleep(self.delay_between_attempts).await; current_attempt += 1; + if current_attempt >= self.max_connection_attempts { + log_status_for_event_listener(EventListenerStatus::Defunct, self); + } continue; } GetVersionResult::Error(e) => return Err(e), _ => {} } - match self + if let ConnectOutcome::ConnectionLost = self .do_connect( last_event_id_for_filter.clone(), last_seen_event_id_sender.clone(), ) .await? { - ConnectOutcome::ConnectionLost => { - current_attempt += 1; - warn!( - "Lost connection to node {}, on attempt {}/{}", - self.node.ip_address, current_attempt, self.max_connection_attempts - ); - } - ConnectOutcome::SystemReconnect => {} - }; - sleep(Duration::from_secs(1)).await; + current_attempt += 1; + warn_connection_lost(self, current_attempt); + } } - EventListenerStatus::Defunct.log_status_for_event_listener(self); - Ok(()) + log_status_for_event_listener(EventListenerStatus::Defunct, self); + Err(Error::msg(MAX_CONNECTION_ATTEMPTS_REACHED)) } async fn do_connect( @@ -245,9 +232,11 @@ impl EventListener { last_seen_event_id_sender: FilterWithEventId, ) -> Result { let connections = self + .connections_builder .build_connections( last_event_id_for_filter.clone(), last_seen_event_id_sender.clone(), + self.node_build_version, ) .await?; let connection_join_handles = start_connections(connections); @@ -265,12 +254,12 @@ impl EventListener { let task_result = select_result.0; if let Ok(res) = task_result { if res.is_err() { - EventListenerStatus::Reconnecting.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::Reconnecting, self); return Ok(ConnectOutcome::ConnectionLost); } Ok(ConnectOutcome::SystemReconnect) } else { - EventListenerStatus::Reconnecting.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::Reconnecting, self); Ok(ConnectOutcome::ConnectionLost) } } @@ -301,15 +290,17 @@ impl EventListener { self.node.ip_address.to_string(), error ); - EventListenerStatus::Reconnecting.log_status_for_event_listener(self); + log_status_for_event_listener(EventListenerStatus::Reconnecting, self); return ConnectOutcome::ConnectionLost; } ConnectionManagerError::InitialConnectionError { error } => { //No futures_left means no more filters active, we need to restart the whole listener if futures_left.is_empty() { error!("Restarting event listener {} because of no more active connections left: {}", self.node.ip_address.to_string(), error); - EventListenerStatus::Reconnecting - .log_status_for_event_listener(self); + log_status_for_event_listener( + EventListenerStatus::Reconnecting, + self, + ); return ConnectOutcome::ConnectionLost; } } @@ -320,35 +311,6 @@ impl EventListener { } } - async fn build_connections( - &mut self, - last_event_id_for_filter: Arc>>, - last_seen_event_id_sender: FilterWithEventId, - ) -> Result, Error> { - let filters = filters_from_version(self.node_build_version); - let mut connections = HashMap::new(); - let maybe_tasks = - (!self.allow_partial_connection).then(|| ConnectionTasks::new(filters.len())); - let guard = last_event_id_for_filter.lock().await; - for filter in filters { - let mut start_from_event_id = guard.get(&filter).copied(); - if start_from_event_id.is_none() { - start_from_event_id = Some(0); - } - let connection = self - .build_connection( - maybe_tasks.clone(), - start_from_event_id, - filter.clone(), - last_seen_event_id_sender.clone(), - ) - .await?; - connections.insert(filter, connection); - } - drop(guard); - Ok(connections) - } - fn status_endpoint(&self) -> Result { let status_endpoint_str = format!( "http://{}:{}/status", @@ -382,30 +344,11 @@ impl EventListener { try_resolve_version(response_json) } - async fn build_connection( - &self, - maybe_tasks: Option, - start_from_event_id: Option, - filter: Filter, - last_seen_event_id_sender: FilterWithEventId, - ) -> Result { - let bind_address_for_filter = self.filtered_sse_url(&filter)?; - let builder = ConnectionManagerBuilder { - bind_address: bind_address_for_filter, - max_attempts: self.max_connection_attempts, - sse_data_sender: self.sse_event_sender.clone(), - maybe_tasks, - connection_timeout: self.connection_timeout, - start_from_event_id, - filter, - current_event_id_sender: last_seen_event_id_sender, - sleep_between_keep_alive_checks: self.sleep_between_keep_alive_checks, - no_message_timeout: self.no_message_timeout, - }; - Ok(builder.build()) - } - async fn get_version(&mut self, current_attempt: usize) -> GetVersionResult { + info!( + "Attempting to connect...\t{}/{}", + current_attempt, self.max_connection_attempts + ); let fetch_result = self .fetch_build_version(self.node_build_version, current_attempt) .await; @@ -417,6 +360,7 @@ impl EventListener { GetVersionResult::Ok(None) } Err(BuildVersionFetchError::VersionNotAcceptable(msg)) => { + log_status_for_event_listener(EventListenerStatus::IncompatibleVersion, self); //The node has a build version which sidecar can't talk to. Failing fast in this case. GetVersionResult::Error(Error::msg(msg)) } @@ -447,7 +391,7 @@ impl EventListener { } fn start_connections( - connections: HashMap, + connections: HashMap>, ) -> Vec>> { connections .into_iter() @@ -500,8 +444,10 @@ fn try_resolve_version(raw_response: Value) -> Result { } } -fn filters_from_version(_build_version: ProtocolVersion) -> Vec { - vec![Filter::Main, Filter::Sigs, Filter::Deploys] +fn log_status_for_event_listener(status: EventListenerStatus, event_listener: &EventListener) { + let node_address = event_listener.node.ip_address.to_string(); + let sse_port = event_listener.node.sse_port; + status.log_status(node_address.as_str(), sse_port); } fn count_error(reason: &str) { @@ -522,44 +468,9 @@ fn validate_version(version: &ProtocolVersion) -> Result<(), BuildVersionFetchEr } } -#[cfg(test)] -mod tests { - - use anyhow::Error; - use casper_types::{ProtocolVersion, SemVer}; - use serde_json::json; - - use crate::{try_resolve_version, BUILD_VERSION_KEY}; - - #[test] - fn try_resolve_version_should_interpret_correct_build_version() { - let mut protocol = test_by_build_version(Some("5.1.111-b94c4f79a")).unwrap(); - assert_eq!(protocol, ProtocolVersion::new(SemVer::new(5, 1, 111))); - - protocol = test_by_build_version(Some("6.2.112-b94c4f79a-casper-mainnet")).unwrap(); - assert_eq!(protocol, ProtocolVersion::new(SemVer::new(6, 2, 112))); - - protocol = test_by_build_version(Some("7.3.113")).unwrap(); - assert_eq!(protocol, ProtocolVersion::new(SemVer::new(7, 3, 113))); - } - - #[test] - fn try_resolve_should_fail_if_build_version_is_absent() { - let ret = test_by_build_version(None); - assert!(ret.is_err()); - } - - #[test] - fn try_resolve_should_fail_if_build_version_is_invalid() { - let ret = test_by_build_version(Some("not-a-semver")); - assert!(ret.is_err()); - } - - fn test_by_build_version(build_version: Option<&str>) -> Result { - let json_object = match build_version { - Some(version) => json!({ BUILD_VERSION_KEY: version }), - None => json!({}), - }; - try_resolve_version(json_object) - } +fn warn_connection_lost(listener: &EventListener, current_attempt: usize) { + warn!( + "Lost connection to node {}, on attempt {}/{}", + listener.node.ip_address, current_attempt, listener.max_connection_attempts + ); } diff --git a/listener/src/sse_connector.rs b/listener/src/sse_connector.rs index 890c8d02..24d5a655 100644 --- a/listener/src/sse_connector.rs +++ b/listener/src/sse_connector.rs @@ -178,12 +178,11 @@ pub mod tests { convert::Infallible, pin::Pin, sync::Arc, - thread::sleep, time::{Duration, Instant}, }; - use tokio::time::timeout; - use tokio::{sync::mpsc::channel, time::interval}; - use tokio_stream::{wrappers::IntervalStream, StreamExt}; + use tokio::sync::mpsc::channel; + use tokio::time::{sleep, timeout}; + use tokio_stream::StreamExt; use url::Url; use warp::{sse::Event as SseEvent, Filter}; @@ -313,7 +312,7 @@ pub mod tests { #[tokio::test] async fn given_sse_connection_should_read_data() { let sse_port = portpicker::pick_unused_port().unwrap(); - spin_up_test_sse_endpoint(sse_port).await; + sse_server_finite_messages(sse_port).await; let mut connection = SseConnection { max_attempts: 5, delay_between_attempts: Duration::from_secs(2), @@ -351,21 +350,23 @@ pub mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn given_sse_connection_when_no_data_should_fail() { let sse_port = portpicker::pick_unused_port().unwrap(); - sse_server(sse_port, 1, Some(25)); + sse_server_messages_in_loop(sse_port, 1, 25); let mut connection = SseConnection { max_attempts: 5, delay_between_attempts: Duration::from_secs(2), connection_timeout: Duration::from_secs(10), - bind_address: Url::parse(format!("http://localhost:{}/ticks", sse_port).as_str()) - .unwrap(), + bind_address: Url::parse( + format!("http://localhost:{}/notifications", sse_port).as_str(), + ) + .unwrap(), sleep_between_keepalive_checks: Duration::from_secs(1), no_message_timeout: Duration::from_secs(5), }; let start = Instant::now(); let data = fetch_data_with_timeout(&mut connection, Duration::from_secs(20)).await; let elapsed = start.elapsed(); - assert!(elapsed.as_secs() >= 5); // It should take more then 5 seconds before the inactivity check kicks in assert!(data.is_empty()); + assert!(elapsed.as_secs() >= 5); // It should take more then 5 seconds before the inactivity check kicks in } #[tokio::test] @@ -393,7 +394,11 @@ pub mod tests { timeout_after: Duration, ) -> Vec { let mut data = vec![]; - if let Ok(mut receiver) = connection.connect(None).await { + let connection = timeout(Duration::from_secs(5), connection.connect(None)).await; + if connection.is_err() { + panic!("Couln't connect to sse endpoint in 5 seconds"); + } + if let Ok(mut receiver) = connection.unwrap() { while let Ok(res) = timeout(timeout_after, receiver.next()).await { if let Some(event_res) = res { if let Ok(event) = event_res { @@ -411,20 +416,36 @@ pub mod tests { fetch_data_with_timeout(connection, Duration::from_secs(120)).await } - fn sse_server(port: u16, interval_in_seconds: u64, mut initial_delay_in_seconds: Option) { - let routes = warp::path("ticks").and(warp::get()).map(move || { - let mut counter: u64 = 0; - // create server event source - let interval = interval(Duration::from_secs(interval_in_seconds)); - let stream = IntervalStream::new(interval); - let event_stream = stream.map(move |_| { - if let Some(delay) = initial_delay_in_seconds.take() { - sleep(Duration::from_secs(delay)); - } - counter += 1; - let event = warp::sse::Event::default().data(counter.to_string()); - Ok::(event) - }); + fn build_stream( + interval_in_seconds: u64, + initial_delay_in_seconds: u64, + ) -> impl Stream> { + let (tx, mut rx) = tokio::sync::mpsc::channel(10); + tokio::spawn(async move { + sleep(Duration::from_secs(initial_delay_in_seconds)).await; + let mut i = 0; + loop { + let _ = tx.send(i).await; + i += 1; + sleep(Duration::from_secs(interval_in_seconds)).await; + } + }); + stream! { + while let Some(z) = rx.recv().await { + let mut event = warp::sse::Event::default().data("abc".to_string()); + event = event.id(z.to_string()); + yield Ok(event); + } + } + } + + fn sse_server_messages_in_loop( + port: u16, + interval_in_seconds: u64, + initial_delay_in_seconds: u64, + ) { + let routes = warp::path("notifications").and(warp::get()).map(move || { + let event_stream = build_stream(interval_in_seconds, initial_delay_in_seconds); // reply using server-sent events // keep-alive is omitted intentionally so we can test scenarios in which the sse endpoint gives no traffic warp::sse::reply(event_stream) @@ -434,7 +455,7 @@ pub mod tests { }); } - async fn spin_up_test_sse_endpoint(sse_port: u16) { + async fn sse_server_finite_messages(sse_port: u16) { fn sse_events() -> impl futures_util::Stream> { iter(vec![ Ok(SseEvent::default().data("msg 1")), diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1c57d8c0..bbd3374c 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.73.0" +channel = "1.74.0" components = [ "rustfmt", "clippy" ] targets = [ "wasm32-unknown-unknown" ] profile = "minimal" \ No newline at end of file diff --git a/sidecar/src/event_stream_server/sse_server.rs b/sidecar/src/event_stream_server/sse_server.rs index f5e14032..15dc64e6 100644 --- a/sidecar/src/event_stream_server/sse_server.rs +++ b/sidecar/src/event_stream_server/sse_server.rs @@ -494,7 +494,6 @@ impl ChannelsAndFilter { /// /// It also takes an `EventFilter` which causes events to which the client didn't subscribe to be /// skipped. -#[allow(clippy::too_many_lines)] fn stream_to_client( initial_events: mpsc::UnboundedReceiver, ongoing_events: broadcast::Receiver, @@ -513,29 +512,35 @@ fn stream_to_client( async move { match result { Ok(BroadcastChannelMessage::ServerSentEvent(event)) => { - if let Some(id) = event.id { - if cloned_initial_ids.read().unwrap().contains(&id) { - debug!(event_id=%id, "skipped duplicate event"); - return None; - } - } - Some(Ok(event)) + handle_sse_event(event, cloned_initial_ids) } Ok(BroadcastChannelMessage::Shutdown) => Some(Err(RecvError::Closed)), - Err(BroadcastStreamRecvError::Lagged(amount)) => { - info!( - "client lagged by {} events - dropping event stream connection to client", - amount - ); - Some(Err(RecvError::Lagged(amount))) - } + Err(BroadcastStreamRecvError::Lagged(amount)) => handle_lagged(amount), } } }) - .take_while(|result| future::ready(!matches!(result, Err(RecvError::Closed)))); + .take_while(|result| future::ready(!matches!(result, Err(RecvError::Closed)))) + .boxed(); + + build_combined_events_stream( + initial_events, + initial_stream_ids, + ongoing_stream, + stream_filter, + event_filter, + ) +} - // Serve the initial events followed by the ongoing ones, filtering as dictated by the - // `event_filter`. +// Builds stream that serves the initial events followed by the ongoing ones, filtering as dictated by the `event_filter`. +fn build_combined_events_stream( + initial_events: mpsc::UnboundedReceiver, + initial_stream_ids: Arc>>, + ongoing_stream: std::pin::Pin< + Box> + Send>, + >, + stream_filter: &'static Endpoint, + event_filter: &'static [EventFilter], +) -> impl Stream> + 'static { UnboundedReceiverStream::new(initial_events) .map(move |event| { if let Some(id) = event.id { @@ -567,6 +572,27 @@ fn stream_to_client( }) } +fn handle_lagged(amount: u64) -> Option> { + info!( + "client lagged by {} events - dropping event stream connection to client", + amount + ); + Some(Err(RecvError::Lagged(amount))) +} + +fn handle_sse_event( + event: ServerSentEvent, + cloned_initial_ids: Arc>>, +) -> Option> { + if let Some(id) = event.id { + if cloned_initial_ids.read().unwrap().contains(&id) { + debug!(event_id=%id, "skipped duplicate event"); + return None; + } + } + Some(Ok(event)) +} + #[cfg(test)] mod tests { use super::*; diff --git a/sidecar/src/event_stream_server/tests.rs b/sidecar/src/event_stream_server/tests.rs index cec3d028..3f4c64dd 100644 --- a/sidecar/src/event_stream_server/tests.rs +++ b/sidecar/src/event_stream_server/tests.rs @@ -39,7 +39,7 @@ const MAX_EVENT_COUNT: u32 = 100_000_000; const BUFFER_LENGTH: u32 = EVENT_COUNT / 2; /// The maximum amount of time to wait for a test server to complete. If this time is exceeded, the /// test has probably hung, and should be deemed to have failed. -const MAX_TEST_TIME: Duration = Duration::from_secs(4); +const MAX_TEST_TIME: Duration = Duration::from_secs(10); /// The duration of the sleep called between each event being sent by the server. const DELAY_BETWEEN_EVENTS: Duration = Duration::from_millis(1); diff --git a/sidecar/src/main.rs b/sidecar/src/main.rs index 0fc955f3..ca78bbdc 100644 --- a/sidecar/src/main.rs +++ b/sidecar/src/main.rs @@ -54,6 +54,7 @@ use tokio::{ time::sleep, }; use tracing::{debug, error, info, trace, warn}; +use types::config::Connection; use types::{ config::StorageConfig, database::{Database, DatabaseReader}, @@ -154,7 +155,7 @@ fn start_event_broadcasting( } fn start_sse_processors( - connection_configs: Vec, + connection_configs: Vec, event_listeners: Vec, sse_data_receivers: Vec>, database: Database, @@ -206,7 +207,7 @@ fn spawn_sse_processor( database: &Database, sse_data_receiver: Receiver, outbound_sse_data_sender: &Sender<(SseData, Option, Option)>, - connection_config: types::config::Connection, + connection_config: Connection, api_version_manager: &std::sync::Arc>, ) -> JoinHandle> { match database.clone() { @@ -288,41 +289,45 @@ fn build_event_listeners( for connection in &config.connections { let (inbound_sse_data_sender, inbound_sse_data_receiver) = mpsc_channel(config.inbound_channel_size.unwrap_or(DEFAULT_CHANNEL_SIZE)); - sse_data_receivers.push(inbound_sse_data_receiver); - - let node_interface = NodeConnectionInterface { - ip_address: IpAddr::from_str(&connection.ip_address)?, - sse_port: connection.sse_port, - rest_port: connection.rest_port, - }; - - let event_listener = EventListenerBuilder { - node: node_interface, - max_connection_attempts: connection.max_attempts, - delay_between_attempts: Duration::from_secs( - connection.delay_between_retries_in_seconds as u64, - ), - allow_partial_connection: connection.allow_partial_connection, - sse_event_sender: inbound_sse_data_sender, - connection_timeout: Duration::from_secs( - connection.connection_timeout_in_seconds.unwrap_or(5) as u64, - ), - sleep_between_keep_alive_checks: Duration::from_secs( - connection - .sleep_between_keep_alive_checks_in_seconds - .unwrap_or(60) as u64, - ), - no_message_timeout: Duration::from_secs( - connection.no_message_timeout_in_seconds.unwrap_or(120) as u64, - ), - } - .build(); - event_listeners.push(event_listener); + let event_listener = builder(connection, inbound_sse_data_sender)?.build(); + event_listeners.push(event_listener?); } Ok((event_listeners, sse_data_receivers)) } +fn builder( + connection: &Connection, + inbound_sse_data_sender: Sender, +) -> Result { + let node_interface = NodeConnectionInterface { + ip_address: IpAddr::from_str(&connection.ip_address)?, + sse_port: connection.sse_port, + rest_port: connection.rest_port, + }; + let event_listener_builder = EventListenerBuilder { + node: node_interface, + max_connection_attempts: connection.max_attempts, + delay_between_attempts: Duration::from_secs( + connection.delay_between_retries_in_seconds as u64, + ), + allow_partial_connection: connection.allow_partial_connection, + sse_event_sender: inbound_sse_data_sender, + connection_timeout: Duration::from_secs( + connection.connection_timeout_in_seconds.unwrap_or(5) as u64, + ), + sleep_between_keep_alive_checks: Duration::from_secs( + connection + .sleep_between_keep_alive_checks_in_seconds + .unwrap_or(60) as u64, + ), + no_message_timeout: Duration::from_secs( + connection.no_message_timeout_in_seconds.unwrap_or(120) as u64, + ), + }; + Ok(event_listener_builder) +} + fn validate_config(config: &Config) -> Result<(), Error> { if config .connections diff --git a/sidecar/src/rest_server/errors.rs b/sidecar/src/rest_server/errors.rs index 0ee764cb..47faffe7 100644 --- a/sidecar/src/rest_server/errors.rs +++ b/sidecar/src/rest_server/errors.rs @@ -32,7 +32,6 @@ impl reject::Reject for StorageError {} /// - Database-related errors /// - Invalid request path errors /// - Invalid parameters in the request query -#[allow(clippy::too_many_lines)] pub(super) async fn handle_rejection(err: Rejection) -> Result { let code; let message; @@ -46,20 +45,7 @@ pub(super) async fn handle_rejection(err: Rejection) -> Result { - code = StatusCode::NOT_FOUND; - message = "Query returned no results".to_string(); - } - DatabaseReadError::Serialisation(err) => { - code = StatusCode::INTERNAL_SERVER_ERROR; - message = format!("Error deserializing returned data: {}", err) - } - DatabaseReadError::Unhandled(err) => { - code = StatusCode::INTERNAL_SERVER_ERROR; - message = format!("Unhandled error occurred in storage: {}", err) - } - } + (code, message) = status_code_and_err_message_for_read_error(err); } else if let Some(InvalidPath) = err.find() { code = StatusCode::BAD_REQUEST; message = "Invalid request path provided".to_string(); @@ -67,13 +53,7 @@ pub(super) async fn handle_rejection(err: Rejection) -> Result Result (StatusCode, String) { + let err_msg = format!( + "Unexpected error in REST server - please file a bug report!\n{:?}", + err + ); + error!(%err_msg); + (StatusCode::INTERNAL_SERVER_ERROR, err_msg) +} + +fn status_code_and_err_message_for_read_error(err: &DatabaseReadError) -> (StatusCode, String) { + match err { + DatabaseReadError::NotFound => ( + StatusCode::NOT_FOUND, + "Query returned no results".to_string(), + ), + DatabaseReadError::Serialisation(err) => ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Error deserializing returned data: {}", err), + ), + DatabaseReadError::Unhandled(err) => ( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Unhandled error occurred in storage: {}", err), + ), + } +} + #[cfg(test)] async fn get_api_error_from_rejection(rejection: Rejection) -> ApiError { let response = handle_rejection(rejection) diff --git a/sidecar/src/tests/performance_tests.rs b/sidecar/src/tests/performance_tests.rs index 9e49330b..bc3d3f0f 100644 --- a/sidecar/src/tests/performance_tests.rs +++ b/sidecar/src/tests/performance_tests.rs @@ -1,22 +1,3 @@ -use std::{ - collections::HashMap, - fmt::{Display, Formatter}, - net::IpAddr, - str::FromStr, - time::Duration, -}; - -use casper_event_types::sse_data::SseData; -use colored::Colorize; -use derive_new::new; -use tabled::{object::Cell, Alignment, ModifyObject, Span, Style, TableIteratorExt, Tabled}; -use tempfile::tempdir; -use tokio::{ - sync::mpsc::{self, Receiver}, - task::JoinHandle, - time::{sleep, Instant}, -}; - use crate::{ database::postgresql_database::PostgreSqlDatabase, run, @@ -37,7 +18,24 @@ use crate::{ utils::tests::display_duration, }; use casper_event_listener::{EventListenerBuilder, NodeConnectionInterface, SseEvent}; +use casper_event_types::sse_data::SseData; use casper_types::{testing::TestRng, AsymmetricType}; +use colored::Colorize; +use derive_new::new; +use std::{ + collections::HashMap, + fmt::{Display, Formatter}, + net::IpAddr, + str::FromStr, + time::Duration, +}; +use tabled::{object::Cell, Alignment, ModifyObject, Span, Style, TableIteratorExt, Tabled}; +use tempfile::tempdir; +use tokio::{ + sync::mpsc::{self, Receiver}, + task::JoinHandle, + time::{sleep, Instant}, +}; use tokio_util::sync::CancellationToken; const ACCEPTABLE_LATENCY: Duration = Duration::from_millis(1000); @@ -277,14 +275,13 @@ async fn performance_check(scenario: Scenario, duration: Duration, acceptable_la tokio::spawn(run(testing_config.inner())); tokio::time::sleep(Duration::from_secs(1)).await; - + let ip_address = IpAddr::from_str("127.0.0.1").expect("Couldn't parse IpAddr"); let node_interface = NodeConnectionInterface { - ip_address: IpAddr::from_str("127.0.0.1").expect("Couldn't parse IpAddr"), + ip_address, sse_port: node_port_for_sse_connection, rest_port: node_port_for_rest_connection, }; let (node_event_tx, node_event_rx) = mpsc::channel(100); - let mut node_event_listener = EventListenerBuilder { node: node_interface, max_connection_attempts: 5, @@ -295,7 +292,8 @@ async fn performance_check(scenario: Scenario, duration: Duration, acceptable_la sleep_between_keep_alive_checks: Duration::from_secs(100), no_message_timeout: Duration::from_secs(100), } - .build(); + .build() + .unwrap(); tokio::spawn(async move { let res = node_event_listener.stream_aggregated_events().await; @@ -311,7 +309,6 @@ async fn performance_check(scenario: Scenario, duration: Duration, acceptable_la sse_port: node_port_for_sse_connection, rest_port: node_port_for_rest_connection, }; - let mut sidecar_event_listener = EventListenerBuilder { node: sidecar_node_interface, max_connection_attempts: 5, @@ -322,7 +319,8 @@ async fn performance_check(scenario: Scenario, duration: Duration, acceptable_la sleep_between_keep_alive_checks: Duration::from_secs(100), no_message_timeout: Duration::from_secs(100), } - .build(); + .build() + .unwrap(); tokio::spawn(async move { let res = sidecar_event_listener.stream_aggregated_events().await; if let Err(error) = res {