From 50d67665efcf64a5cf90de8e0db138e555a77986 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Mon, 27 Nov 2023 19:47:57 +0530 Subject: [PATCH 01/20] chore: update dependencies(rumqttc) --- Cargo.lock | 1160 ++++++++++++++++++----------------- uplink/src/base/mqtt/mod.rs | 4 +- 2 files changed, 593 insertions(+), 571 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a75a0209..998c5689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "afl" version = "0.8.0" @@ -17,9 +32,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -50,19 +65,19 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -98,14 +113,14 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "bitflags", - "bytes 1.4.0", + "bitflags 1.3.2", + "bytes 1.5.0", "futures-util", "http", "http-body", @@ -115,14 +130,14 @@ dependencies = [ "memchr", "mime", "percent-encoding", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", "rustversion", "serde", "serde_json", "serde_path_to_error", "serde_urlencoded", "sync_wrapper", - "tokio 1.28.2", + "tokio 1.34.0", "tower", "tower-layer", "tower-service", @@ -135,7 +150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", - "bytes 1.4.0", + "bytes 1.5.0", "futures-util", "http", "http-body", @@ -145,6 +160,21 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.11.0" @@ -159,9 +189,9 @@ checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bincode" @@ -188,6 +218,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "block-buffer" version = "0.9.0" @@ -199,15 +235,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -217,17 +253,18 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -263,7 +300,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim 0.8.0", "textwrap", "unicode-width", @@ -272,9 +309,9 @@ dependencies = [ [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "lazy_static", @@ -323,23 +360,13 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -353,9 +380,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if 1.0.0", @@ -366,9 +393,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if 1.0.0", ] @@ -379,10 +406,10 @@ version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio 0.8.8", + "mio 0.8.9", "parking_lot", "signal-hook", "signal-hook-mio", @@ -391,9 +418,9 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ "winapi 0.3.9", ] @@ -419,7 +446,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -430,9 +457,25 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.18", + "syn 2.0.39", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", + "serde", ] +[[package]] +name = "deunicode" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" + [[package]] name = "digest" version = "0.9.0" @@ -444,27 +487,27 @@ dependencies = [ [[package]] name = "dummy" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba338a15d93c01c2f117a2b0bd1bfa3c780fe771e7db7c69fc70bda265e2115" +checksum = "7e57e12b69e57fad516e01e2b3960f122696fdb13420e1a88ed8e210316f2876" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if 1.0.0", ] @@ -486,7 +529,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -521,13 +564,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" dependencies = [ - "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -542,23 +584,20 @@ dependencies = [ [[package]] name = "fake" -version = "2.8.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af7b0c58ac9d03169e27f080616ce9f64004edca3d2ef4147a811c21b23b319" +checksum = "26221445034074d46b276e13eb97a265ebdb8ed8da705c4dddd3dd20b66b45d2" dependencies = [ + "deunicode", "dummy", "rand 0.8.5", - "unidecode", ] [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "filedescriptor" @@ -573,14 +612,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.16", - "windows-sys 0.48.0", + "redox_syscall 0.3.5", + "windows-sys", ] [[package]] @@ -592,7 +631,18 @@ dependencies = [ "futures-core", "futures-sink", "nanorand", - "pin-project 1.1.0", + "pin-project 1.1.3", + "spin 0.9.8", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", "spin 0.9.8", ] @@ -619,9 +669,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", ] @@ -648,7 +698,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags", + "bitflags 1.3.2", "fuchsia-zircon-sys", ] @@ -660,9 +710,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[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", @@ -675,9 +725,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", @@ -685,15 +735,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", @@ -702,38 +752,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", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[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-test" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84af27744870a4a325fa342ce65a940dfba08957b260b790ec278c1d81490349" +checksum = "73ad78d6c79a3c76f8bc7496240d0586e069ed6797824fdd8c41d7c42b145b8d" dependencies = [ "futures-core", "futures-executor", @@ -742,15 +792,15 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "pin-project 1.1.0", + "pin-project 1.1.3", "pin-utils", ] [[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", @@ -759,7 +809,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", "pin-utils", "slab", ] @@ -796,9 +846,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 1.0.0", "js-sys", @@ -819,13 +869,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "git2" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", "libgit2-sys", "log", @@ -840,20 +896,20 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.19" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "futures-core", "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", - "tokio 1.28.2", - "tokio-util 0.7.8", + "tokio 1.34.0", + "tokio-util 0.7.10", "tracing", ] @@ -865,9 +921,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -889,18 +945,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -908,22 +955,13 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - [[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 1.4.0", + "bytes 1.5.0", "fnv", "itoa", ] @@ -934,9 +972,9 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "http", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", ] [[package]] @@ -947,15 +985,15 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "human_bytes" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27e2b089f28ad15597b48d8c0a8fe94eeb1c1cb26ca99b6f66ac9582ae10c5e6" +checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e" [[package]] name = "humantime" @@ -968,11 +1006,11 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-channel", "futures-core", "futures-util", @@ -982,9 +1020,9 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.9", - "socket2 0.4.9", - "tokio 1.28.2", + "pin-project-lite 0.2.13", + "socket2 0.4.10", + "tokio 1.34.0", "tower-service", "tracing", "want", @@ -992,29 +1030,30 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.21.1", - "tokio 1.28.2", + "rustls 0.21.9", + "tokio 1.34.0", "tokio-rustls 0.24.1", ] [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1034,9 +1073,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[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", @@ -1055,12 +1094,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.1", + "hashbrown 0.14.3", "serde", ] @@ -1073,26 +1112,6 @@ dependencies = [ "bytes 0.5.6", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ioctl-rs" version = "0.1.6" @@ -1113,30 +1132,30 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.7.2" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -1159,9 +1178,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libgit2-sys" @@ -1177,9 +1196,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.9" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" dependencies = [ "cc", "libc", @@ -1189,15 +1208,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1205,9 +1224,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.18" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lz4_flex" @@ -1224,26 +1243,26 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -1266,6 +1285,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.6.23" @@ -1287,14 +1315,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1347,7 +1375,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9b7801639a5398353b9acf0764907d6571ca92e6b7a3662013b03861789449c" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", ] [[package]] @@ -1356,7 +1384,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.11", ] [[package]] @@ -1379,9 +1407,9 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.38" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" +checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" dependencies = [ "cfg-if 0.1.10", "libc", @@ -1424,14 +1452,23 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.3", "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1446,11 +1483,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.54" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ - "bitflags", + "bitflags 2.4.1", "cfg-if 1.0.0", "foreign-types", "libc", @@ -1467,7 +1504,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -1478,18 +1515,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.26.0+1.1.1u" +version = "300.1.6+3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.88" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ "cc", "libc", @@ -1510,13 +1547,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "smallvec", "windows-targets", ] @@ -1529,9 +1566,9 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[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 = "pin-project" @@ -1544,11 +1581,11 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ - "pin-project-internal 1.1.0", + "pin-project-internal 1.1.3", ] [[package]] @@ -1564,13 +1601,13 @@ dependencies = [ [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -1581,9 +1618,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1646,7 +1683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dfe828cdc03091f621a7c9a257769fbb9c66d75f7e45d0fbb563fa3bf669815" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "filedescriptor", "lazy_static", "libc", @@ -1658,6 +1695,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1710,9 +1753,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -1725,9 +1768,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1819,7 +1862,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.11", ] [[package]] @@ -1833,9 +1876,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1843,14 +1886,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -1864,31 +1905,32 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -1900,6 +1942,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -1908,9 +1961,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "remote-pty-common" @@ -1946,12 +1999,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.2", - "bytes 1.4.0", + "base64 0.21.5", + "bytes 1.5.0", "encoding_rs", "futures-core", "futures-util", @@ -1966,22 +2019,23 @@ dependencies = [ "mime", "once_cell", "percent-encoding", - "pin-project-lite 0.2.9", - "rustls 0.21.1", + "pin-project-lite 0.2.13", + "rustls 0.21.9", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "tokio 1.28.2", + "system-configuration", + "tokio 1.34.0", "tokio-rustls 0.24.1", - "tokio-util 0.7.8", + "tokio-util 0.7.10", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.22.6", + "webpki-roots 0.25.3", "winreg", ] @@ -1995,28 +2049,48 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi 0.3.9", ] +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom 0.2.11", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + [[package]] name = "rumqttc" -version = "0.22.0" -source = "git+https://github.com/bytebeamio/rumqtt#714f71c9bc3369fa186353201dc2e8197d07594c" +version = "0.23.0" +source = "git+https://github.com/bytebeamio/rumqtt#22d7fae16e3be9cc4f65b49eb31b2fe425aa9e3f" dependencies = [ - "bytes 1.4.0", - "flume", - "futures", + "bytes 1.5.0", + "flume 0.11.0", + "futures-util", "log", "rustls-native-certs", "rustls-pemfile", "rustls-webpki", "thiserror", - "tokio 1.28.2", + "tokio 1.34.0", "tokio-rustls 0.24.1", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2032,21 +2106,20 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.17", + "semver 1.0.20", ] [[package]] name = "rustix" -version = "0.37.19" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ - "bitflags", - "errno 0.3.1", - "io-lifetimes", + "bitflags 2.4.1", + "errno 0.3.7", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2057,28 +2130,28 @@ checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" dependencies = [ "base64 0.11.0", "log", - "ring", + "ring 0.16.20", "sct 0.6.1", - "webpki 0.21.4", + "webpki", ] [[package]] name = "rustls" -version = "0.21.1" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", - "ring", + "ring 0.17.5", "rustls-webpki", - "sct 0.7.0", + "sct 0.7.1", ] [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -2088,49 +2161,49 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -2138,18 +2211,18 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] @@ -2160,11 +2233,11 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2173,9 +2246,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2192,9 +2265,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "semver-parser" @@ -2204,29 +2277,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -2235,10 +2308,11 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ + "itoa", "serde", ] @@ -2256,15 +2330,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ - "base64 0.21.2", + "base64 0.21.5", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_json", "serde_with_macros", @@ -2273,14 +2347,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -2336,9 +2410,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2361,9 +2435,9 @@ checksum = "39acde55a154c4cd3ae048ac78cc21c25f3a0145e44111b523279113dce0d94a" [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ "libc", "signal-hook-registry", @@ -2376,7 +2450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", - "mio 0.8.8", + "mio 0.8.9", "signal-hook", ] @@ -2398,29 +2472,29 @@ dependencies = [ "futures-core", "libc", "signal-hook", - "tokio 1.28.2", + "tokio 1.34.0", ] [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi 0.3.9", @@ -2428,12 +2502,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -2461,7 +2535,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" name = "storage" version = "0.1.0" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "log", "mqttbytes", "pretty_env_logger", @@ -2517,9 +2591,9 @@ dependencies = [ "parking_lot", "pnet_packet", "rand 0.8.5", - "socket2 0.5.3", + "socket2 0.5.5", "thiserror", - "tokio 1.28.2", + "tokio 1.34.0", "tracing", ] @@ -2536,9 +2610,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -2580,11 +2654,32 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tar" -version = "0.4.38" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" dependencies = [ "filetime", "libc", @@ -2603,23 +2698,22 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ - "autocfg", "cfg-if 1.0.0", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -2644,22 +2738,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -2674,11 +2768,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ + "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -2686,15 +2782,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -2739,21 +2835,21 @@ dependencies = [ [[package]] name = "tokio" -version = "1.28.2" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ - "autocfg", - "bytes 1.4.0", + "backtrace", + "bytes 1.5.0", "libc", - "mio 0.8.8", + "mio 0.8.9", "num_cpus", "parking_lot", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", "signal-hook-registry", - "socket2 0.4.9", - "tokio-macros 2.1.0", - "windows-sys 0.48.0", + "socket2 0.5.5", + "tokio-macros 2.2.0", + "windows-sys", ] [[package]] @@ -2764,9 +2860,9 @@ checksum = "e7d4237822b7be8fff0a7a27927462fad435dcb6650f95cea9e946bf6bdc7e07" dependencies = [ "bytes 0.5.6", "once_cell", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", "tokio 0.2.25", - "tokio 1.28.2", + "tokio 1.34.0", "tokio-stream", ] @@ -2783,13 +2879,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", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] @@ -2811,7 +2907,7 @@ dependencies = [ "futures-core", "rustls 0.17.0", "tokio 0.2.25", - "webpki 0.21.4", + "webpki", ] [[package]] @@ -2820,8 +2916,8 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.1", - "tokio 1.28.2", + "rustls 0.21.9", + "tokio 1.34.0", ] [[package]] @@ -2831,8 +2927,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", - "pin-project-lite 0.2.9", - "tokio 1.28.2", + "pin-project-lite 0.2.13", + "tokio 1.34.0", ] [[package]] @@ -2852,16 +2948,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-core", "futures-sink", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", "slab", - "tokio 1.28.2", + "tokio 1.34.0", "tracing", ] @@ -2882,9 +2978,9 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "pin-project 1.1.0", - "pin-project-lite 0.2.9", - "tokio 1.28.2", + "pin-project 1.1.3", + "pin-project-lite 0.2.13", + "tokio 1.34.0", "tower-layer", "tower-service", "tracing", @@ -2904,33 +3000,32 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.9", + "pin-project-lite 0.2.13", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -2938,12 +3033,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -3005,7 +3100,7 @@ dependencies = [ "crossterm", "env_logger", "futures", - "getrandom 0.2.10", + "getrandom 0.2.11", "js-sys", "libc", "log", @@ -3015,7 +3110,7 @@ dependencies = [ "rand 0.7.3", "remote-pty-common", "remote-pty-master", - "ring", + "ring 0.16.20", "serde", "serde_json", "thiserror", @@ -3028,7 +3123,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki 0.21.4", + "webpki", "webpki-roots 0.19.0", "wee_alloc", ] @@ -3060,9 +3155,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uds_windows" @@ -3082,9 +3177,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -3103,21 +3198,21 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] -name = "unidecode" -version = "0.3.0" +name = "untrusted" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "uplink" @@ -3126,10 +3221,10 @@ dependencies = [ "anyhow", "async-trait", "axum", - "bytes 1.4.0", + "bytes 1.5.0", "config", "fake", - "flume", + "flume 0.10.14", "fs2", "futures-util", "human_bytes", @@ -3154,10 +3249,10 @@ dependencies = [ "tempdir", "thiserror", "time", - "tokio 1.28.2", + "tokio 1.34.0", "tokio-compat-02", "tokio-stream", - "tokio-util 0.7.8", + "tokio-util 0.7.10", "tracing", "tracing-subscriber", "tunshell-client", @@ -3166,9 +3261,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -3185,13 +3280,13 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" name = "utils" version = "0.1.0" dependencies = [ - "flume", + "flume 0.10.14", "futures-util", "serde", "serde_json", - "tokio 1.28.2", + "tokio 1.34.0", "tokio-stream", - "tokio-util 0.7.8", + "tokio-util 0.7.10", "uplink", ] @@ -3245,11 +3340,10 @@ checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -3267,9 +3361,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3277,24 +3371,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3304,9 +3398,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3314,28 +3408,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -3346,9 +3440,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", @@ -3360,18 +3454,8 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3380,17 +3464,14 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739" dependencies = [ - "webpki 0.21.4", + "webpki", ] [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki 0.22.0", -] +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "wee_alloc" @@ -3434,9 +3515,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi 0.3.9", ] @@ -3448,29 +3529,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ "windows-targets", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -3482,110 +3548,69 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi 0.3.9", + "cfg-if 1.0.0", + "windows-sys", ] [[package]] @@ -3600,18 +3625,15 @@ dependencies = [ [[package]] name = "xattr" -version = "0.2.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", ] [[package]] name = "xdg" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688597db5a750e9cad4511cb94729a078e274308099a0382b5b8203bbc767fee" -dependencies = [ - "home", -] +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" diff --git a/uplink/src/base/mqtt/mod.rs b/uplink/src/base/mqtt/mod.rs index 07026aad..6e408750 100644 --- a/uplink/src/base/mqtt/mod.rs +++ b/uplink/src/base/mqtt/mod.rs @@ -10,7 +10,7 @@ use std::path::Path; use crate::{Action, Config}; use rumqttc::{ - AsyncClient, ConnectionError, Event, EventLoop, Incoming, Key, MqttOptions, Publish, QoS, + AsyncClient, ConnectionError, Event, EventLoop, Incoming, MqttOptions, Publish, QoS, TlsConfiguration, Transport, }; use std::sync::Arc; @@ -195,7 +195,7 @@ fn mqttoptions(config: &Config) -> MqttOptions { let transport = Transport::Tls(TlsConfiguration::Simple { ca, alpn: None, - client_auth: Some((device_certificate, Key::RSA(device_private_key))), + client_auth: Some((device_certificate, device_private_key)), }); mqttoptions.set_transport(transport); From c1affbcc3e47f035d4ca252541fe1b442ba2c1b3 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 5 Dec 2023 18:52:46 +0530 Subject: [PATCH 02/20] feat: track disk space utilized by persistence (#312) * feat: track disk space utilized by persistence * feat: track disk utilization by persistence * log: disk utilization * fix: call the right method * fix: init `bytes_occupied` * log: add missing line * doc: why `disk_utilized` --- storage/src/lib.rs | 28 ++++++++++++++++++++++++++- uplink/src/base/serializer/metrics.rs | 7 +++++++ uplink/src/base/serializer/mod.rs | 18 ++++++++++++++--- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/storage/src/lib.rs b/storage/src/lib.rs index 03919e21..02a009a9 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -70,6 +70,13 @@ impl Storage { } } + pub fn disk_utilized(&self) -> usize { + match &self.persistence { + Some(p) => p.bytes_occupied, + None => 0, + } + } + pub fn inmemory_read_size(&self) -> usize { self.current_read_file.len() } @@ -97,6 +104,10 @@ impl Storage { next_file.file.write_all(&hash.to_be_bytes())?; next_file.file.write_all(&self.current_write_file[..])?; next_file.file.flush()?; + + // 8 is the number of bytes the hash(u64) occupies + persistence.bytes_occupied += 8 + self.current_write_file.len(); + self.current_write_file.clear(); Ok(next_file.deleted) } @@ -213,6 +224,8 @@ struct Persistence { // /// Deleted file id // deleted: Option, non_destructive_read: bool, + /// Disk space(in bytes) currently occupied by persistence files + bytes_occupied: usize, } impl Persistence { @@ -221,6 +234,13 @@ impl Persistence { let backlog_files = get_file_ids(&path)?; info!("List of file ids loaded from disk: {backlog_files:?}"); + let bytes_occupied = backlog_files.iter().fold(0, |acc, id| { + let mut file = PathBuf::from(&path); + let file_name = format!("backup@{id}"); + file.push(file_name); + fs::metadata(&file).unwrap().len() as usize + acc + }); + Ok(Persistence { path, max_file_count, @@ -228,6 +248,7 @@ impl Persistence { current_read_file_id: None, // deleted: None, non_destructive_read: false, + bytes_occupied, }) } @@ -239,8 +260,13 @@ impl Persistence { } /// Removes a file with provided id - fn remove(&self, id: u64) -> Result { + fn remove(&mut self, id: u64) -> Result { let path = self.path(id)?; + + // Query the fs to track size of removed persistence file + let metadata = fs::metadata(&path)?; + self.bytes_occupied -= metadata.len() as usize; + fs::remove_file(&path)?; Ok(path) diff --git a/uplink/src/base/serializer/metrics.rs b/uplink/src/base/serializer/metrics.rs index 2844aead..68e1fc43 100644 --- a/uplink/src/base/serializer/metrics.rs +++ b/uplink/src/base/serializer/metrics.rs @@ -17,6 +17,8 @@ pub struct SerializerMetrics { pub read_memory: usize, /// Number of files that have been written to disk pub disk_files: usize, + /// Disk size currently occupied by persistence files + pub disk_utilized: usize, /// Nuber of persistence files that had to deleted before being consumed pub lost_segments: usize, /// Number of errors faced during serializer operation @@ -35,6 +37,7 @@ impl SerializerMetrics { write_memory: 0, read_memory: 0, disk_files: 0, + disk_utilized: 0, lost_segments: 0, errors: 0, sent_size: 0, @@ -68,6 +71,10 @@ impl SerializerMetrics { self.disk_files = count; } + pub fn set_disk_utilized(&mut self, bytes: usize) { + self.disk_utilized = bytes; + } + pub fn increment_errors(&mut self) { self.errors += 1; } diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index 60330834..aedb4ff2 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -578,24 +578,28 @@ fn check_metrics(metrics: &mut SerializerMetrics, storage_handler: &StorageHandl let mut inmemory_write_size = 0; let mut inmemory_read_size = 0; let mut file_count = 0; + let mut disk_utilized = 0; for storage in storage_handler.map.values() { inmemory_read_size += storage.inmemory_read_size(); inmemory_write_size += storage.inmemory_write_size(); file_count += storage.file_count(); + disk_utilized += storage.disk_utilized(); } metrics.set_write_memory(inmemory_write_size); metrics.set_read_memory(inmemory_read_size); metrics.set_disk_files(file_count); + metrics.set_disk_utilized(disk_utilized); info!( - "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} write_memory = {} read_memory = {}", + "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} disk_utilized = {} write_memory = {} read_memory = {}", metrics.mode, metrics.batches, metrics.errors, metrics.lost_segments, metrics.disk_files, + convert(metrics.disk_utilized as f64), convert(metrics.write_memory as f64), convert(metrics.read_memory as f64), ); @@ -609,16 +613,19 @@ fn save_and_prepare_next_metrics( let mut inmemory_write_size = 0; let mut inmemory_read_size = 0; let mut file_count = 0; + let mut disk_utilized = 0; for storage in storage_handler.map.values() { inmemory_write_size += storage.inmemory_write_size(); inmemory_read_size += storage.inmemory_read_size(); file_count += storage.file_count(); + disk_utilized += storage.disk_utilized(); } metrics.set_write_memory(inmemory_write_size); metrics.set_read_memory(inmemory_read_size); metrics.set_disk_files(file_count); + metrics.set_disk_utilized(disk_utilized); let m = metrics.clone(); pending.push_back(m); @@ -637,27 +644,31 @@ fn check_and_flush_metrics( let mut inmemory_write_size = 0; let mut inmemory_read_size = 0; let mut file_count = 0; + let mut disk_utilized = 0; for storage in storage_handler.map.values() { inmemory_write_size += storage.inmemory_write_size(); inmemory_read_size += storage.inmemory_read_size(); file_count += storage.file_count(); + disk_utilized += storage.disk_utilized(); } metrics.set_write_memory(inmemory_write_size); metrics.set_read_memory(inmemory_read_size); metrics.set_disk_files(file_count); + metrics.set_disk_utilized(disk_utilized); // Send pending metrics. This signifies state change while let Some(metrics) = pending.get(0) { // Always send pending metrics. They represent state changes info!( - "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} write_memory = {} read_memory = {}", + "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} disk_utilized = {} write_memory = {} read_memory = {}", metrics.mode, metrics.batches, metrics.errors, metrics.lost_segments, metrics.disk_files, + convert(metrics.disk_utilized as f64), convert(metrics.write_memory as f64), convert(metrics.read_memory as f64), ); @@ -667,12 +678,13 @@ fn check_and_flush_metrics( if metrics.batches() > 0 { info!( - "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} write_memory = {} read_memory = {}", + "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} disk_utilized = {} write_memory = {} read_memory = {}", metrics.mode, metrics.batches, metrics.errors, metrics.lost_segments, metrics.disk_files, + convert(metrics.disk_utilized as f64), convert(metrics.write_memory as f64), convert(metrics.read_memory as f64), ); From f1dbca65c49b76f6195d95258b0aec8221c7b21b Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 5 Dec 2023 18:57:52 +0530 Subject: [PATCH 03/20] refactor: use `StreamConfig` in `Serializer` (#296) * refactor: use `StreamConfig` in `Serializer` * test: fix stream config * refactor: rm compression from `Stream`/`Buffer` * style: `stream_name`/`stream_config` * refactor: `new` replaces `with_config` --- uplink/src/base/bridge/mod.rs | 22 ++-- uplink/src/base/bridge/stream.rs | 108 ++++++------------- uplink/src/base/bridge/streams.rs | 7 +- uplink/src/base/mod.rs | 19 +++- uplink/src/base/serializer/mod.rs | 167 +++++++++++++++++++----------- 5 files changed, 168 insertions(+), 155 deletions(-) diff --git a/uplink/src/base/bridge/mod.rs b/uplink/src/base/bridge/mod.rs index b95b6de0..f96e217e 100644 --- a/uplink/src/base/bridge/mod.rs +++ b/uplink/src/base/bridge/mod.rs @@ -12,15 +12,14 @@ mod metrics; pub(crate) mod stream; mod streams; -use crate::{Action, ActionResponse, ActionRoute, Config}; - -use self::actions_lane::Error; -pub use self::{ - actions_lane::{ActionsBridge, ActionsBridgeTx}, - data_lane::{DataBridge, DataBridgeTx}, -}; - -use super::Compression; +pub use actions_lane::ActionsBridgeTx; +use actions_lane::{ActionsBridge, Error}; +use data_lane::DataBridge; +pub use data_lane::DataBridgeTx; + +use super::StreamConfig; +use crate::base::ActionRoute; +use crate::{Action, ActionResponse, Config}; pub use metrics::StreamMetrics; pub trait Point: Send + Debug + Serialize + 'static { @@ -30,8 +29,8 @@ pub trait Point: Send + Debug + Serialize + 'static { } pub trait Package: Send + Debug { - fn topic(&self) -> Arc; - fn stream(&self) -> Arc; + fn stream_config(&self) -> Arc; + fn stream_name(&self) -> Arc; // TODO: Implement a generic Return type that can wrap // around custom serialization error types. fn serialize(&self) -> serde_json::Result>; @@ -41,7 +40,6 @@ pub trait Package: Send + Debug { fn is_empty(&self) -> bool { self.len() == 0 } - fn compression(&self) -> Compression; } // TODO Don't do any deserialization on payload. Read it a Vec which is in turn a json diff --git a/uplink/src/base/bridge/stream.rs b/uplink/src/base/bridge/stream.rs index d83c9354..17c099bb 100644 --- a/uplink/src/base/bridge/stream.rs +++ b/uplink/src/base/bridge/stream.rs @@ -4,7 +4,7 @@ use flume::{SendError, Sender}; use log::{debug, trace}; use serde::Serialize; -use crate::base::{Compression, StreamConfig, DEFAULT_TIMEOUT}; +use crate::base::StreamConfig; use super::{Package, Point, StreamMetrics}; @@ -27,15 +27,12 @@ pub const MAX_BUFFER_SIZE: usize = 100; #[derive(Debug)] pub struct Stream { pub name: Arc, - pub max_buffer_size: usize, - pub flush_period: Duration, - topic: Arc, + pub config: Arc, last_sequence: u32, last_timestamp: u64, buffer: Buffer, tx: Sender>, pub metrics: StreamMetrics, - compression: Compression, } impl Stream @@ -44,50 +41,25 @@ where Buffer: Package, { pub fn new( - stream: impl Into, - topic: impl Into, - max_buffer_size: usize, + stream_name: impl Into, + stream_config: StreamConfig, tx: Sender>, - compression: Compression, ) -> Stream { - let name = Arc::new(stream.into()); - let topic = Arc::new(topic.into()); - let buffer = Buffer::new(name.clone(), topic.clone(), compression); - let flush_period = Duration::from_secs(DEFAULT_TIMEOUT); - let metrics = StreamMetrics::new(&name, max_buffer_size); + let name = Arc::new(stream_name.into()); + let config = Arc::new(stream_config); + let buffer = Buffer::new(name.clone(), config.clone()); + let metrics = StreamMetrics::new(&name, config.buf_size); - Stream { - name, - max_buffer_size, - flush_period, - topic, - last_sequence: 0, - last_timestamp: 0, - buffer, - tx, - metrics, - compression, - } - } - - pub fn with_config( - name: &str, - config: &StreamConfig, - tx: Sender>, - ) -> Stream { - let mut stream = Stream::new(name, &config.topic, config.buf_size, tx, config.compression); - stream.flush_period = config.flush_period; - stream + Stream { name, config, last_sequence: 0, last_timestamp: 0, buffer, tx, metrics } } pub fn dynamic( - stream: impl Into, + stream_name: impl Into, project_id: impl Into, device_id: impl Into, - max_buffer_size: usize, tx: Sender>, ) -> Stream { - let stream = stream.into(); + let stream_name = stream_name.into(); let project_id = project_id.into(); let device_id = device_id.into(); @@ -96,10 +68,11 @@ where + "/devices/" + &device_id + "/events/" - + &stream + + &stream_name + "/jsonarray"; + let config = StreamConfig { topic, ..Default::default() }; - Stream::new(stream, topic, max_buffer_size, tx, Compression::Disabled) + Stream::new(stream_name, config, tx) } fn add(&mut self, data: T) -> Result>, Error> { @@ -127,7 +100,7 @@ where self.last_timestamp = current_timestamp; // if max_buffer_size is breached, flush - let buf = if self.buffer.buffer.len() >= self.max_buffer_size { + let buf = if self.buffer.buffer.len() >= self.config.buf_size { self.metrics.add_batch(); Some(self.take_buffer()) } else { @@ -140,10 +113,10 @@ where // Returns buffer content, replacing with empty buffer in-place fn take_buffer(&mut self) -> Buffer { let name = self.name.clone(); - let topic = self.topic.clone(); - trace!("Flushing stream name: {}, topic: {}", name, topic); + let config = self.config.clone(); + trace!("Flushing stream name: {}, topic: {}", name, config.topic); - mem::replace(&mut self.buffer, Buffer::new(name, topic, self.compression)) + mem::replace(&mut self.buffer, Buffer::new(name, config)) } /// Triggers flush and async channel send if not empty @@ -175,7 +148,7 @@ where } let status = match self.len() { - 1 => StreamStatus::Init(self.flush_period), + 1 => StreamStatus::Init(self.config.flush_period), len => StreamStatus::Partial(len), }; @@ -192,7 +165,7 @@ where } let status = match self.len() { - 1 => StreamStatus::Init(self.flush_period), + 1 => StreamStatus::Init(self.config.flush_period), len => StreamStatus::Partial(len), }; @@ -210,23 +183,21 @@ where /// Buffer doesn't put any restriction on type of `T` #[derive(Debug)] pub struct Buffer { - pub stream: Arc, - pub topic: Arc, + pub stream_name: Arc, + pub stream_config: Arc, pub buffer: Vec, pub anomalies: String, pub anomaly_count: usize, - pub compression: Compression, } impl Buffer { - pub fn new(stream: Arc, topic: Arc, compression: Compression) -> Buffer { + pub fn new(stream_name: Arc, stream_config: Arc) -> Buffer { Buffer { - stream, - topic, - buffer: vec![], + buffer: Vec::with_capacity(stream_config.buf_size), + stream_name, + stream_config, anomalies: String::with_capacity(100), anomaly_count: 0, - compression, } } @@ -236,7 +207,7 @@ impl Buffer { return; } - let error = String::from(self.stream.as_ref()) + let error = self.stream_name.to_string() + ".sequence: " + &last.to_string() + ", " @@ -268,12 +239,12 @@ where T: Point, Vec: Serialize, { - fn topic(&self) -> Arc { - self.topic.clone() + fn stream_config(&self) -> Arc { + self.stream_config.clone() } - fn stream(&self) -> Arc { - self.stream.clone() + fn stream_name(&self) -> Arc { + self.stream_name.clone() } fn serialize(&self) -> serde_json::Result> { @@ -291,29 +262,18 @@ where fn latency(&self) -> u64 { 0 } - - fn compression(&self) -> Compression { - self.compression - } } impl Clone for Stream { fn clone(&self) -> Self { Stream { name: self.name.clone(), - flush_period: self.flush_period, - max_buffer_size: self.max_buffer_size, - topic: self.topic.clone(), + config: self.config.clone(), last_sequence: 0, last_timestamp: 0, - buffer: Buffer::new( - self.buffer.stream.clone(), - self.buffer.topic.clone(), - self.compression, - ), - metrics: StreamMetrics::new(&self.name, self.max_buffer_size), + buffer: Buffer::new(self.buffer.stream_name.clone(), self.buffer.stream_config.clone()), + metrics: StreamMetrics::new(&self.name, self.config.buf_size), tx: self.tx.clone(), - compression: self.compression, } } } diff --git a/uplink/src/base/bridge/streams.rs b/uplink/src/base/bridge/streams.rs index 158f3870..7b72d0d4 100644 --- a/uplink/src/base/bridge/streams.rs +++ b/uplink/src/base/bridge/streams.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use flume::Sender; use log::{error, info, trace}; -use super::stream::{self, StreamStatus, MAX_BUFFER_SIZE}; +use super::stream::{self, StreamStatus}; use super::{Point, StreamMetrics}; use crate::base::StreamConfig; use crate::{Config, Package, Stream}; @@ -30,7 +30,7 @@ impl Streams { pub fn config_streams(&mut self, streams_config: HashMap) { for (name, stream) in streams_config { - let stream = Stream::with_config(&name, &stream, self.data_tx.clone()); + let stream = Stream::new(&name, stream, self.data_tx.clone()); self.map.insert(name.to_owned(), stream); } } @@ -50,7 +50,6 @@ impl Streams { &stream_name, &self.config.project_id, &self.config.device_id, - MAX_BUFFER_SIZE, self.data_tx.clone(), ); @@ -58,7 +57,7 @@ impl Streams { } }; - let max_stream_size = stream.max_buffer_size; + let max_stream_size = stream.config.buf_size; let state = match stream.fill(data).await { Ok(s) => s, Err(e) => { diff --git a/uplink/src/base/mod.rs b/uplink/src/base/mod.rs index c78d1e22..1b012dc0 100644 --- a/uplink/src/base/mod.rs +++ b/uplink/src/base/mod.rs @@ -1,4 +1,5 @@ use std::env::current_dir; +use std::hash::Hash; use std::path::PathBuf; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::{collections::HashMap, fmt::Debug}; @@ -59,7 +60,7 @@ pub fn clock() -> u128 { SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() } -#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default)] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default, Hash, PartialEq, Eq)] pub enum Compression { #[default] Disabled, @@ -67,7 +68,7 @@ pub enum Compression { } #[serde_as] -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Deserialize, Eq)] pub struct StreamConfig { pub topic: String, #[serde(default = "max_buf_size")] @@ -95,7 +96,19 @@ impl Default for StreamConfig { } } -#[derive(Debug, Clone, Deserialize)] +impl Hash for StreamConfig { + fn hash(&self, state: &mut H) { + self.topic.hash(state) + } +} + +impl PartialEq for StreamConfig { + fn eq(&self, other: &Self) -> bool { + self.topic == other.topic + } +} + +#[derive(Debug, Clone, Deserialize, Hash, PartialEq, Eq)] pub struct Persistence { #[serde(default = "default_file_size")] pub max_file_size: usize, diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index aedb4ff2..fe489b81 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -17,22 +17,31 @@ use crate::base::Compression; use crate::{Config, Package}; pub use metrics::SerializerMetrics; -use super::default_file_size; +use super::{default_file_size, StreamConfig}; const METRICS_INTERVAL: Duration = Duration::from_secs(10); #[derive(thiserror::Error, Debug)] pub enum MqttError { #[error("SendError(..)")] - Send(Request), + Send(Arc, Request), #[error("TrySendError(..)")] TrySend(Request), } +impl From<(Arc, ClientError)> for MqttError { + fn from((stream, e): (Arc, ClientError)) -> Self { + match e { + ClientError::Request(r) => MqttError::Send(stream, r), + ClientError::TryRequest(r) => MqttError::TrySend(r), + } + } +} + impl From for MqttError { fn from(e: ClientError) -> Self { match e { - ClientError::Request(r) => MqttError::Send(r), + ClientError::Request(r) => MqttError::Send(Arc::new(Default::default()), r), ClientError::TryRequest(r) => MqttError::TrySend(r), } } @@ -63,24 +72,23 @@ pub enum Error { #[derive(Debug, PartialEq)] enum Status { Normal, - SlowEventloop(Publish), + SlowEventloop(Publish, Arc), EventLoopReady, - EventLoopCrash(Publish), + EventLoopCrash(Publish, Arc), } /// Description of an interface that the [`Serializer`] expects to be provided by the MQTT client to publish the serialized data with. #[async_trait::async_trait] pub trait MqttClient: Clone { /// Accept payload and resolve as an error only when the client has died(thread kill). Useful in Slow/Catchup mode. - async fn publish( + async fn publish( &self, - topic: S, + stream: Arc, qos: QoS, retain: bool, payload: V, ) -> Result<(), MqttError> where - S: Into + Send, V: Into> + Send; /// Accept payload and resolve as an error if data can't be sent over network, immediately. Useful in Normal mode. @@ -98,18 +106,17 @@ pub trait MqttClient: Clone { #[async_trait::async_trait] impl MqttClient for AsyncClient { - async fn publish( + async fn publish( &self, - topic: S, + stream: Arc, qos: QoS, retain: bool, payload: V, ) -> Result<(), MqttError> where - S: Into + Send, V: Into> + Send, { - self.publish(topic, qos, retain, payload).await?; + self.publish(&stream.topic, qos, retain, payload).await.map_err(|e| (stream, e))?; Ok(()) } @@ -130,9 +137,9 @@ impl MqttClient for AsyncClient { } struct StorageHandler { - map: HashMap, + map: HashMap, Storage>, // Stream being read from - read_stream: Option, + read_stream: Option>, } impl StorageHandler { @@ -155,26 +162,31 @@ impl StorageHandler { path.display() ); } - map.insert(stream_config.topic.clone(), storage); + map.insert(Arc::new(stream_config.clone()), storage); } Ok(Self { map, read_stream: None }) } - fn select(&mut self, topic: &str) -> &mut Storage { - self.map.entry(topic.to_owned()).or_insert_with(|| Storage::new(topic, default_file_size())) + fn select(&mut self, stream: &Arc) -> &mut Storage { + self.map + .entry(stream.to_owned()) + .or_insert_with(|| Storage::new(&stream.topic, default_file_size())) } - fn next(&mut self, metrics: &mut SerializerMetrics) -> Option<&mut Storage> { + fn next( + &mut self, + metrics: &mut SerializerMetrics, + ) -> Option<(&Arc, &mut Storage)> { let storages = self.map.iter_mut(); - for (stream_name, storage) in storages { + for (stream, storage) in storages { match (storage.reload_on_eof(), &mut self.read_stream) { // Done reading all pending files for a persisted stream (Ok(true), Some(curr_stream)) => { - if curr_stream == stream_name { + if curr_stream == stream { self.read_stream.take(); - debug!("Completed reading from: {stream_name}"); + debug!("Completed reading from: {}", stream.topic); } continue; @@ -183,12 +195,12 @@ impl StorageHandler { (Ok(true), _) => continue, // Reading from a newly loaded non-empty persisted stream (Ok(false), None) => { - debug!("Reading from: {stream_name}"); - self.read_stream = Some(stream_name.to_owned()); - return Some(storage); + debug!("Reading from: {}", stream.topic); + self.read_stream = Some(stream.to_owned()); + return Some((stream, storage)); } // Continuing to read from persisted stream loaded earlier - (Ok(false), _) => return Some(storage), + (Ok(false), _) => return Some((stream, storage)), // Reload again on encountering a corrupted file (Err(e), _) => { metrics.increment_errors(); @@ -277,8 +289,12 @@ impl Serializer { } /// Write all data received, from here-on, to disk only. - async fn crash(&mut self, publish: Publish) -> Result { - let storage = self.storage_handler.select(&publish.topic); + async fn crash( + &mut self, + publish: Publish, + stream: Arc, + ) -> Result { + let storage = self.storage_handler.select(&stream); // Write failed publish to disk first, metrics don't matter match write_to_disk(publish, storage) { Ok(Some(deleted)) => debug!("Lost segment = {deleted}"), @@ -290,7 +306,7 @@ impl Serializer { // Collect next data packet and write to disk let data = self.collector_rx.recv_async().await?; let publish = construct_publish(data)?; - let storage = self.storage_handler.select(&publish.topic); + let storage = self.storage_handler.select(&stream); match write_to_disk(publish, storage) { Ok(Some(deleted)) => debug!("Lost segment = {deleted}"), Ok(_) => {} @@ -301,7 +317,7 @@ impl Serializer { /// Write new data to disk until back pressure due to slow n/w is resolved // TODO: Handle errors. Don't return errors - async fn slow(&mut self, publish: Publish) -> Result { + async fn slow(&mut self, publish: Publish, stream: Arc) -> Result { let mut interval = interval(METRICS_INTERVAL); // Reactlabs setup processes logs generated by uplink info!("Switching to slow eventloop mode!!"); @@ -310,15 +326,16 @@ impl Serializer { // Note: self.client.publish() is executing code before await point // in publish method every time. Verify this behaviour later let payload = Bytes::copy_from_slice(&publish.payload[..]); - let publish = send_publish(self.client.clone(), publish.topic, payload); + let publish = send_publish(self.client.clone(), publish.topic, payload, stream); tokio::pin!(publish); let v: Result = loop { select! { data = self.collector_rx.recv_async() => { let data = data?; + let stream = data.stream_config(); let publish = construct_publish(data)?; - let storage = self.storage_handler.select(&publish.topic); + let storage = self.storage_handler.select(&stream); match write_to_disk(publish, storage) { Ok(Some(deleted)) => { debug!("Lost segment = {deleted}"); @@ -338,8 +355,8 @@ impl Serializer { Ok(_) => { break Ok(Status::EventLoopReady) } - Err(MqttError::Send(Request::Publish(publish))) => { - break Ok(Status::EventLoopCrash(publish)); + Err(MqttError::Send(stream, Request::Publish(publish))) => { + break Ok(Status::EventLoopCrash(publish, stream)); }, Err(e) => { unreachable!("Unexpected error: {}", e); @@ -374,7 +391,7 @@ impl Serializer { let max_packet_size = self.config.mqtt.max_packet_size; let client = self.client.clone(); - let storage = match self.storage_handler.next(&mut self.metrics) { + let (stream, storage) = match self.storage_handler.next(&mut self.metrics) { Some(s) => s, _ => return Ok(Status::Normal), }; @@ -397,15 +414,16 @@ impl Serializer { }; let mut last_publish_payload_size = publish.payload.len(); - let send = send_publish(client, publish.topic, publish.payload); + let send = send_publish(client, publish.topic, publish.payload, stream.clone()); tokio::pin!(send); let v: Result = loop { select! { data = self.collector_rx.recv_async() => { let data = data?; + let stream = data.stream_config(); let publish = construct_publish(data)?; - let storage = self.storage_handler.select(&publish.topic); + let storage = self.storage_handler.select(&stream); match write_to_disk(publish, storage) { Ok(Some(deleted)) => { debug!("Lost segment = {deleted}"); @@ -427,11 +445,11 @@ impl Serializer { // indefinitely write to disk to not loose data let client = match o { Ok(c) => c, - Err(MqttError::Send(Request::Publish(publish))) => break Ok(Status::EventLoopCrash(publish)), + Err(MqttError::Send(stream, Request::Publish(publish))) => break Ok(Status::EventLoopCrash(publish, stream)), Err(e) => unreachable!("Unexpected error: {}", e), }; - let storage = match self.storage_handler.next(&mut self.metrics) { + let (stream, storage) = match self.storage_handler.next(&mut self.metrics) { Some(s) => s, _ => return Ok(Status::Normal), }; @@ -449,7 +467,7 @@ impl Serializer { let payload = publish.payload; last_publish_payload_size = payload.len(); - send.set(send_publish(client, publish.topic, payload)); + send.set(send_publish(client, publish.topic, payload, stream.clone())); } // On a regular interval, forwards metrics information to network _ = interval.tick() => { @@ -477,16 +495,17 @@ impl Serializer { select! { data = self.collector_rx.recv_async() => { let data = data?; + let stream = data.stream_config(); let publish = construct_publish(data)?; let payload_size = publish.payload.len(); debug!("publishing on {} with size = {}", publish.topic, payload_size); - match self.client.try_publish(publish.topic, QoS::AtLeastOnce, false, publish.payload) { + match self.client.try_publish(&stream.topic, QoS::AtLeastOnce, false, publish.payload) { Ok(_) => { self.metrics.add_batch(); self.metrics.add_sent_size(payload_size); continue; } - Err(MqttError::TrySend(Request::Publish(publish))) => return Ok(Status::SlowEventloop(publish)), + Err(MqttError::TrySend(Request::Publish(publish))) => return Ok(Status::SlowEventloop(publish, stream)), Err(e) => unreachable!("Unexpected error: {}", e), } @@ -511,9 +530,9 @@ impl Serializer { loop { let next_status = match status { Status::Normal => self.normal().await?, - Status::SlowEventloop(publish) => self.slow(publish).await?, + Status::SlowEventloop(publish, stream) => self.slow(publish, stream).await?, Status::EventLoopReady => self.catchup().await?, - Status::EventLoopCrash(publish) => self.crash(publish).await?, + Status::EventLoopCrash(publish, stream) => self.crash(publish, stream).await?, }; status = next_status; @@ -525,9 +544,10 @@ async fn send_publish( client: C, topic: String, payload: Bytes, + stream: Arc, ) -> Result { debug!("publishing on {topic} with size = {}", payload.len()); - client.publish(topic, QoS::AtLeastOnce, false, payload).await?; + client.publish(stream, QoS::AtLeastOnce, false, payload).await?; Ok(client) } @@ -541,15 +561,16 @@ fn lz4_compress(payload: &mut Vec) -> Result<(), Error> { // Constructs a [Publish] packet given a [Package] element. Updates stream metrics as necessary. fn construct_publish(data: Box) -> Result { - let stream = data.stream().as_ref().to_owned(); + let stream_name = data.stream_name().as_ref().to_owned(); + let stream_config = data.stream_config(); let point_count = data.len(); let batch_latency = data.latency(); - trace!("Data received on stream: {stream}; message count = {point_count}; batching latency = {batch_latency}"); + trace!("Data received on stream: {stream_name}; message count = {point_count}; batching latency = {batch_latency}"); - let topic = data.topic().to_string(); + let topic = stream_config.topic.clone(); let mut payload = data.serialize()?; - if let Compression::Lz4 = data.compression() { + if let Compression::Lz4 = stream_config.compression { lz4_compress(&mut payload)?; } @@ -718,21 +739,23 @@ mod test { #[async_trait::async_trait] impl MqttClient for MockClient { - async fn publish( + async fn publish( &self, - topic: S, + stream: Arc, qos: QoS, retain: bool, payload: V, ) -> Result<(), MqttError> where - S: Into + Send, V: Into> + Send, { - let mut publish = Publish::new(topic, qos, payload); + let mut publish = Publish::new(&stream.topic, qos, payload); publish.retain = retain; let publish = Request::Publish(publish); - self.net_tx.send_async(publish).await.map_err(|e| MqttError::Send(e.into_inner()))?; + self.net_tx + .send_async(publish) + .await + .map_err(|e| MqttError::Send(stream, e.into_inner()))?; Ok(()) } @@ -805,7 +828,15 @@ mod test { impl MockCollector { fn new(data_tx: flume::Sender>) -> MockCollector { MockCollector { - stream: Stream::new("hello", "hello/world", 1, data_tx, Compression::Disabled), + stream: Stream::new( + "hello", + StreamConfig { + topic: "hello/world".to_string(), + buf_size: 1, + ..Default::default() + }, + data_tx, + ), } } @@ -842,7 +873,7 @@ mod test { }); match tokio::runtime::Runtime::new().unwrap().block_on(serializer.normal()).unwrap() { - Status::SlowEventloop(Publish { qos: QoS::AtLeastOnce, topic, payload, .. }) => { + Status::SlowEventloop(Publish { qos: QoS::AtLeastOnce, topic, payload, .. }, _) => { assert_eq!(topic, "hello/world"); let recvd: Value = serde_json::from_slice(&payload).unwrap(); let obj = &recvd.as_array().unwrap()[0]; @@ -902,8 +933,10 @@ mod test { QoS::AtLeastOnce, "[{{\"sequence\":1,\"timestamp\":0,\"msg\":\"Hello, World!\"}}]".as_bytes(), ); - let status = - tokio::runtime::Runtime::new().unwrap().block_on(serializer.slow(publish)).unwrap(); + let status = tokio::runtime::Runtime::new() + .unwrap() + .block_on(serializer.slow(publish, Arc::new(Default::default()))) + .unwrap(); assert_eq!(status, Status::EventLoopReady); } @@ -929,8 +962,15 @@ mod test { "[{\"sequence\":1,\"timestamp\":0,\"msg\":\"Hello, World!\"}]".as_bytes(), ); - match tokio::runtime::Runtime::new().unwrap().block_on(serializer.slow(publish)).unwrap() { - Status::EventLoopCrash(Publish { qos: QoS::AtLeastOnce, topic, payload, .. }) => { + match tokio::runtime::Runtime::new() + .unwrap() + .block_on(serializer.slow( + publish, + Arc::new(StreamConfig { topic: "hello/world".to_string(), ..Default::default() }), + )) + .unwrap() + { + Status::EventLoopCrash(Publish { qos: QoS::AtLeastOnce, topic, payload, .. }, _) => { assert_eq!(topic, "hello/world"); let recvd = std::str::from_utf8(&payload).unwrap(); assert_eq!(recvd, "[{\"sequence\":1,\"timestamp\":0,\"msg\":\"Hello, World!\"}]"); @@ -961,7 +1001,7 @@ mod test { let mut storage = serializer .storage_handler .map - .entry("hello/world".to_string()) + .entry(Arc::new(Default::default())) .or_insert(Storage::new("hello/world", 1024)); let mut collector = MockCollector::new(data_tx); @@ -1013,7 +1053,10 @@ mod test { let mut storage = serializer .storage_handler .map - .entry("hello/world".to_string()) + .entry(Arc::new(StreamConfig { + topic: "hello/world".to_string(), + ..Default::default() + })) .or_insert(Storage::new("hello/world", 1024)); let mut collector = MockCollector::new(data_tx); @@ -1034,7 +1077,7 @@ mod test { write_to_disk(publish.clone(), &mut storage).unwrap(); match tokio::runtime::Runtime::new().unwrap().block_on(serializer.catchup()).unwrap() { - Status::EventLoopCrash(Publish { topic, payload, .. }) => { + Status::EventLoopCrash(Publish { topic, payload, .. }, _) => { assert_eq!(topic, "hello/world"); let recvd = std::str::from_utf8(&payload).unwrap(); assert_eq!(recvd, "[{\"sequence\":1,\"timestamp\":0,\"msg\":\"Hello, World!\"}]"); From 6ea72353fd0fef4038ba9598a88c7f984cd6348c Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Fri, 8 Dec 2023 16:29:18 +0530 Subject: [PATCH 04/20] fix: Docker compile broken by #301 --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 71a4006c..979033fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,7 @@ RUN source $HOME/.cargo/env COPY uplink/ /usr/share/bytebeam/uplink/uplink COPY storage/ /usr/share/bytebeam/uplink/storage +COPY tools/utils /usr/share/bytebeam/uplink/tools/utils COPY Cargo.* /usr/share/bytebeam/uplink/ COPY .git/ /usr/share/bytebeam/uplink/.git From 6e65ba776f5315f5479f01e1cff28e4068c00bfe Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Fri, 8 Dec 2023 16:38:03 +0530 Subject: [PATCH 05/20] refactor: handle files on disk as `PersistenceFile` (#314) * refactor: `PersistenceFile` * refactor: generalize `PersistenceFile` * style: clppy suggestion --- storage/src/lib.rs | 212 +++++++++++++++++++++++++-------------------- 1 file changed, 119 insertions(+), 93 deletions(-) diff --git a/storage/src/lib.rs b/storage/src/lib.rs index 02a009a9..c9bfc2d2 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -3,8 +3,8 @@ use log::{self, debug, error, info, warn}; use seahash::hash; use std::collections::VecDeque; -use std::fs::{self, File, OpenOptions}; -use std::io::{self, Read, Write}; +use std::fs::{self, OpenOptions}; +use std::io::{self, copy, Write}; use std::mem; use std::path::{Path, PathBuf}; @@ -94,22 +94,15 @@ impl Storage { match &mut self.persistence { Some(persistence) => { - let hash = hash(&self.current_write_file[..]); - let mut next_file = persistence.open_next_write_file()?; - info!( - "Flushing data to disk for stoarge: {}; path = {:?}", - self.name, next_file.path - ); - - next_file.file.write_all(&hash.to_be_bytes())?; - next_file.file.write_all(&self.current_write_file[..])?; - next_file.file.flush()?; + let NextFile { mut file, deleted } = persistence.open_next_write_file()?; + info!("Flushing data to disk for stoarge: {}; path = {:?}", self.name, file.path()); + file.write(&mut self.current_write_file)?; // 8 is the number of bytes the hash(u64) occupies persistence.bytes_occupied += 8 + self.current_write_file.len(); - self.current_write_file.clear(); - Ok(next_file.deleted) + + Ok(deleted) } None => { // TODO(RT): Make sure that disk files starts with id 1 to represent in memory file @@ -206,9 +199,91 @@ fn get_file_ids(path: &Path) -> Result, Error> { Ok(file_ids) } -struct NextFile { - path: PathBuf, - file: File, +/// A handle to describe a persistence file on disk +pub struct PersistenceFile<'a> { + /// Path to the persistence directory + dir: &'a Path, + /// Name of the file e.g. `backup@1` + file_name: String, +} + +impl<'a> PersistenceFile<'a> { + pub fn new(dir: &'a Path, file_name: String) -> Result { + Ok(Self { dir, file_name }) + } + + /// Path of persistence file when stored on disk + pub fn path(&self) -> PathBuf { + self.dir.join(&self.file_name) + } + + // Moves the corrupt persistence file into special directory + fn handle_corrupt_file(&self) -> Result<(), Error> { + let path_src = self.path(); + let dest_dir = self.dir.join("corrupted"); + fs::create_dir_all(&dest_dir)?; + let path_dest = dest_dir.join(&self.file_name); + + warn!("Moving corrupted file from {path_src:?} to {path_dest:?}"); + fs::rename(path_src, path_dest)?; + + Ok(()) + } + + /// Read contents of the persistence file from disk into buffer in memory + pub fn read(&mut self, buf: &mut BytesMut) -> Result<(), Error> { + let path = self.path(); + let mut file = OpenOptions::new().read(true).open(path)?; + + // Initialize buffer and load next read file + buf.clear(); + copy(&mut file, &mut buf.writer())?; + + // Verify with checksum + if buf.len() < 8 { + self.handle_corrupt_file()?; + return Err(Error::CorruptedFile); + } + + let expected_hash = buf.get_u64(); + let actual_hash = hash(&buf[..]); + if actual_hash != expected_hash { + self.handle_corrupt_file()?; + return Err(Error::CorruptedFile); + } + + Ok(()) + } + + /// Write contents of buffer from memory onto the persistence file in disk + pub fn write(&mut self, buf: &mut BytesMut) -> Result<(), Error> { + let path = self.path(); + let mut file = OpenOptions::new().write(true).create(true).open(path)?; + + let hash = hash(&buf[..]); + file.write_all(&hash.to_be_bytes())?; + file.write_all(&buf[..])?; + file.flush()?; + + Ok(()) + } + + /// Deletes the persistence file from disk + pub fn delete(&mut self) -> Result { + let path = self.path(); + + // Query the fs to track size of removed persistence file + let metadata = fs::metadata(&path)?; + let bytes_occupied = metadata.len(); + + fs::remove_file(&path)?; + + Ok(bytes_occupied) + } +} + +struct NextFile<'a> { + file: PersistenceFile<'a>, deleted: Option, } @@ -252,53 +327,22 @@ impl Persistence { }) } - fn path(&self, id: u64) -> Result { - let file_name = format!("backup@{id}"); - let path = self.path.join(file_name); - - Ok(path) - } - - /// Removes a file with provided id + /// Removes a persistence file with provided id fn remove(&mut self, id: u64) -> Result { - let path = self.path(id)?; - - // Query the fs to track size of removed persistence file - let metadata = fs::metadata(&path)?; - self.bytes_occupied -= metadata.len() as usize; + let file_name = format!("backup@{}", id); + let mut file = PersistenceFile::new(&self.path, file_name)?; + let path = file.path(); - fs::remove_file(&path)?; + self.bytes_occupied -= file.delete()? as usize; Ok(path) } - /// Move corrupt file to special directory - fn handle_corrupt_file(&self) -> Result<(), Error> { - let id = self.current_read_file_id.expect("There is supposed to be a file here"); - let path_src = self.path(id)?; - let dest_dir = self.path.join("corrupted"); - fs::create_dir_all(&dest_dir)?; - - let file_name = path_src.file_name().expect("The file name should exist"); - let path_dest = dest_dir.join(file_name); - - warn!("Moving corrupted file from {path_src:?} to {path_dest:?}"); - fs::rename(path_src, path_dest)?; - - Ok(()) - } - /// Opens file to flush current inmemory write buffer to disk. /// Also handles retention of previous files on disk fn open_next_write_file(&mut self) -> Result { let next_file_id = self.backlog_files.back().map_or(0, |id| id + 1); - let file_name = format!("backup@{next_file_id}"); - let next_file_path = self.path.join(file_name); - let next_file = OpenOptions::new().write(true).create(true).open(&next_file_path)?; - self.backlog_files.push_back(next_file_id); - - let mut next = NextFile { path: next_file_path, file: next_file, deleted: None }; let mut backlog_files_count = self.backlog_files.len(); // File being read is also to be considered @@ -306,58 +350,40 @@ impl Persistence { backlog_files_count += 1 } - // Return next file details if backlog is within limits - if backlog_files_count <= self.max_file_count { - return Ok(next); - } + // Delete earliest file if backlog limits crossed + let deleted = if backlog_files_count > self.max_file_count { + // Remove file being read, or first in backlog + // NOTE: keeps read buffer unchanged + let id = match self.current_read_file_id.take() { + Some(id) => id, + _ => self.backlog_files.pop_front().unwrap(), + }; + + if !self.non_destructive_read { + let deleted_file = self.remove(id)?; + warn!("file limit reached. deleting backup@{}; path = {deleted_file:?}", id); + } - // Remove file being read, or first in backlog - // NOTE: keeps read buffer unchanged - let id = match self.current_read_file_id.take() { - Some(id) => id, - _ => self.backlog_files.pop_front().unwrap(), + Some(id) + } else { + None }; - next.deleted = Some(id); - if !self.non_destructive_read { - let deleted_file = self.remove(id)?; - warn!("file limit reached. deleting backup@{}; path = {deleted_file:?}", id); - } - - Ok(next) + let file_name = format!("backup@{}", next_file_id); + Ok(NextFile { file: PersistenceFile::new(&self.path, file_name)?, deleted }) } + /// Load the next persistence file to be read into memory fn load_next_read_file(&mut self, current_read_file: &mut BytesMut) -> Result<(), Error> { // Len always > 0 because of above if. Doesn't panic let id = self.backlog_files.pop_front().unwrap(); - let next_file_path = self.path(id)?; - - let mut file = OpenOptions::new().read(true).open(&next_file_path)?; + let file_name = format!("backup@{}", id); + let mut file = PersistenceFile::new(&self.path, file_name)?; // Load file into memory and store its id for deleting in the future - let metadata = fs::metadata(&next_file_path)?; - - // Initialize next read file with 0s - current_read_file.clear(); - let init = vec![0u8; metadata.len() as usize]; - current_read_file.put_slice(&init); - - file.read_exact(&mut current_read_file[..])?; + file.read(current_read_file)?; self.current_read_file_id = Some(id); - // Verify with checksum - if current_read_file.len() < 8 { - self.handle_corrupt_file()?; - return Err(Error::CorruptedFile); - } - - let expected_hash = current_read_file.get_u64(); - let actual_hash = hash(¤t_read_file[..]); - if actual_hash != expected_hash { - self.handle_corrupt_file()?; - return Err(Error::CorruptedFile); - } - Ok(()) } } From 5f05423cc3d20960e6728d26687410eba4886155 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Sat, 9 Dec 2023 00:16:11 +0530 Subject: [PATCH 06/20] refactor: simplify `Serializer` stream tracking --- uplink/src/base/serializer/mod.rs | 56 +++++++++++++------------------ 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index fe489b81..ea5b2469 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -24,24 +24,15 @@ const METRICS_INTERVAL: Duration = Duration::from_secs(10); #[derive(thiserror::Error, Debug)] pub enum MqttError { #[error("SendError(..)")] - Send(Arc, Request), + Send(Request), #[error("TrySendError(..)")] TrySend(Request), } -impl From<(Arc, ClientError)> for MqttError { - fn from((stream, e): (Arc, ClientError)) -> Self { - match e { - ClientError::Request(r) => MqttError::Send(stream, r), - ClientError::TryRequest(r) => MqttError::TrySend(r), - } - } -} - impl From for MqttError { fn from(e: ClientError) -> Self { match e { - ClientError::Request(r) => MqttError::Send(Arc::new(Default::default()), r), + ClientError::Request(r) => MqttError::Send(r), ClientError::TryRequest(r) => MqttError::TrySend(r), } } @@ -81,14 +72,15 @@ enum Status { #[async_trait::async_trait] pub trait MqttClient: Clone { /// Accept payload and resolve as an error only when the client has died(thread kill). Useful in Slow/Catchup mode. - async fn publish( + async fn publish( &self, - stream: Arc, + topic: S, qos: QoS, retain: bool, payload: V, ) -> Result<(), MqttError> where + S: Into + Send, V: Into> + Send; /// Accept payload and resolve as an error if data can't be sent over network, immediately. Useful in Normal mode. @@ -100,23 +92,24 @@ pub trait MqttClient: Clone { payload: V, ) -> Result<(), MqttError> where - S: Into, - V: Into>; + S: Into + Send, + V: Into> + Send; } #[async_trait::async_trait] impl MqttClient for AsyncClient { - async fn publish( + async fn publish( &self, - stream: Arc, + topic: S, qos: QoS, retain: bool, payload: V, ) -> Result<(), MqttError> where + S: Into + Send, V: Into> + Send, { - self.publish(&stream.topic, qos, retain, payload).await.map_err(|e| (stream, e))?; + self.publish(topic, qos, retain, payload).await?; Ok(()) } @@ -326,7 +319,7 @@ impl Serializer { // Note: self.client.publish() is executing code before await point // in publish method every time. Verify this behaviour later let payload = Bytes::copy_from_slice(&publish.payload[..]); - let publish = send_publish(self.client.clone(), publish.topic, payload, stream); + let publish = send_publish(self.client.clone(), publish.topic, payload); tokio::pin!(publish); let v: Result = loop { @@ -355,7 +348,7 @@ impl Serializer { Ok(_) => { break Ok(Status::EventLoopReady) } - Err(MqttError::Send(stream, Request::Publish(publish))) => { + Err(MqttError::Send(Request::Publish(publish))) => { break Ok(Status::EventLoopCrash(publish, stream)); }, Err(e) => { @@ -414,7 +407,8 @@ impl Serializer { }; let mut last_publish_payload_size = publish.payload.len(); - let send = send_publish(client, publish.topic, publish.payload, stream.clone()); + let mut last_publish_stream = stream.clone(); + let send = send_publish(client, publish.topic, publish.payload); tokio::pin!(send); let v: Result = loop { @@ -445,7 +439,7 @@ impl Serializer { // indefinitely write to disk to not loose data let client = match o { Ok(c) => c, - Err(MqttError::Send(stream, Request::Publish(publish))) => break Ok(Status::EventLoopCrash(publish, stream)), + Err(MqttError::Send(Request::Publish(publish))) => break Ok(Status::EventLoopCrash(publish, last_publish_stream.clone())), Err(e) => unreachable!("Unexpected error: {}", e), }; @@ -467,7 +461,8 @@ impl Serializer { let payload = publish.payload; last_publish_payload_size = payload.len(); - send.set(send_publish(client, publish.topic, payload, stream.clone())); + last_publish_stream = stream.clone(); + send.set(send_publish(client, publish.topic, payload)); } // On a regular interval, forwards metrics information to network _ = interval.tick() => { @@ -544,10 +539,9 @@ async fn send_publish( client: C, topic: String, payload: Bytes, - stream: Arc, ) -> Result { debug!("publishing on {topic} with size = {}", payload.len()); - client.publish(stream, QoS::AtLeastOnce, false, payload).await?; + client.publish(topic, QoS::AtLeastOnce, false, payload).await?; Ok(client) } @@ -739,23 +733,21 @@ mod test { #[async_trait::async_trait] impl MqttClient for MockClient { - async fn publish( + async fn publish( &self, - stream: Arc, + topic: S, qos: QoS, retain: bool, payload: V, ) -> Result<(), MqttError> where + S: Into + Send, V: Into> + Send, { - let mut publish = Publish::new(&stream.topic, qos, payload); + let mut publish = Publish::new(topic, qos, payload); publish.retain = retain; let publish = Request::Publish(publish); - self.net_tx - .send_async(publish) - .await - .map_err(|e| MqttError::Send(stream, e.into_inner()))?; + self.net_tx.send_async(publish).await.map_err(|e| MqttError::Send(e.into_inner()))?; Ok(()) } From 9a76c9b52dfc5bdb52fb39551bfc5f02eca50113 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Sat, 9 Dec 2023 22:16:11 +0530 Subject: [PATCH 07/20] chore: use workspace dependencies (#315) * test: update dev-dep on rumqttc * chore: workspace level deps for storage/uplink * chore: workspace deps for uplink/utils * cleanup: don't import tokio full featured --- Cargo.lock | 14 ++------------ Cargo.toml | 15 +++++++++++++++ storage/Cargo.toml | 12 ++++++------ storage/src/lib.rs | 2 +- tools/utils/Cargo.toml | 16 ++++++++-------- tools/vd-lib | 1 + uplink/Cargo.toml | 26 +++++++++++++------------- 7 files changed, 46 insertions(+), 40 deletions(-) create mode 160000 tools/vd-lib diff --git a/Cargo.lock b/Cargo.lock index 998c5689..b0e98f88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1369,15 +1369,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "mqttbytes" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b7801639a5398353b9acf0764907d6571ca92e6b7a3662013b03861789449c" -dependencies = [ - "bytes 1.5.0", -] - [[package]] name = "nanorand" version = "0.7.0" @@ -2537,9 +2528,9 @@ version = "0.1.0" dependencies = [ "bytes 1.5.0", "log", - "mqttbytes", "pretty_env_logger", - "rand 0.7.3", + "rand 0.8.5", + "rumqttc", "seahash", "tempdir", "thiserror", @@ -2844,7 +2835,6 @@ dependencies = [ "libc", "mio 0.8.9", "num_cpus", - "parking_lot", "pin-project-lite 0.2.13", "signal-hook-registry", "socket2 0.5.5", diff --git a/Cargo.toml b/Cargo.toml index 42c05274..c244beab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,21 @@ exclude = [ "tools/tunshell", ] +[workspace.dependencies] +bytes = "1" +flume = "0.10" +futures-util = "0.3" +log = "0.4" +rand = "0.8" +rumqttc = { git = "https://github.com/bytebeamio/rumqtt" } +serde = { version = "1", features = ["derive"] } +serde_json = "1.0" +tempdir = "0.3" +thiserror = "1" +tokio = { version = "1", features = ["rt-multi-thread", "process"] } +tokio-stream = "0.1" +tokio-util = { version = "0.7", features = ["codec", "time"] } + [profile.dev] opt-level = 1 debug = true diff --git a/storage/Cargo.toml b/storage/Cargo.toml index 4543ec18..ba212fad 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -5,13 +5,13 @@ authors = ["tekjar "] edition = "2021" [dependencies] -bytes = "1" -log = "0.4" +bytes = { workspace = true } +log = { workspace = true } seahash = "4" -thiserror = "1" +thiserror = { workspace = true } [dev-dependencies] -tempdir = "0.3" -rand = "0.7" -mqttbytes = "0.1" +tempdir = { workspace = true } +rand = { workspace = true } +rumqttc = { workspace = true } pretty_env_logger = "0.4" diff --git a/storage/src/lib.rs b/storage/src/lib.rs index c9bfc2d2..e4783797 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -391,7 +391,7 @@ impl Persistence { #[cfg(test)] mod test { use super::*; - use mqttbytes::*; + use rumqttc::*; use tempdir::TempDir; fn init_backup_folders() -> TempDir { diff --git a/tools/utils/Cargo.toml b/tools/utils/Cargo.toml index 70b7732f..bc707d15 100644 --- a/tools/utils/Cargo.toml +++ b/tools/utils/Cargo.toml @@ -20,11 +20,11 @@ name = "wait_and_send" path = "src/wait_and_send.rs" [dependencies] -uplink = { path = "../../uplink" } -tokio = { version = "1", features = ["full"] } -futures-util = "0.3" -serde = { version = "1", features = ["derive"] } -tokio-util = { version = "0.7", features = ["codec", "time"] } -tokio-stream = "0.1" -serde_json = "1.0" -flume = "0.10" \ No newline at end of file +flume = { workspace = true } +futures-util = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true } +tokio-stream = { workspace = true } +tokio-util = { workspace = true } +uplink = { path = "../../uplink" } \ No newline at end of file diff --git a/tools/vd-lib b/tools/vd-lib new file mode 160000 index 00000000..cdaec8b6 --- /dev/null +++ b/tools/vd-lib @@ -0,0 +1 @@ +Subproject commit cdaec8b6dacc3779e063e0ff1241a41a821b0cf2 diff --git a/uplink/Cargo.toml b/uplink/Cargo.toml index 3c10e340..40168d91 100644 --- a/uplink/Cargo.toml +++ b/uplink/Cargo.toml @@ -5,16 +5,16 @@ authors = ["tekjar "] edition = "2021" [dependencies] -bytes = "1" -flume = "0.10" -rumqttc = { git = "https://github.com/bytebeamio/rumqtt" } -serde = { version = "1", features = ["derive"] } -serde_json = "1.0" +bytes = { workspace = true } +flume = { workspace = true } +rumqttc = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } serde_with = "3.3.0" -thiserror = "1" -tokio = { version = "1", features = ["full"] } -tokio-util = { version = "0.7", features = ["codec", "time"] } -tokio-stream = "0.1" +thiserror = { workspace = true } +tokio = { workspace = true } +tokio-stream = { workspace = true } +tokio-util = { workspace = true } # binary utils anyhow = "1" @@ -29,7 +29,7 @@ pretty-bytes = "0.2.2" storage = { path = "../storage" } # logging -log = "0.4" +log = { workspace = true } regex = "1.7.1" tracing = { version="0.1", features=["log"] } tracing-subscriber = { version="=0.3.14", features=["env-filter"] } @@ -40,10 +40,10 @@ tokio-compat-02 = "0.2.0" tunshell-client = { git = "https://github.com/bytebeamio/tunshell.git", branch = "android_patch" } # simulator fake = { version = "2.5.0", features = ["derive"] } -rand = "0.8" +rand = { workspace = true } # downloader fs2 = "0.4" -futures-util = "0.3" +futures-util = { workspace = true } human_bytes = "0.4" reqwest = { version = "0.11", default-features = false, features = ["stream", "rustls-tls"] } # systemstats @@ -66,4 +66,4 @@ signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } vergen = { version = "7", features = ["git", "build", "time"] } [dev-dependencies] -tempdir = "0.3" +tempdir = { workspace = true } From 6e67c492de330791f824f9867e261cb7803641ab Mon Sep 17 00:00:00 2001 From: "argonautbot[bot]" <84760521+argonautbot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:16:13 +0000 Subject: [PATCH 08/20] argonaut workflow Setup : From 383b7ceee72be4a03dcc7e8d84989ae55cd2f67f Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Mon, 11 Dec 2023 16:34:40 +0530 Subject: [PATCH 09/20] refactor: `CtrlTx` to send control messages to various uplink components (#316) * refactor: separate out `CtrlTx` * test: fix compilation * refactor: single `CtrlTx` for whole of uplink * chore: rm unused dir --- uplink/src/base/bridge/actions_lane.rs | 46 +++++++++++++++++--------- uplink/src/base/bridge/data_lane.rs | 34 +++++++++++++------ uplink/src/base/bridge/mod.rs | 28 ++++++++-------- uplink/src/base/mod.rs | 17 ++++++++++ uplink/src/collector/downloader.rs | 16 ++++----- uplink/src/collector/script_runner.rs | 16 ++++----- uplink/src/console.rs | 10 +++--- uplink/src/lib.rs | 8 +++-- uplink/src/main.rs | 15 ++++----- 9 files changed, 115 insertions(+), 75 deletions(-) diff --git a/uplink/src/base/bridge/actions_lane.rs b/uplink/src/base/bridge/actions_lane.rs index c6468272..7f2a753d 100644 --- a/uplink/src/base/bridge/actions_lane.rs +++ b/uplink/src/base/bridge/actions_lane.rs @@ -126,8 +126,14 @@ impl ActionsBridge { Ok(()) } - pub fn tx(&self) -> ActionsBridgeTx { - ActionsBridgeTx { status_tx: self.status_tx.clone(), shutdown_handle: self.ctrl_tx.clone() } + /// Handle to send action status messages from connected application + pub fn status_tx(&self) -> StatusTx { + StatusTx { inner: self.status_tx.clone() } + } + + /// Handle to send action lane control messages + pub fn ctrl_tx(&self) -> CtrlTx { + CtrlTx { inner: self.ctrl_tx.clone() } } fn clear_current_action(&mut self) { @@ -425,20 +431,28 @@ impl ActionRouter { } } +/// Handle for apps to send action status to bridge #[derive(Debug, Clone)] -pub struct ActionsBridgeTx { - // Handle for apps to send action status to bridge - pub(crate) status_tx: Sender, - pub(crate) shutdown_handle: Sender, +pub struct StatusTx { + pub(crate) inner: Sender, } -impl ActionsBridgeTx { +impl StatusTx { pub async fn send_action_response(&self, response: ActionResponse) { - self.status_tx.send_async(response).await.unwrap() + self.inner.send_async(response).await.unwrap() } +} + +/// Handle to send control messages to action lane +#[derive(Debug, Clone)] +pub struct CtrlTx { + pub(crate) inner: Sender, +} +impl CtrlTx { + /// Triggers shutdown of `bridge::actions_lane` pub async fn trigger_shutdown(&self) { - self.shutdown_handle.send_async(ActionBridgeShutdown).await.unwrap() + self.inner.send_async(ActionBridgeShutdown).await.unwrap() } } @@ -654,7 +668,7 @@ mod tests { let (route_tx, action_rx) = bounded(1); bridge.register_action_route(test_route, route_tx).unwrap(); - let bridge_tx = bridge.tx(); + let bridge_tx = bridge.status_tx(); spawn_bridge(bridge); @@ -697,8 +711,8 @@ mod tests { let mut config = default_config(); config.action_redirections.insert("test".to_string(), "redirect".to_string()); let (mut bridge, actions_tx, data_rx) = create_bridge(Arc::new(config)); - let bridge_tx_1 = bridge.tx(); - let bridge_tx_2 = bridge.tx(); + let bridge_tx_1 = bridge.status_tx(); + let bridge_tx_2 = bridge.status_tx(); let (route_tx, action_rx_1) = bounded(1); let test_route = ActionRoute { name: "test".to_string(), timeout: Duration::from_secs(30) }; @@ -765,8 +779,8 @@ mod tests { std::env::set_current_dir(&tmpdir).unwrap(); let config = default_config(); let (mut bridge, actions_tx, data_rx) = create_bridge(Arc::new(config)); - let bridge_tx_1 = bridge.tx(); - let bridge_tx_2 = bridge.tx(); + let bridge_tx_1 = bridge.status_tx(); + let bridge_tx_2 = bridge.status_tx(); let (route_tx, action_rx_1) = bounded(1); let tunshell_route = @@ -856,8 +870,8 @@ mod tests { std::env::set_current_dir(&tmpdir).unwrap(); let config = default_config(); let (mut bridge, actions_tx, data_rx) = create_bridge(Arc::new(config)); - let bridge_tx_1 = bridge.tx(); - let bridge_tx_2 = bridge.tx(); + let bridge_tx_1 = bridge.status_tx(); + let bridge_tx_2 = bridge.status_tx(); let (route_tx, action_rx_1) = bounded(1); let test_route = ActionRoute { name: "test".to_string(), timeout: Duration::from_secs(30) }; diff --git a/uplink/src/base/bridge/data_lane.rs b/uplink/src/base/bridge/data_lane.rs index 6e100fc1..3101d897 100644 --- a/uplink/src/base/bridge/data_lane.rs +++ b/uplink/src/base/bridge/data_lane.rs @@ -42,8 +42,14 @@ impl DataBridge { Self { data_tx, data_rx, config, streams, ctrl_rx, ctrl_tx } } - pub fn tx(&self) -> DataBridgeTx { - DataBridgeTx { data_tx: self.data_tx.clone(), shutdown_handle: self.ctrl_tx.clone() } + /// Handle to send data points from source application + pub fn data_tx(&self) -> DataTx { + DataTx { inner: self.data_tx.clone() } + } + + /// Handle to send data lane control message + pub fn ctrl_tx(&self) -> CtrlTx { + CtrlTx { inner: self.ctrl_tx.clone() } } pub async fn start(&mut self) -> Result<(), Error> { @@ -79,23 +85,31 @@ impl DataBridge { } } +/// Handle for apps to send action status to bridge #[derive(Debug, Clone)] -pub struct DataBridgeTx { - // Handle for apps to send action status to bridge - pub(crate) data_tx: Sender, - pub(crate) shutdown_handle: Sender, +pub struct DataTx { + pub(crate) inner: Sender, } -impl DataBridgeTx { +impl DataTx { pub async fn send_payload(&self, payload: Payload) { - self.data_tx.send_async(payload).await.unwrap() + self.inner.send_async(payload).await.unwrap() } pub fn send_payload_sync(&self, payload: Payload) { - self.data_tx.send(payload).unwrap() + self.inner.send(payload).unwrap() } +} + +/// Handle to send control messages to data lane +#[derive(Debug, Clone)] +pub struct CtrlTx { + pub(crate) inner: Sender, +} +impl CtrlTx { + /// Triggers shutdown of `bridge::data_lane` pub async fn trigger_shutdown(&self) { - self.shutdown_handle.send_async(DataBridgeShutdown).await.unwrap() + self.inner.send_async(DataBridgeShutdown).await.unwrap() } } diff --git a/uplink/src/base/bridge/mod.rs b/uplink/src/base/bridge/mod.rs index f96e217e..d6e261e9 100644 --- a/uplink/src/base/bridge/mod.rs +++ b/uplink/src/base/bridge/mod.rs @@ -1,7 +1,6 @@ use flume::{Receiver, Sender}; use serde::{Deserialize, Serialize}; use serde_json::Value; -use tokio::join; use std::{fmt::Debug, sync::Arc}; @@ -12,10 +11,10 @@ mod metrics; pub(crate) mod stream; mod streams; -pub use actions_lane::ActionsBridgeTx; use actions_lane::{ActionsBridge, Error}; +pub use actions_lane::{CtrlTx as ActionsLaneCtrlTx, StatusTx}; use data_lane::DataBridge; -pub use data_lane::DataBridgeTx; +pub use data_lane::{CtrlTx as DataLaneCtrlTx, DataTx}; use super::StreamConfig; use crate::base::ActionRoute; @@ -93,8 +92,13 @@ impl Bridge { Self { data, actions } } - pub fn tx(&self) -> BridgeTx { - BridgeTx { data: self.data.tx(), actions: self.actions.tx() } + /// Handle to send data/action status messages + pub fn bridge_tx(&self) -> BridgeTx { + BridgeTx { data_tx: self.data.data_tx(), status_tx: self.actions.status_tx() } + } + + pub(crate) fn ctrl_tx(&self) -> (actions_lane::CtrlTx, data_lane::CtrlTx) { + (self.actions.ctrl_tx(), self.data.ctrl_tx()) } pub fn register_action_route( @@ -116,24 +120,20 @@ impl Bridge { #[derive(Debug, Clone)] pub struct BridgeTx { - pub data: DataBridgeTx, - pub actions: ActionsBridgeTx, + pub data_tx: DataTx, + pub status_tx: StatusTx, } impl BridgeTx { pub async fn send_payload(&self, payload: Payload) { - self.data.send_payload(payload).await + self.data_tx.send_payload(payload).await } pub fn send_payload_sync(&self, payload: Payload) { - self.data.send_payload_sync(payload) + self.data_tx.send_payload_sync(payload) } pub async fn send_action_response(&self, response: ActionResponse) { - self.actions.send_action_response(response).await - } - - pub async fn trigger_shutdown(&self) { - join!(self.actions.trigger_shutdown(), self.data.trigger_shutdown()); + self.status_tx.send_action_response(response).await } } diff --git a/uplink/src/base/mod.rs b/uplink/src/base/mod.rs index 1b012dc0..2cbe1e64 100644 --- a/uplink/src/base/mod.rs +++ b/uplink/src/base/mod.rs @@ -6,6 +6,7 @@ use std::{collections::HashMap, fmt::Debug}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DurationSeconds}; +use tokio::join; #[cfg(target_os = "linux")] use crate::collector::journalctl::JournalCtlConfig; @@ -13,6 +14,7 @@ use crate::collector::journalctl::JournalCtlConfig; use crate::collector::logcat::LogcatConfig; use self::bridge::stream::MAX_BUFFER_SIZE; +use self::bridge::{ActionsLaneCtrlTx, DataLaneCtrlTx}; pub mod actions; pub mod bridge; @@ -279,3 +281,18 @@ pub struct Config { #[cfg(target_os = "android")] pub logging: Option, } + +/// Send control messages to the various components in uplink. Currently this is +/// used only to trigger uplink shutdown. Shutdown signals are sent to all +/// components simultaneously with a join. +#[derive(Debug, Clone)] +pub struct CtrlTx { + pub actions_lane: ActionsLaneCtrlTx, + pub data_lane: DataLaneCtrlTx, +} + +impl CtrlTx { + pub async fn trigger_shutdown(&self) { + join!(self.actions_lane.trigger_shutdown(), self.data_lane.trigger_shutdown()); + } +} diff --git a/uplink/src/collector/downloader.rs b/uplink/src/collector/downloader.rs index 95b2c78d..f44ed100 100644 --- a/uplink/src/collector/downloader.rs +++ b/uplink/src/collector/downloader.rs @@ -414,7 +414,7 @@ mod test { use super::*; use crate::base::{ - bridge::{ActionsBridgeTx, DataBridgeTx}, + bridge::{DataTx, StatusTx}, ActionRoute, DownloaderConfig, MqttConfig, }; @@ -433,14 +433,12 @@ mod test { } fn create_bridge() -> (BridgeTx, Receiver) { - let (data_tx, _) = flume::bounded(2); - let (status_tx, status_rx) = flume::bounded(2); - let (shutdown_handle, _) = bounded(1); - let data = DataBridgeTx { data_tx, shutdown_handle }; - let (shutdown_handle, _) = bounded(1); - let actions = ActionsBridgeTx { status_tx, shutdown_handle }; - - (BridgeTx { data, actions }, status_rx) + let (inner, _) = bounded(2); + let data_tx = DataTx { inner }; + let (inner, status_rx) = bounded(2); + let status_tx = StatusTx { inner }; + + (BridgeTx { data_tx, status_tx }, status_rx) } #[test] diff --git a/uplink/src/collector/script_runner.rs b/uplink/src/collector/script_runner.rs index dd921f04..3539796f 100644 --- a/uplink/src/collector/script_runner.rs +++ b/uplink/src/collector/script_runner.rs @@ -150,21 +150,19 @@ mod tests { use super::*; use crate::{ - base::bridge::{ActionsBridgeTx, DataBridgeTx}, + base::bridge::{DataTx, StatusTx}, Action, }; use flume::bounded; fn create_bridge() -> (BridgeTx, Receiver) { - let (data_tx, _) = flume::bounded(2); - let (status_tx, status_rx) = flume::bounded(2); - let (shutdown_handle, _) = bounded(1); - let data = DataBridgeTx { data_tx, shutdown_handle }; - let (shutdown_handle, _) = bounded(1); - let actions = ActionsBridgeTx { status_tx, shutdown_handle }; - - (BridgeTx { data, actions }, status_rx) + let (inner, _) = flume::bounded(2); + let data_tx = DataTx { inner }; + let (inner, status_rx) = flume::bounded(2); + let status_tx = StatusTx { inner }; + + (BridgeTx { data_tx, status_tx }, status_rx) } #[test] diff --git a/uplink/src/console.rs b/uplink/src/console.rs index 8b3b4825..187bbda3 100644 --- a/uplink/src/console.rs +++ b/uplink/src/console.rs @@ -1,20 +1,20 @@ use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::post, Router}; use log::info; -use uplink::base::bridge::BridgeTx; +use uplink::base::CtrlTx; use crate::ReloadHandle; #[derive(Debug, Clone)] struct StateHandle { reload_handle: ReloadHandle, - bridge_handle: BridgeTx, + ctrl_tx: CtrlTx, } #[tokio::main] -pub async fn start(port: u16, reload_handle: ReloadHandle, bridge_handle: BridgeTx) { +pub async fn start(port: u16, reload_handle: ReloadHandle, ctrl_tx: CtrlTx) { let address = format!("0.0.0.0:{port}"); info!("Starting uplink console server: {address}"); - let state = StateHandle { reload_handle, bridge_handle }; + let state = StateHandle { reload_handle, ctrl_tx }; let app = Router::new() .route("/logs", post(reload_loglevel)) .route("/shutdown", post(shutdown)) @@ -34,7 +34,7 @@ async fn reload_loglevel(State(state): State, filter: String) -> im async fn shutdown(State(state): State) -> impl IntoResponse { info!("Shutting down uplink"); - state.bridge_handle.trigger_shutdown().await; + state.ctrl_tx.trigger_shutdown().await; StatusCode::OK } diff --git a/uplink/src/lib.rs b/uplink/src/lib.rs index 52f4acd0..5ab2a545 100644 --- a/uplink/src/lib.rs +++ b/uplink/src/lib.rs @@ -49,6 +49,7 @@ use anyhow::Error; use base::bridge::stream::Stream; use base::monitor::Monitor; +use base::CtrlTx; use collector::device_shadow::DeviceShadow; use collector::downloader::FileDownloader; use collector::installer::OTAInstaller; @@ -322,8 +323,9 @@ impl Uplink { ) } - pub fn spawn(&mut self, bridge: Bridge) -> Result<(), Error> { + pub fn spawn(&mut self, bridge: Bridge) -> Result { let (mqtt_metrics_tx, mqtt_metrics_rx) = bounded(10); + let (ctrl_actions_lane, ctrl_data_lane) = bridge.ctrl_tx(); let mut mqtt = Mqtt::new(self.config.clone(), self.action_tx.clone(), mqtt_metrics_tx); let mqtt_client = mqtt.client(); @@ -403,11 +405,11 @@ impl Uplink { }) }); - Ok(()) + Ok(CtrlTx { actions_lane: ctrl_actions_lane, data_lane: ctrl_data_lane }) } pub fn spawn_builtins(&mut self, bridge: &mut Bridge) -> Result<(), Error> { - let bridge_tx = bridge.tx(); + let bridge_tx = bridge.bridge_tx(); let route = ActionRoute { name: "launch_shell".to_owned(), timeout: Duration::from_secs(10) }; diff --git a/uplink/src/main.rs b/uplink/src/main.rs index 3cb23166..a09ece67 100644 --- a/uplink/src/main.rs +++ b/uplink/src/main.rs @@ -127,7 +127,7 @@ fn main() -> Result<(), Error> { let mut bridge = uplink.configure_bridge(); uplink.spawn_builtins(&mut bridge)?; - let bridge_tx = bridge.tx(); + let bridge_tx = bridge.bridge_tx(); let mut tcpapps = vec![]; for (app, cfg) in config.tcpapps.clone() { @@ -137,7 +137,7 @@ fn main() -> Result<(), Error> { bridge.register_action_routes(&cfg.actions, actions_tx)?; route_rx = Some(actions_rx) } - tcpapps.push(TcpJson::new(app, cfg, route_rx, bridge.tx())); + tcpapps.push(TcpJson::new(app, cfg, route_rx, bridge.bridge_tx())); } let simulator_actions = config.simulator.as_ref().and_then(|cfg| { @@ -151,10 +151,9 @@ fn main() -> Result<(), Error> { route_rx }); - uplink.spawn(bridge)?; + let ctrl_tx = uplink.spawn(bridge)?; if let Some(config) = config.simulator.clone() { - let bridge_tx = bridge_tx.clone(); spawn_named_thread("Simulator", || { simulator::start(config, bridge_tx, simulator_actions).unwrap(); }); @@ -162,10 +161,8 @@ fn main() -> Result<(), Error> { if config.console.enabled { let port = config.console.port; - let bridge_tx = bridge_tx.clone(); - spawn_named_thread("Uplink Console", move || { - console::start(port, reload_handle, bridge_tx) - }); + let ctrl_tx = ctrl_tx.clone(); + spawn_named_thread("Uplink Console", move || console::start(port, reload_handle, ctrl_tx)); } let rt = tokio::runtime::Builder::new_current_thread() @@ -194,7 +191,7 @@ fn main() -> Result<(), Error> { // Handle a shutdown signal from POSIX while let Some(signal) = signals.next().await { match signal { - SIGTERM | SIGINT | SIGQUIT => bridge_tx.trigger_shutdown().await, + SIGTERM | SIGINT | SIGQUIT => ctrl_tx.trigger_shutdown().await, s => error!("Couldn't handle signal: {s}"), } } From 0afd04b43256d072a5214c0448e4537afa5c5230 Mon Sep 17 00:00:00 2001 From: Pranav Kumar Date: Fri, 15 Dec 2023 13:11:06 +0530 Subject: [PATCH 10/20] feat: enable simulation on non-demo tenants (#317) --- simulator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulator.sh b/simulator.sh index 85bad046..240a51f7 100755 --- a/simulator.sh +++ b/simulator.sh @@ -83,7 +83,7 @@ download_auth_config() { echo "Downloading config: $url" mkdir -p devices curl --location $url \ - --header 'x-bytebeam-tenant: demo' \ + --header "x-bytebeam-tenant: $BYTEBEAM_TENANT_ID" \ --header "x-bytebeam-api-key: $BYTEBEAM_API_KEY" > devices/device_$id.json } From 071e922dd75706bf1faa934237d9542fb3d547cf Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 2 Jan 2024 18:42:10 +0530 Subject: [PATCH 11/20] feat: extract out system stat collector (#318) * feat: extract out system stat collector * refactor: handle uplink restarts with reconnects * ci: release tools --- .github/workflows/release.yml | 28 ++ Cargo.toml | 1 + tools/system-stats/Cargo.lock | 841 +++++++++++++++++++++++++++++++++ tools/system-stats/Cargo.toml | 18 + tools/system-stats/src/lib.rs | 636 +++++++++++++++++++++++++ tools/system-stats/src/main.rs | 71 +++ vd-lib | 1 + 7 files changed, 1596 insertions(+) create mode 100644 tools/system-stats/Cargo.lock create mode 100644 tools/system-stats/Cargo.toml create mode 100644 tools/system-stats/src/lib.rs create mode 100644 tools/system-stats/src/main.rs create mode 160000 vd-lib diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a4f47f4..72c42279 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,33 @@ on: types: [published] jobs: + release-tools: + name: Build tools/${{ matrix.build }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + build: [system-stats] + steps: + - uses: actions/checkout@v3 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true + target: x86_64-unknown-linux-musl + + - name: Build binary + working-directory: tools/${{ matrix.build }} + run: cargo build --verbose --release + + - name: Upload release archive + uses: softprops/action-gh-release@v1 + with: + files: tools/${{ matrix.build }}/target/release/${{ matrix.build }} + build-release: name: Build release for ${{ matrix.target }} runs-on: ${{ matrix.os }} @@ -105,6 +132,7 @@ jobs: uses: softprops/action-gh-release@v1 with: files: uplink* + build-release-android: name: Build release for android runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index c244beab..c2b1f2ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ exclude = [ "tools/deserialize-backup", "tools/simulator", + "tools/system-stats", "tools/tunshell", ] diff --git a/tools/system-stats/Cargo.lock b/tools/system-stats/Cargo.lock new file mode 100644 index 00000000..654de981 --- /dev/null +++ b/tools/system-stats/Cargo.lock @@ -0,0 +1,841 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crossbeam-deque" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "deranged" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "simplelog" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369" +dependencies = [ + "log", + "termcolor", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysinfo" +version = "0.26.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c18a6156d1f27a9592ee18c1a846ca8dd5c258b7179fc193ae87c74ebb666f5" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + +[[package]] +name = "system-stats" +version = "0.1.0" +dependencies = [ + "futures-util", + "log", + "serde", + "serde_json", + "simplelog", + "structopt", + "sysinfo", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "libc", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tokio" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +dependencies = [ + "backtrace", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.41", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/tools/system-stats/Cargo.toml b/tools/system-stats/Cargo.toml new file mode 100644 index 00000000..f5235776 --- /dev/null +++ b/tools/system-stats/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "system-stats" +version = "0.1.0" +edition = "2021" +authors = ["Devdutt Shenoi "] + +[dependencies] +futures-util = { version = "0.3", features = ["sink"] } +log = "0.4" +serde = { version = "1", features = ["derive"] } +serde_json = "1.0" +simplelog = "0.12.0" +structopt = "0.3" +sysinfo = "0.26" +thiserror = "1" +tokio = { version = "1", features = ["rt-multi-thread", "macros", "net"] } +tokio-stream = "0.1" +tokio-util = { version = "0.7", features = ["codec", "time"] } \ No newline at end of file diff --git a/tools/system-stats/src/lib.rs b/tools/system-stats/src/lib.rs new file mode 100644 index 00000000..200a10d9 --- /dev/null +++ b/tools/system-stats/src/lib.rs @@ -0,0 +1,636 @@ +use futures_util::SinkExt; +use log::error; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use sysinfo::{ + ComponentExt, CpuExt, DiskExt, NetworkData, NetworkExt, PidExt, ProcessExt, SystemExt, +}; +use tokio::{net::TcpStream, time::interval}; +use tokio_util::codec::{Framed, LinesCodec, LinesCodecError}; + +use std::{ + collections::HashMap, + time::{Duration, Instant, SystemTime, UNIX_EPOCH}, +}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("Io error {0}")] + Io(#[from] std::io::Error), + #[error("Lines codec error {0}")] + Codec(#[from] LinesCodecError), + #[error("Serde error {0}")] + Json(#[from] serde_json::error::Error), +} + +#[derive(Debug, Serialize)] +pub struct Payload { + pub stream: String, + pub sequence: u32, + pub timestamp: u64, + #[serde(flatten)] + pub payload: Value, +} + +fn clock() -> u64 { + SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64 +} + +type Pid = u32; + +#[derive(Debug, Default, Serialize, Clone)] +pub struct System { + sequence: u32, + timestamp: u64, + kernel_version: String, + uptime: u64, + no_processes: usize, + /// Average load within one minute. + load_avg_one: f64, + /// Average load within five minutes. + load_avg_five: f64, + /// Average load within fifteen minutes. + load_avg_fifteen: f64, + total_memory: u64, + available_memory: u64, + used_memory: u64, +} + +impl System { + fn init(sys: &sysinfo::System) -> System { + System { + kernel_version: match sys.kernel_version() { + Some(kv) => kv, + None => String::default(), + }, + total_memory: sys.total_memory(), + ..Default::default() + } + } + + fn update(&mut self, sys: &sysinfo::System, timestamp: u64) { + self.sequence += 1; + self.timestamp = timestamp; + self.uptime = sys.uptime(); + self.no_processes = sys.processes().len(); + let sysinfo::LoadAvg { one, five, fifteen } = sys.load_average(); + self.load_avg_one = one; + self.load_avg_five = five; + self.load_avg_fifteen = fifteen; + self.available_memory = sys.available_memory(); + self.used_memory = self.total_memory - self.available_memory; + } +} + +impl From<&System> for Payload { + fn from(value: &System) -> Self { + let System { + sequence, + timestamp, + kernel_version, + uptime, + no_processes, + load_avg_one, + load_avg_five, + load_avg_fifteen, + total_memory, + available_memory, + used_memory, + } = value; + + Payload { + stream: "uplink".to_owned(), + sequence: *sequence, + timestamp: *timestamp, + payload: json!({ + "kernel_version": kernel_version, + "uptime": uptime, + "no_processes": no_processes, + "load_avg_one": load_avg_one, + "load_avg_five": load_avg_five, + "load_avg_fifteen": load_avg_fifteen, + "total_memory": total_memory, + "available_memory": available_memory, + "used_memory": used_memory, + }), + } + } +} + +struct SystemStats { + stat: System, +} + +impl SystemStats { + fn push(&mut self, sys: &sysinfo::System, timestamp: u64) -> Payload { + self.stat.update(sys, timestamp); + + (&self.stat).into() + } +} + +#[derive(Debug, Serialize, Clone)] +struct Network { + sequence: u32, + timestamp: u64, + name: String, + incoming_data_rate: f64, + outgoing_data_rate: f64, + #[serde(skip_serializing)] + timer: Instant, +} + +impl Network { + fn init(name: String) -> Self { + Network { + sequence: 0, + timestamp: 0, + name, + incoming_data_rate: 0.0, + outgoing_data_rate: 0.0, + timer: Instant::now(), + } + } + + /// Update metrics values for network usage over time + fn update(&mut self, data: &NetworkData, timestamp: u64, sequence: u32) { + let update_period = self.timer.elapsed().as_secs_f64(); + // TODO: check if these calculations are correct + self.incoming_data_rate = data.total_received() as f64 / update_period; + self.outgoing_data_rate = data.total_transmitted() as f64 / update_period; + self.timestamp = timestamp; + self.sequence = sequence; + } +} + +impl From<&mut Network> for Payload { + fn from(value: &mut Network) -> Self { + let Network { sequence, timestamp, name, incoming_data_rate, outgoing_data_rate, .. } = + value; + + Payload { + stream: "uplink_network_stats".to_owned(), + sequence: *sequence, + timestamp: *timestamp, + payload: json!({ + "name": name, + "incoming_data_rate": incoming_data_rate, + "outgoing_data_rate": outgoing_data_rate, + }), + } + } +} + +struct NetworkStats { + sequence: u32, + map: HashMap, +} + +impl NetworkStats { + fn push( + &mut self, + net_name: String, + net_data: &sysinfo::NetworkData, + timestamp: u64, + ) -> Payload { + self.sequence += 1; + let net = self.map.entry(net_name.clone()).or_insert_with(|| Network::init(net_name)); + net.update(net_data, timestamp, self.sequence); + + net.into() + } +} + +#[derive(Debug, Serialize, Default, Clone)] +struct Disk { + sequence: u32, + timestamp: u64, + name: String, + total: u64, + available: u64, + used: u64, +} + +impl Disk { + fn init(name: String, disk: &sysinfo::Disk) -> Self { + Disk { name, total: disk.total_space(), ..Default::default() } + } + + fn update(&mut self, disk: &sysinfo::Disk, timestamp: u64, sequence: u32) { + self.total = disk.total_space(); + self.available = disk.available_space(); + self.used = self.total - self.available; + self.timestamp = timestamp; + self.sequence = sequence; + } +} + +impl From<&mut Disk> for Payload { + fn from(value: &mut Disk) -> Self { + let Disk { sequence, timestamp, name, total, available, used } = value; + + Payload { + stream: "uplink_disk_stats".to_owned(), + sequence: *sequence, + timestamp: *timestamp, + payload: json!({ + "name": name, + "total": total, + "available": available, + "used": used, + }), + } + } +} + +struct DiskStats { + sequence: u32, + map: HashMap, +} + +impl DiskStats { + fn push(&mut self, disk_data: &sysinfo::Disk, timestamp: u64) -> Payload { + self.sequence += 1; + let disk_name = disk_data.name().to_string_lossy().to_string(); + let disk = + self.map.entry(disk_name.clone()).or_insert_with(|| Disk::init(disk_name, disk_data)); + disk.update(disk_data, timestamp, self.sequence); + + disk.into() + } +} + +#[derive(Debug, Default, Serialize, Clone)] +struct Processor { + sequence: u32, + timestamp: u64, + name: String, + frequency: u64, + usage: f32, +} + +impl Processor { + fn init(name: String) -> Self { + Processor { name, ..Default::default() } + } + + fn update(&mut self, proc: &sysinfo::Cpu, timestamp: u64, sequence: u32) { + self.frequency = proc.frequency(); + self.usage = proc.cpu_usage(); + self.timestamp = timestamp; + self.sequence = sequence; + } +} + +impl From<&mut Processor> for Payload { + fn from(value: &mut Processor) -> Self { + let Processor { sequence, timestamp, name, frequency, usage } = value; + + Payload { + stream: "uplink_processor_stats".to_owned(), + sequence: *sequence, + timestamp: *timestamp, + payload: json!({ + "name": name, + "frequency": frequency, + "usage": usage, + }), + } + } +} + +struct ProcessorStats { + sequence: u32, + map: HashMap, +} + +impl ProcessorStats { + fn push(&mut self, proc_data: &sysinfo::Cpu, timestamp: u64) -> Payload { + let proc_name = proc_data.name().to_string(); + self.sequence += 1; + let proc = self.map.entry(proc_name.clone()).or_insert_with(|| Processor::init(proc_name)); + proc.update(proc_data, timestamp, self.sequence); + + proc.into() + } +} + +#[derive(Debug, Default, Serialize, Clone)] +struct Component { + sequence: u32, + timestamp: u64, + label: String, + temperature: f32, +} + +impl Component { + fn init(label: String) -> Self { + Component { label, ..Default::default() } + } + + fn update(&mut self, comp: &sysinfo::Component, timestamp: u64, sequence: u32) { + self.temperature = comp.temperature(); + self.timestamp = timestamp; + self.sequence = sequence; + } +} + +impl From<&mut Component> for Payload { + fn from(value: &mut Component) -> Self { + let Component { sequence, timestamp, label, temperature } = value; + + Payload { + stream: "uplink_component_stats".to_owned(), + sequence: *sequence, + timestamp: *timestamp, + payload: json!({ + "label": label, "temperature": temperature + }), + } + } +} + +struct ComponentStats { + sequence: u32, + map: HashMap, +} + +impl ComponentStats { + fn push(&mut self, comp_data: &sysinfo::Component, timestamp: u64) -> Payload { + let comp_label = comp_data.label().to_string(); + self.sequence += 1; + let comp = + self.map.entry(comp_label.clone()).or_insert_with(|| Component::init(comp_label)); + comp.update(comp_data, timestamp, self.sequence); + + comp.into() + } +} + +#[derive(Debug, Default, Serialize, Clone)] +struct Process { + sequence: u32, + timestamp: u64, + pid: Pid, + name: String, + cpu_usage: f32, + mem_usage: u64, + disk_total_written_bytes: u64, + disk_written_bytes: u64, + disk_total_read_bytes: u64, + disk_read_bytes: u64, + start_time: u64, +} + +impl Process { + fn init(pid: Pid, name: String, start_time: u64) -> Self { + Process { pid, name, start_time, ..Default::default() } + } + + fn update(&mut self, proc: &sysinfo::Process, timestamp: u64, sequence: u32) { + let sysinfo::DiskUsage { total_written_bytes, written_bytes, total_read_bytes, read_bytes } = + proc.disk_usage(); + self.disk_total_written_bytes = total_written_bytes; + self.disk_written_bytes = written_bytes; + self.disk_total_read_bytes = total_read_bytes; + self.disk_read_bytes = read_bytes; + self.cpu_usage = proc.cpu_usage(); + self.mem_usage = proc.memory(); + self.timestamp = timestamp; + self.sequence = sequence; + } +} + +impl From<&mut Process> for Payload { + fn from(value: &mut Process) -> Self { + let Process { + sequence, + timestamp, + pid, + name, + cpu_usage, + mem_usage, + disk_total_written_bytes, + disk_written_bytes, + disk_total_read_bytes, + disk_read_bytes, + start_time, + } = value; + + Payload { + stream: "uplink_process_stats".to_owned(), + sequence: *sequence, + timestamp: *timestamp, + payload: json!({ + "pid": pid, + "name": name, + "cpu_usage": cpu_usage, + "mem_usage": mem_usage, + "disk_total_written_bytes": disk_total_written_bytes, + "disk_written_bytes": disk_written_bytes, + "disk_total_read_bytes": disk_total_read_bytes, + "disk_read_bytes": disk_read_bytes, + "start_time": start_time, + }), + } + } +} + +struct ProcessStats { + sequence: u32, + map: HashMap, +} + +impl ProcessStats { + fn push( + &mut self, + id: Pid, + proc_data: &sysinfo::Process, + name: String, + timestamp: u64, + ) -> Payload { + self.sequence += 1; + let proc = + self.map.entry(id).or_insert_with(|| Process::init(id, name, proc_data.start_time())); + proc.update(proc_data, timestamp, self.sequence); + + proc.into() + } +} + +#[derive(Debug, Clone, Deserialize, Default)] +pub struct Config { + pub process_names: Vec, + pub update_period: u64, +} + +/// Collects and forward system information such as kernel version, memory and disk space usage, +/// information regarding running processes, network and processor usage, etc to an IoT platform. +pub struct StatCollector { + /// Handle to sysinfo struct containing system information. + sys: sysinfo::System, + /// System information values to be serialized. + system: SystemStats, + /// Information about running processes. + processes: ProcessStats, + /// Individual Processor information. + processors: ProcessorStats, + /// Information regarding individual Network interfaces. + networks: NetworkStats, + /// Information regarding individual Disks. + disks: DiskStats, + /// Temperature information from individual components. + components: ComponentStats, + /// System stats configuration. + config: Config, + /// Handle to.send stats as payload onto bridge + client: Framed, +} + +impl StatCollector { + /// Create and initialize a stat collector + pub fn new(config: Config, client: Framed) -> Self { + let mut sys = sysinfo::System::new(); + sys.refresh_disks_list(); + sys.refresh_networks_list(); + sys.refresh_memory(); + sys.refresh_cpu(); + sys.refresh_components(); + + let mut map = HashMap::new(); + for disk_data in sys.disks() { + let disk_name = disk_data.name().to_string_lossy().to_string(); + map.insert(disk_name.clone(), Disk::init(disk_name, disk_data)); + } + let disks = DiskStats { sequence: 0, map }; + + let mut map = HashMap::new(); + for (net_name, _) in sys.networks() { + map.insert(net_name.to_owned(), Network::init(net_name.to_owned())); + } + let networks = NetworkStats { sequence: 0, map }; + + let mut map = HashMap::new(); + for proc in sys.cpus().iter() { + let proc_name = proc.name().to_owned(); + map.insert(proc_name.clone(), Processor::init(proc_name)); + } + let processors = ProcessorStats { sequence: 0, map }; + + let processes = ProcessStats { sequence: 0, map: HashMap::new() }; + let components = ComponentStats { sequence: 0, map: HashMap::new() }; + + let system = SystemStats { stat: System::init(&sys) }; + + StatCollector { + sys, + system, + config, + processes, + disks, + networks, + processors, + components, + client, + } + } + + /// Stat collector execution loop, sleeps for the duation of `config.stats.update_period` in seconds. + /// Update system information values and increment sequence numbers, while.sending to specific data streams. + pub async fn start(mut self) -> Result<(), Error> { + let mut interval = interval(Duration::from_secs(self.config.update_period)); + loop { + interval.tick().await; + + self.update_memory_stats().await?; + self.update_disk_stats().await?; + self.update_network_stats().await?; + self.update_cpu_stats().await?; + self.update_component_stats().await?; + self.update_process_stats().await?; + } + } + + // Refresh memory stats + async fn update_memory_stats(&mut self) -> Result<(), Error> { + self.sys.refresh_memory(); + let timestamp = clock(); + let payload = self.system.push(&self.sys, timestamp); + let payload = serde_json::to_string(&payload)?; + self.client.send(payload).await?; + + Ok(()) + } + + // Refresh disk stats + async fn update_disk_stats(&mut self) -> Result<(), Error> { + self.sys.refresh_disks(); + let timestamp = clock(); + for disk_data in self.sys.disks() { + let payload = self.disks.push(disk_data, timestamp); + let payload = serde_json::to_string(&payload)?; + self.client.send(payload).await?; + } + + Ok(()) + } + + // Refresh network byte rate stats + async fn update_network_stats(&mut self) -> Result<(), Error> { + self.sys.refresh_networks(); + let timestamp = clock(); + for (net_name, net_data) in self.sys.networks() { + let payload = self.networks.push(net_name.to_owned(), net_data, timestamp); + let payload = serde_json::to_string(&payload)?; + self.client.send(payload).await?; + } + + Ok(()) + } + + // Refresh processor stats + async fn update_cpu_stats(&mut self) -> Result<(), Error> { + self.sys.refresh_cpu(); + let timestamp = clock(); + for proc_data in self.sys.cpus().iter() { + let payload = self.processors.push(proc_data, timestamp); + let payload = serde_json::to_string(&payload)?; + self.client.send(payload).await?; + } + + Ok(()) + } + + // Refresh component stats + async fn update_component_stats(&mut self) -> Result<(), Error> { + self.sys.refresh_components(); + let timestamp = clock(); + for comp_data in self.sys.components().iter() { + let payload = self.components.push(comp_data, timestamp); + let payload = serde_json::to_string(&payload)?; + self.client.send(payload).await?; + } + + Ok(()) + } + + // Refresh processes info + // NOTE: This can be further optimized by storing pids of interested processes + // at init and only collecting process information for them instead of iterating + // over all running processes as is being done now. + async fn update_process_stats(&mut self) -> Result<(), Error> { + self.sys.refresh_processes(); + let timestamp = clock(); + for (&id, p) in self.sys.processes() { + let name = p.cmd().get(0).map(|s| s.to_string()).unwrap_or(p.name().to_string()); + + if self.config.process_names.contains(&name) { + let payload = self.processes.push(id.as_u32(), p, name, timestamp); + let payload = serde_json::to_string(&payload)?; + self.client.send(payload).await?; + } + } + + Ok(()) + } +} diff --git a/tools/system-stats/src/main.rs b/tools/system-stats/src/main.rs new file mode 100644 index 00000000..131d0393 --- /dev/null +++ b/tools/system-stats/src/main.rs @@ -0,0 +1,71 @@ +use std::time::Duration; + +use log::{error, LevelFilter}; +use simplelog::{ + ColorChoice, CombinedLogger, ConfigBuilder, LevelPadding, TermLogger, TerminalMode, +}; +use structopt::StructOpt; +use system_stats::{Config, StatCollector}; +use tokio::net::TcpStream; +use tokio_util::codec::{Framed, LinesCodec}; + +#[derive(StructOpt, Debug)] +#[structopt(name = "simulator", about = "simulates a demo device")] +pub struct CommandLine { + /// uplink port + #[structopt(short = "p", help = "uplink port")] + pub port: u16, + /// log level (v: info, vv: debug, vvv: trace) + #[structopt(short = "v", long = "verbose", parse(from_occurrences))] + pub verbose: u8, + /// name of processes to be monitored + #[structopt(short = "P", help = "processes")] + pub process_names: Vec, + /// time between updates + #[structopt(short = "t", help = "update period", default_value = "30")] + pub update_period: u64, +} + +#[tokio::main] +async fn main() { + let CommandLine { process_names, update_period, port, .. } = init(); + + let addr = format!("localhost:{}", port); + + loop { + let Ok(stream) = TcpStream::connect(&addr).await else { + error!("Uplink is not running, will reconnect after sleeping"); + std::thread::sleep(Duration::from_secs(update_period)); + continue; + }; + let client = Framed::new(stream, LinesCodec::new()); + let config = Config { process_names: process_names.clone(), update_period }; + + let collector = StatCollector::new(config, client); + if let Err(e) = collector.start().await { + error!("Error forwarding stats: {e}"); + } + } +} + +fn init() -> CommandLine { + let commandline: CommandLine = StructOpt::from_args(); + let level = match commandline.verbose { + 0 => LevelFilter::Warn, + 1 => LevelFilter::Info, + 2 => LevelFilter::Debug, + _ => LevelFilter::Trace, + }; + + let mut config = ConfigBuilder::new(); + config + .set_location_level(LevelFilter::Off) + .set_target_level(LevelFilter::Error) + .set_thread_level(LevelFilter::Error) + .set_level_padding(LevelPadding::Right); + + let loggers = TermLogger::new(level, config.build(), TerminalMode::Mixed, ColorChoice::Auto); + CombinedLogger::init(vec![loggers]).unwrap(); + + commandline +} diff --git a/vd-lib b/vd-lib new file mode 160000 index 00000000..cdaec8b6 --- /dev/null +++ b/vd-lib @@ -0,0 +1 @@ +Subproject commit cdaec8b6dacc3779e063e0ff1241a41a821b0cf2 From 2d1a69d87f29f26911a40c7873913f78bb6f700b Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Thu, 4 Jan 2024 15:59:24 +0530 Subject: [PATCH 12/20] fix: ensure storages are force flushed during uplink shutdown (#311) * feat: force serializer into crash mode on shutdown (#309) * feat: force serializer into crash mode on shutdown * log: writing incoming data into persistence * fix: pull pending requests from channel * feat: force flush non-overflowed in-memory buffers (#310) * feat: force flush non-overflowed in-memory buffers * fix: increase shutdown period NOTE: necessary for safely handling force flush to disk * log: successful force flush * doc: update comment * fix: `try_recv` to trigger storage flush NOTE: needs to be verified for any realistic possibility of data loss * fix: ignore empty buffers * fix: write not read buffer * fix: ignore empty write buffers * fix: wait max 2 secs for data flushed from bridge * test: fix unintended shutdown * chore: updated rumqttc main * refactor: shutdown mode * doc: shutdown is the same as crash * log: shutdown not crash * feat: `Ctrl` handles for `Serializer` * doc: revert unnecessary comment removal * refactor: serializer shutdown is the end --- Cargo.lock | 174 ++++++++++++++++++++---------- storage/src/lib.rs | 10 ++ uplink/src/base/mod.rs | 8 +- uplink/src/base/serializer/mod.rs | 91 +++++++++++++++- uplink/src/lib.rs | 9 +- uplink/src/main.rs | 2 +- 6 files changed, 235 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0e98f88..05655cac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,7 +289,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -344,9 +344,9 @@ dependencies = [ [[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", @@ -354,9 +354,9 @@ 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" @@ -564,12 +564,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -619,7 +619,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall 0.3.5", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1153,9 +1153,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1208,9 +1208,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" @@ -1322,7 +1322,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1546,7 +1546,7 @@ dependencies = [ "libc", "redox_syscall 0.4.1", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -2047,22 +2047,22 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" dependencies = [ "cc", "getrandom 0.2.11", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rumqttc" version = "0.23.0" -source = "git+https://github.com/bytebeamio/rumqtt#22d7fae16e3be9cc4f65b49eb31b2fe425aa9e3f" +source = "git+https://github.com/bytebeamio/rumqtt#fdfe9abff099ece29715f38bba93925dcc2ed0eb" dependencies = [ "bytes 1.5.0", "flume 0.11.0", @@ -2102,15 +2102,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.25" +version = "0.38.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" dependencies = [ "bitflags 2.4.1", - "errno 0.3.7", + "errno 0.3.8", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -2133,7 +2133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", - "ring 0.17.5", + "ring 0.17.6", "rustls-webpki", "sct 0.7.1", ] @@ -2165,7 +2165,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.5", + "ring 0.17.6", "untrusted 0.9.0", ] @@ -2187,7 +2187,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2212,7 +2212,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.5", + "ring 0.17.6", "untrusted 0.9.0", ] @@ -2498,7 +2498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2697,7 +2697,7 @@ dependencies = [ "fastrand", "redox_syscall 0.4.1", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2839,7 +2839,7 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.5", "tokio-macros 2.2.0", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3351,9 +3351,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3361,9 +3361,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -3376,9 +3376,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3388,9 +3388,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3398,9 +3398,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -3411,9 +3411,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-streams" @@ -3430,9 +3430,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -3524,7 +3524,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -3533,7 +3533,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "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]] @@ -3542,13 +3551,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "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]] @@ -3557,42 +3581,84 @@ 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.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.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.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.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.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.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" @@ -3600,7 +3666,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if 1.0.0", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] diff --git a/storage/src/lib.rs b/storage/src/lib.rs index e4783797..d692cbc7 100644 --- a/storage/src/lib.rs +++ b/storage/src/lib.rs @@ -16,6 +16,8 @@ pub enum Error { NotBackup, #[error("Corrupted backup file")] CorruptedFile, + #[error("Empty write buffer")] + NoWrites, } pub struct Storage { @@ -92,6 +94,14 @@ impl Storage { return Ok(None); } + self.flush() + } + + /// Force flush the contents of write buffer onto disk + pub fn flush(&mut self) -> Result, Error> { + if self.current_write_file.is_empty() { + return Err(Error::NoWrites); + } match &mut self.persistence { Some(persistence) => { let NextFile { mut file, deleted } = persistence.open_next_write_file()?; diff --git a/uplink/src/base/mod.rs b/uplink/src/base/mod.rs index 2cbe1e64..bfc19ced 100644 --- a/uplink/src/base/mod.rs +++ b/uplink/src/base/mod.rs @@ -15,6 +15,7 @@ use crate::collector::logcat::LogcatConfig; use self::bridge::stream::MAX_BUFFER_SIZE; use self::bridge::{ActionsLaneCtrlTx, DataLaneCtrlTx}; +use self::serializer::CtrlTx as SerializerCtrlTx; pub mod actions; pub mod bridge; @@ -289,10 +290,15 @@ pub struct Config { pub struct CtrlTx { pub actions_lane: ActionsLaneCtrlTx, pub data_lane: DataLaneCtrlTx, + pub serializer: SerializerCtrlTx, } impl CtrlTx { pub async fn trigger_shutdown(&self) { - join!(self.actions_lane.trigger_shutdown(), self.data_lane.trigger_shutdown()); + join!( + self.actions_lane.trigger_shutdown(), + self.data_lane.trigger_shutdown(), + self.serializer.trigger_shutdown() + ); } } diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index ea5b2469..dc55de50 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -2,10 +2,11 @@ mod metrics; use std::collections::{HashMap, VecDeque}; use std::io::{self, Write}; +use std::time::Instant; use std::{sync::Arc, time::Duration}; use bytes::Bytes; -use flume::{Receiver, RecvError, Sender}; +use flume::{bounded, Receiver, RecvError, Sender}; use log::{debug, error, info, trace}; use lz4_flex::frame::FrameEncoder; use rumqttc::*; @@ -58,6 +59,8 @@ pub enum Error { EmptyStorage, #[error("Permission denied while accessing persistence directory \"{0}\"")] Persistence(String), + #[error("Serializer has shutdown after handling crash")] + Shutdown, } #[derive(Debug, PartialEq)] @@ -66,6 +69,7 @@ enum Status { SlowEventloop(Publish, Arc), EventLoopReady, EventLoopCrash(Publish, Arc), + Shutdown, } /// Description of an interface that the [`Serializer`] expects to be provided by the MQTT client to publish the serialized data with. @@ -206,6 +210,19 @@ impl StorageHandler { None } + + fn flush_all(&mut self) { + for (stream_config, storage) in self.map.iter_mut() { + match storage.flush() { + Ok(_) => trace!("Force flushed stream = {} onto disk", stream_config.topic), + Err(storage::Error::NoWrites) => {} + Err(e) => error!( + "Error when force flushing storage = {}; error = {e}", + stream_config.topic + ), + } + } + } } /// The uplink Serializer is the component that deals with serializing, compressing and writing data onto disk or Network. @@ -246,6 +263,9 @@ impl StorageHandler { /// but continue trying to publish /// ///``` +/// +/// NOTE: Shutdown mode and crash mode are only different in how they get triggered, +/// but should be considered as interchangeable in the above diagram. /// [`start()`]: Serializer::start /// [`try_publish()`]: AsyncClient::try_publish /// [`publish()`]: AsyncClient::publish @@ -257,6 +277,9 @@ pub struct Serializer { metrics: SerializerMetrics, metrics_tx: Sender, pending_metrics: VecDeque, + /// Control handles + ctrl_rx: Receiver, + ctrl_tx: Sender, } impl Serializer { @@ -269,6 +292,7 @@ impl Serializer { metrics_tx: Sender, ) -> Result, Error> { let storage_handler = StorageHandler::new(config.clone())?; + let (ctrl_tx, ctrl_rx) = bounded(1); Ok(Serializer { config, @@ -278,9 +302,39 @@ impl Serializer { metrics: SerializerMetrics::new("catchup"), metrics_tx, pending_metrics: VecDeque::with_capacity(3), + ctrl_tx, + ctrl_rx, }) } + pub fn ctrl_tx(&self) -> CtrlTx { + CtrlTx { inner: self.ctrl_tx.clone() } + } + + /// Write all data received, from here-on, to disk only, shutdown serializer + /// after handling all data payloads. + fn shutdown(&mut self) -> Result<(), Error> { + debug!("Forced into shutdown mode, writing all incoming data to persistence."); + + loop { + // Collect remaining data packets and write to disk + // NOTE: wait 2s to allow bridge to shutdown and flush leftover data. + let deadline = Instant::now() + Duration::from_secs(2); + let Ok(data) = self.collector_rx.recv_deadline(deadline) else { + self.storage_handler.flush_all(); + return Ok(()); + }; + let stream_config = data.stream_config(); + let publish = construct_publish(data)?; + let storage = self.storage_handler.select(&stream_config); + match write_to_disk(publish, storage) { + Ok(Some(deleted)) => debug!("Lost segment = {deleted}"), + Ok(_) => {} + Err(e) => error!("Shutdown: write error = {:?}", e), + } + } + } + /// Write all data received, from here-on, to disk only. async fn crash( &mut self, @@ -358,6 +412,10 @@ impl Serializer { _ = interval.tick() => { check_metrics(&mut self.metrics, &self.storage_handler); } + // Transition into crash mode when uplink is shutting down + Ok(SerializerShutdown) = self.ctrl_rx.recv_async() => { + break Ok(Status::Shutdown) + } } }; @@ -468,6 +526,10 @@ impl Serializer { _ = interval.tick() => { let _ = check_and_flush_metrics(&mut self.pending_metrics, &mut self.metrics, &self.metrics_tx, &self.storage_handler); } + // Transition into crash mode when uplink is shutting down + Ok(SerializerShutdown) = self.ctrl_rx.recv_async() => { + return Ok(Status::Shutdown) + } } }; @@ -514,6 +576,10 @@ impl Serializer { debug!("Failed to flush serializer metrics (normal). Error = {}", e); } } + // Transition into crash mode when uplink is shutting down + Ok(SerializerShutdown) = self.ctrl_rx.recv_async() => { + return Ok(Status::Shutdown) + } } } } @@ -528,10 +594,17 @@ impl Serializer { Status::SlowEventloop(publish, stream) => self.slow(publish, stream).await?, Status::EventLoopReady => self.catchup().await?, Status::EventLoopCrash(publish, stream) => self.crash(publish, stream).await?, + Status::Shutdown => break, }; status = next_status; } + + self.shutdown()?; + + info!("Serializer has handled all pending packets, shutting down"); + + Ok(()) } } @@ -711,6 +784,22 @@ fn check_and_flush_metrics( Ok(()) } +/// Command to remotely trigger `Serializer` shutdown +pub(crate) struct SerializerShutdown; + +/// Handle to send control messages to `Serializer` +#[derive(Debug, Clone)] +pub struct CtrlTx { + pub(crate) inner: Sender, +} + +impl CtrlTx { + /// Triggers shutdown of `Serializer` + pub async fn trigger_shutdown(&self) { + self.inner.send_async(SerializerShutdown).await.unwrap() + } +} + // TODO(RT): Test cases // - Restart with no internet but files on disk diff --git a/uplink/src/lib.rs b/uplink/src/lib.rs index 5ab2a545..ae88dec2 100644 --- a/uplink/src/lib.rs +++ b/uplink/src/lib.rs @@ -336,6 +336,7 @@ impl Uplink { mqtt_client.clone(), self.serializer_metrics_tx(), )?; + let ctrl_serializer = serializer.ctrl_tx(); // Serializer thread to handle network conditions state machine // and send data to mqtt thread @@ -381,7 +382,7 @@ impl Uplink { }) }); - let Bridge { data: mut data_lane, actions: mut actions_lane } = bridge; + let Bridge { data: mut data_lane, actions: mut actions_lane, .. } = bridge; // Bridge thread to direct actions spawn_named_thread("Bridge actions_lane", || { @@ -405,7 +406,11 @@ impl Uplink { }) }); - Ok(CtrlTx { actions_lane: ctrl_actions_lane, data_lane: ctrl_data_lane }) + Ok(CtrlTx { + actions_lane: ctrl_actions_lane, + data_lane: ctrl_data_lane, + serializer: ctrl_serializer, + }) } pub fn spawn_builtins(&mut self, bridge: &mut Bridge) -> Result<(), Error> { diff --git a/uplink/src/main.rs b/uplink/src/main.rs index a09ece67..4b42ae21 100644 --- a/uplink/src/main.rs +++ b/uplink/src/main.rs @@ -200,7 +200,7 @@ fn main() -> Result<(), Error> { uplink.resolve_on_shutdown().await.unwrap(); info!("Uplink shutting down..."); // NOTE: wait 5s to allow serializer to write to network/disk - sleep(Duration::from_secs(5)).await; + sleep(Duration::from_secs(10)).await; }); Ok(()) From 7b7d4e48b69d5f7ce19e6a7516f4f15b5b64b5b7 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Thu, 4 Jan 2024 20:45:09 +0530 Subject: [PATCH 13/20] feat: persist inflight publishes and send on restart (#299) * changes by vilayat * changes by vilayat * fix: basic implementation fixes, needs debugging * doc: note on where to load inflight publishes * fix: `EventLoop::clean` to force persist inflight * chore: cleanup * doc: remove outdated comments * doc: don't disconnect, note why * chore: rm unused loc * feat: load saved inflight publishes on uplink restart (#307) * Implemeted reading from disk and publishing onto the network * inflight persistence logic * doc: make the code readable --------- Co-authored-by: Devdutt Shenoi * chore: revert unrelated changes * doc: make it clear what is happening * doc: replace commented out code with TODO * fix: `Error=PacketIdZero` * chore: cargo update * fix: handle incoming data during inflight recovery * doc: describe undesired behavior * refactor: DRY `PersistenceFile` * log: add condition for successful completion * doc: improve comments in `recovery` * refactor: improve readability with placement * fix: merge breaking code * doc: code improvement TODO based on #311 * feat: `Ctrl` handles for `Mqtt` * refactor: remove code that never gets hit * refactor: load pending packets into eventloop * fix: delete file once read * refactor: error handling in recovery * fix: glienicke bridge to limit inflight growth * refactor: unnecessary copy * style: don't log before success * log: make sense * fix: save pending files from getting lost * fix: `VecDeque` to maintain order * doc: revert update to illustration * style: remove whitespace * rm: unused directories * chore: use main rumqtt * doc: update note * fix: don't change pkid of inflight * log: improve messaging * style: make it obvious --------- Co-authored-by: vilayat-ali Co-authored-by: Syed Vilayat Ali Rizvi <73014428+Vilayat-Ali@users.noreply.github.com> --- Cargo.lock | 358 ++++++++++++++---------------- tools/vd-lib | 1 - uplink/src/base/mod.rs | 3 + uplink/src/base/mqtt/mod.rs | 223 ++++++++++++++----- uplink/src/base/serializer/mod.rs | 6 +- uplink/src/lib.rs | 2 + vd-lib | 1 - 7 files changed, 343 insertions(+), 251 deletions(-) delete mode 160000 tools/vd-lib delete mode 160000 vd-lib diff --git a/Cargo.lock b/Cargo.lock index 05655cac..40dab31e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,19 +65,19 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -137,7 +137,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sync_wrapper", - "tokio 1.34.0", + "tokio 1.35.1", "tower", "tower-layer", "tower-service", @@ -369,9 +369,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -380,22 +380,20 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" dependencies = [ "autocfg", "cfg-if 1.0.0", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" dependencies = [ "cfg-if 1.0.0", ] @@ -409,7 +407,7 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio 0.8.9", + "mio 0.8.10", "parking_lot", "signal-hook", "signal-hook-mio", @@ -446,7 +444,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -457,14 +455,14 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -472,9 +470,9 @@ dependencies = [ [[package]] name = "deunicode" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a1abaf4d861455be59f64fd2b55606cb151fce304ede7165f410243ce96bde6" +checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" [[package]] name = "digest" @@ -494,7 +492,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -529,7 +527,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -584,9 +582,9 @@ dependencies = [ [[package]] name = "fake" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26221445034074d46b276e13eb97a265ebdb8ed8da705c4dddd3dd20b66b45d2" +checksum = "1c25829bde82205da46e1823b2259db6273379f626fc211f126f65654a2669be" dependencies = [ "deunicode", "dummy", @@ -612,14 +610,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 1.0.0", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall", + "windows-sys 0.52.0", ] [[package]] @@ -710,9 +708,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -725,9 +723,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -735,15 +733,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -752,38 +750,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-test" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ad78d6c79a3c76f8bc7496240d0586e069ed6797824fdd8c41d7c42b145b8d" +checksum = "ce388237b32ac42eca0df1ba55ed3bbda4eaf005d7d4b5dbc0b20ab962928ac9" dependencies = [ "futures-core", "futures-executor", @@ -798,9 +796,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -908,7 +906,7 @@ dependencies = [ "http", "indexmap 2.1.0", "slab", - "tokio 1.34.0", + "tokio 1.35.1", "tokio-util 0.7.10", "tracing", ] @@ -968,9 +966,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 1.5.0", "http", @@ -1006,9 +1004,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes 1.5.0", "futures-channel", @@ -1021,8 +1019,8 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.13", - "socket2 0.4.10", - "tokio 1.34.0", + "socket2", + "tokio 1.35.1", "tower-service", "tracing", "want", @@ -1037,16 +1035,16 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.9", - "tokio 1.34.0", + "rustls 0.21.10", + "tokio 1.35.1", "tokio-rustls 0.24.1", ] [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1138,9 +1136,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[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" @@ -1178,9 +1176,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libgit2-sys" @@ -1254,18 +1252,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memory_units" @@ -1315,9 +1304,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -1453,18 +1442,18 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[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" @@ -1474,9 +1463,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.60" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ "bitflags 2.4.1", "cfg-if 1.0.0", @@ -1495,7 +1484,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -1506,18 +1495,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.1.6+3.1.4" +version = "300.2.1+3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.96" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", @@ -1544,7 +1533,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "smallvec", "windows-targets 0.48.5", ] @@ -1598,7 +1587,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -1621,9 +1610,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "pnet_base" @@ -1744,9 +1733,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] @@ -1759,9 +1748,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1894,15 +1883,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[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" @@ -1990,9 +1970,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ "base64 0.21.5", "bytes 1.5.0", @@ -2011,13 +1991,13 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.9", + "rustls 0.21.10", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "system-configuration", - "tokio 1.34.0", + "tokio 1.35.1", "tokio-rustls 0.24.1", "tokio-util 0.7.10", "tower-service", @@ -2047,9 +2027,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", "getrandom 0.2.11", @@ -2062,7 +2042,7 @@ dependencies = [ [[package]] name = "rumqttc" version = "0.23.0" -source = "git+https://github.com/bytebeamio/rumqtt#fdfe9abff099ece29715f38bba93925dcc2ed0eb" +source = "git+https://github.com/bytebeamio/rumqtt#eca37defa880f5060dd66be4d779bba0fbf91e8a" dependencies = [ "bytes 1.5.0", "flume 0.11.0", @@ -2072,7 +2052,7 @@ dependencies = [ "rustls-pemfile", "rustls-webpki", "thiserror", - "tokio 1.34.0", + "tokio 1.35.1", "tokio-rustls 0.24.1", ] @@ -2097,14 +2077,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.20", + "semver 1.0.21", ] [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno 0.3.8", @@ -2128,12 +2108,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.9" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.6", + "ring 0.17.7", "rustls-webpki", "sct 0.7.1", ] @@ -2165,7 +2145,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.6", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -2177,17 +2157,17 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[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 = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2212,7 +2192,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.6", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -2256,9 +2236,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "semver-parser" @@ -2268,29 +2248,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -2299,9 +2279,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" dependencies = [ "itoa", "serde", @@ -2345,7 +2325,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -2441,7 +2421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", - "mio 0.8.9", + "mio 0.8.10", "signal-hook", ] @@ -2463,7 +2443,7 @@ dependencies = [ "futures-core", "libc", "signal-hook", - "tokio 1.34.0", + "tokio 1.35.1", ] [[package]] @@ -2481,16 +2461,6 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi 0.3.9", -] - [[package]] name = "socket2" version = "0.5.5" @@ -2582,9 +2552,9 @@ dependencies = [ "parking_lot", "pnet_packet", "rand 0.8.5", - "socket2 0.5.5", + "socket2", "thiserror", - "tokio 1.34.0", + "tokio 1.35.1", "tracing", ] @@ -2601,9 +2571,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" dependencies = [ "proc-macro2", "quote", @@ -2689,15 +2659,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if 1.0.0", "fastrand", - "redox_syscall 0.4.1", + "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2729,22 +2699,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -2759,9 +2729,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", "itoa", @@ -2779,9 +2749,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -2826,18 +2796,18 @@ dependencies = [ [[package]] name = "tokio" -version = "1.34.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes 1.5.0", "libc", - "mio 0.8.9", + "mio 0.8.10", "num_cpus", "pin-project-lite 0.2.13", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros 2.2.0", "windows-sys 0.48.0", ] @@ -2852,7 +2822,7 @@ dependencies = [ "once_cell", "pin-project-lite 0.2.13", "tokio 0.2.25", - "tokio 1.34.0", + "tokio 1.35.1", "tokio-stream", ] @@ -2875,7 +2845,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -2906,8 +2876,8 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.9", - "tokio 1.34.0", + "rustls 0.21.10", + "tokio 1.35.1", ] [[package]] @@ -2918,7 +2888,7 @@ checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", "pin-project-lite 0.2.13", - "tokio 1.34.0", + "tokio 1.35.1", ] [[package]] @@ -2947,7 +2917,7 @@ dependencies = [ "futures-sink", "pin-project-lite 0.2.13", "slab", - "tokio 1.34.0", + "tokio 1.35.1", "tracing", ] @@ -2970,7 +2940,7 @@ dependencies = [ "futures-util", "pin-project 1.1.3", "pin-project-lite 0.2.13", - "tokio 1.34.0", + "tokio 1.35.1", "tower-layer", "tower-service", "tracing", @@ -3008,7 +2978,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -3052,9 +3022,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" @@ -3161,9 +3131,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" @@ -3239,7 +3209,7 @@ dependencies = [ "tempdir", "thiserror", "time", - "tokio 1.34.0", + "tokio 1.35.1", "tokio-compat-02", "tokio-stream", "tokio-util 0.7.10", @@ -3274,7 +3244,7 @@ dependencies = [ "futures-util", "serde", "serde_json", - "tokio 1.34.0", + "tokio 1.35.1", "tokio-stream", "tokio-util 0.7.10", "uplink", @@ -3370,7 +3340,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", "wasm-bindgen-shared", ] @@ -3404,7 +3374,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3520,11 +3490,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -3681,11 +3651,13 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +checksum = "914566e6413e7fa959cc394fb30e563ba80f3541fbd40816d4c05a0fc3f2a0f1" dependencies = [ "libc", + "linux-raw-sys", + "rustix", ] [[package]] diff --git a/tools/vd-lib b/tools/vd-lib deleted file mode 160000 index cdaec8b6..00000000 --- a/tools/vd-lib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cdaec8b6dacc3779e063e0ff1241a41a821b0cf2 diff --git a/uplink/src/base/mod.rs b/uplink/src/base/mod.rs index bfc19ced..527763a0 100644 --- a/uplink/src/base/mod.rs +++ b/uplink/src/base/mod.rs @@ -15,6 +15,7 @@ use crate::collector::logcat::LogcatConfig; use self::bridge::stream::MAX_BUFFER_SIZE; use self::bridge::{ActionsLaneCtrlTx, DataLaneCtrlTx}; +use self::mqtt::CtrlTx as MqttCtrlTx; use self::serializer::CtrlTx as SerializerCtrlTx; pub mod actions; @@ -290,6 +291,7 @@ pub struct Config { pub struct CtrlTx { pub actions_lane: ActionsLaneCtrlTx, pub data_lane: DataLaneCtrlTx, + pub mqtt: MqttCtrlTx, pub serializer: SerializerCtrlTx, } @@ -298,6 +300,7 @@ impl CtrlTx { join!( self.actions_lane.trigger_shutdown(), self.data_lane.trigger_shutdown(), + self.mqtt.trigger_shutdown(), self.serializer.trigger_shutdown() ); } diff --git a/uplink/src/base/mqtt/mod.rs b/uplink/src/base/mqtt/mod.rs index 6e408750..35ecf622 100644 --- a/uplink/src/base/mqtt/mod.rs +++ b/uplink/src/base/mqtt/mod.rs @@ -1,8 +1,10 @@ -use flume::{Sender, TrySendError}; +use bytes::BytesMut; +use flume::{bounded, Receiver, Sender, TrySendError}; use log::{debug, error, info}; +use storage::PersistenceFile; use thiserror::Error; -use tokio::task; use tokio::time::Duration; +use tokio::{select, task}; use std::fs::File; use std::io::Read; @@ -10,8 +12,8 @@ use std::path::Path; use crate::{Action, Config}; use rumqttc::{ - AsyncClient, ConnectionError, Event, EventLoop, Incoming, MqttOptions, Publish, QoS, - TlsConfiguration, Transport, + read, AsyncClient, ConnectionError, Event, EventLoop, Incoming, MqttOptions, Packet, Publish, + QoS, Request, TlsConfiguration, Transport, }; use std::sync::Arc; @@ -25,6 +27,12 @@ pub enum Error { Serde(#[from] serde_json::Error), #[error("TrySend error {0}")] TrySend(Box>), + #[error("Io error {0}")] + Io(#[from] std::io::Error), + #[error("Mqtt error {0}")] + Mqtt(#[from] rumqttc::mqttbytes::Error), + #[error("Storage error {0}")] + Storage(#[from] storage::Error), } impl From> for Error { @@ -47,6 +55,9 @@ pub struct Mqtt { metrics: MqttMetrics, /// Metrics tx metrics_tx: Sender, + /// Control handles + ctrl_rx: Receiver, + ctrl_tx: Sender, } impl Mqtt { @@ -57,8 +68,9 @@ impl Mqtt { ) -> Mqtt { // create a new eventloop and reuse it during every reconnection let options = mqttoptions(&config); - let (client, mut eventloop) = AsyncClient::new(options, 10); + let (client, mut eventloop) = AsyncClient::new(options, 0); eventloop.network_options.set_connection_timeout(config.mqtt.network_timeout); + let (ctrl_tx, ctrl_rx) = bounded(1); Mqtt { config, @@ -67,6 +79,8 @@ impl Mqtt { native_actions_tx: actions_tx, metrics: MqttMetrics::new(), metrics_tx, + ctrl_tx, + ctrl_rx, } } @@ -75,65 +89,152 @@ impl Mqtt { self.client.clone() } + pub fn ctrl_tx(&self) -> CtrlTx { + CtrlTx { inner: self.ctrl_tx.clone() } + } + + /// Shutdown eventloop and write inflight publish packets to disk + pub fn persist_inflight(&mut self) -> Result<(), Error> { + self.eventloop.clean(); + let publishes: Vec<&Publish> = self + .eventloop + .pending + .iter() + .filter_map(|request| match request { + Request::Publish(publish) => Some(publish), + _ => None, + }) + .collect(); + + if publishes.is_empty() { + return Ok(()); + } + + let mut file = PersistenceFile::new(&self.config.persistence_path, "inflight".to_string())?; + let mut buf = BytesMut::new(); + + for publish in publishes { + publish.write(&mut buf)?; + } + + file.write(&mut buf)?; + debug!("Pending publishes written to disk: {}", file.path().display()); + + Ok(()) + } + + /// Checks for and loads data pending in persistence/inflight file + /// once done, deletes the file, while writing incoming data into storage. + fn reload_from_inflight_file(&mut self) -> Result<(), Error> { + // Read contents of inflight file into an in-memory buffer + let mut file = PersistenceFile::new(&self.config.persistence_path, "inflight".to_string())?; + let path = file.path(); + if !path.is_file() { + return Ok(()); + } + let mut buf = BytesMut::new(); + file.read(&mut buf)?; + + let max_packet_size = self.config.mqtt.max_packet_size; + loop { + // NOTE: This can fail when packet sizes > max_payload_size in config are written to disk. + match read(&mut buf, max_packet_size) { + Ok(Packet::Publish(publish)) => { + self.eventloop.pending.push_back(Request::Publish(publish)) + } + Ok(packet) => unreachable!("Unexpected packet: {:?}", packet), + Err(rumqttc::Error::InsufficientBytes(_)) => break, + Err(e) => { + error!("Error reading from file: {e}"); + break; + } + } + } + + info!("Pending publishes read from disk; removing file: {}", path.display()); + file.delete()?; + + Ok(()) + } + /// Poll eventloop to receive packets from broker pub async fn start(mut self) { + if let Err(e) = self.reload_from_inflight_file() { + error!("Error recovering data from inflight file: {e}"); + } + loop { - match self.eventloop.poll().await { - Ok(Event::Incoming(Incoming::ConnAck(connack))) => { - info!("Connected to broker. Session present = {}", connack.session_present); - let subscription = self.config.actions_subscription.clone(); - let client = self.client(); - - self.metrics.add_connection(); - - // This can potentially block when client from other threads - // have already filled the channel due to bad network. So we spawn - task::spawn(async move { - match client.subscribe(&subscription, QoS::AtLeastOnce).await { - Ok(..) => info!("Subscribe -> {:?}", subscription), - Err(e) => error!("Failed to send subscription. Error = {:?}", e), + select! { + event = self.eventloop.poll() => { + match event { + Ok(Event::Incoming(Incoming::ConnAck(connack))) => { + info!("Connected to broker. Session present = {}", connack.session_present); + let subscription = self.config.actions_subscription.clone(); + let client = self.client(); + + self.metrics.add_connection(); + + // This can potentially block when client from other threads + // have already filled the channel due to bad network. So we spawn + task::spawn(async move { + match client.subscribe(&subscription, QoS::AtLeastOnce).await { + Ok(..) => info!("Subscribe -> {:?}", subscription), + Err(e) => error!("Failed to send subscription. Error = {:?}", e), + } + }); } - }); - } - Ok(Event::Incoming(Incoming::Publish(p))) => { - self.metrics.add_action(); - if let Err(e) = self.handle_incoming_publish(p) { - error!("Incoming publish handle failed. Error = {:?}", e); - } - } - Ok(Event::Incoming(packet)) => { - debug!("Incoming = {:?}", packet); - match packet { - rumqttc::Packet::PubAck(_) => self.metrics.add_puback(), - rumqttc::Packet::PingResp => { - self.metrics.add_pingresp(); - let inflight = self.eventloop.state.inflight(); - self.metrics.update_inflight(inflight); - if let Err(e) = self.check_and_flush_metrics() { - error!("Failed to flush MQTT metrics. Erro = {:?}", e); + Ok(Event::Incoming(Incoming::Publish(p))) => { + self.metrics.add_action(); + if let Err(e) = self.handle_incoming_publish(p) { + error!("Incoming publish handle failed. Error = {:?}", e); } } - _ => {} - } - } - Ok(Event::Outgoing(packet)) => { - debug!("Outgoing = {:?}", packet); - match packet { - rumqttc::Outgoing::Publish(_) => self.metrics.add_publish(), - rumqttc::Outgoing::PingReq => { - self.metrics.add_pingreq(); + Ok(Event::Incoming(packet)) => { + debug!("Incoming = {:?}", packet); + match packet { + rumqttc::Packet::PubAck(_) => self.metrics.add_puback(), + rumqttc::Packet::PingResp => { + self.metrics.add_pingresp(); + let inflight = self.eventloop.state.inflight(); + self.metrics.update_inflight(inflight); + if let Err(e) = self.check_and_flush_metrics() { + error!("Failed to flush MQTT metrics. Erro = {:?}", e); + } + } + _ => {} + } + } + Ok(Event::Outgoing(packet)) => { + debug!("Outgoing = {:?}", packet); + match packet { + rumqttc::Outgoing::Publish(_) => self.metrics.add_publish(), + rumqttc::Outgoing::PingReq => { + self.metrics.add_pingreq(); + } + _ => {} + } + } + Err(e) => { + self.metrics.add_reconnection(); + self.check_disconnection_metrics(e); + tokio::time::sleep(Duration::from_secs(3)).await; + continue; } - _ => {} } - } - Err(e) => { - self.metrics.add_reconnection(); - self.check_disconnection_metrics(e); - tokio::time::sleep(Duration::from_secs(3)).await; - continue; + }, + Ok(MqttShutdown) = self.ctrl_rx.recv_async() => { + break; } } } + + // TODO: when uplink uses last-wills to handle unexpected disconnections, try to disconnect from + // mqtt connection, before force persisting in-flight publishes to disk. Timedout in a second. + // But otherwise sending a disconnect to broker is unnecessary. + + if let Err(e) = self.persist_inflight() { + error!("Couldn't persist inflight messages. Error = {:?}", e); + } } fn handle_incoming_publish(&mut self, publish: Publish) -> Result<(), Error> { @@ -216,3 +317,19 @@ fn _get_certs(key_path: &Path, ca_path: &Path) -> (Vec, Vec) { (key, ca) } + +/// Command to remotely trigger `Mqtt` shutdown +pub(crate) struct MqttShutdown; + +/// Handle to send control messages to `Mqtt` +#[derive(Debug, Clone)] +pub struct CtrlTx { + pub(crate) inner: Sender, +} + +impl CtrlTx { + /// Triggers shutdown of `Mqtt` + pub async fn trigger_shutdown(&self) { + self.inner.send_async(MqttShutdown).await.unwrap() + } +} diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index dc55de50..18145dc1 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -260,7 +260,7 @@ impl StorageHandler { /// │Serializer::slow(publish)◄───────────────────────────┤SlowEventloop(publish)│ /// └-------------------------┘ └──────────────────────┘ /// Write to storage, Slow network encountered -/// but continue trying to publish +/// but continue trying to publish /// ///``` /// @@ -538,8 +538,8 @@ impl Serializer { &mut self.metrics, &self.storage_handler, ); - let v = v?; - Ok(v) + + v } async fn normal(&mut self) -> Result { diff --git a/uplink/src/lib.rs b/uplink/src/lib.rs index ae88dec2..d16da57b 100644 --- a/uplink/src/lib.rs +++ b/uplink/src/lib.rs @@ -329,6 +329,7 @@ impl Uplink { let mut mqtt = Mqtt::new(self.config.clone(), self.action_tx.clone(), mqtt_metrics_tx); let mqtt_client = mqtt.client(); + let ctrl_mqtt = mqtt.ctrl_tx(); let serializer = Serializer::new( self.config.clone(), @@ -409,6 +410,7 @@ impl Uplink { Ok(CtrlTx { actions_lane: ctrl_actions_lane, data_lane: ctrl_data_lane, + mqtt: ctrl_mqtt, serializer: ctrl_serializer, }) } diff --git a/vd-lib b/vd-lib deleted file mode 160000 index cdaec8b6..00000000 --- a/vd-lib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cdaec8b6dacc3779e063e0ff1241a41a821b0cf2 From a8c5b6f21ec0ec3f46775750c166384efa44cc5b Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 9 Jan 2024 23:27:37 +0530 Subject: [PATCH 14/20] ci: compile system-stats with musl --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 72c42279..66d98178 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,12 +24,12 @@ jobs: - name: Build binary working-directory: tools/${{ matrix.build }} - run: cargo build --verbose --release + run: cargo build --verbose --release --target x86_64-unknown-linux-musl - name: Upload release archive uses: softprops/action-gh-release@v1 with: - files: tools/${{ matrix.build }}/target/release/${{ matrix.build }} + files: tools/${{ matrix.build }}/target/x86_64-unknown-linux-musl/release/${{ matrix.build }} build-release: name: Build release for ${{ matrix.target }} From 8f1e61d42904d37628c8bff27cb4f7616fd6b2f5 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Thu, 11 Jan 2024 10:54:29 +0530 Subject: [PATCH 15/20] refactor: avoid string concat with `+` refer: https://play.rust-lang.org/?gist=7a14d7b72cde6f9271edd074d4d7a54c --- uplink/src/base/bridge/stream.rs | 17 ++++------------- uplink/src/collector/process.rs | 2 +- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/uplink/src/base/bridge/stream.rs b/uplink/src/base/bridge/stream.rs index 17c099bb..e0aa1e37 100644 --- a/uplink/src/base/bridge/stream.rs +++ b/uplink/src/base/bridge/stream.rs @@ -63,13 +63,8 @@ where let project_id = project_id.into(); let device_id = device_id.into(); - let topic = String::from("/tenants/") - + &project_id - + "/devices/" - + &device_id - + "/events/" - + &stream_name - + "/jsonarray"; + let topic = + format!("/tenants/{project_id}/devices/{device_id}/events/{stream_name}/jsonarray"); let config = StreamConfig { topic, ..Default::default() }; Stream::new(stream_name, config, tx) @@ -207,11 +202,7 @@ impl Buffer { return; } - let error = self.stream_name.to_string() - + ".sequence: " - + &last.to_string() - + ", " - + ¤t.to_string(); + let error = format!("{}.sequence: {last}, {current}", self.stream_name); self.anomalies.push_str(&error) } @@ -221,7 +212,7 @@ impl Buffer { return; } - let error = "timestamp: ".to_owned() + &last.to_string() + ", " + ¤t.to_string(); + let error = format!("timestamp: {last}, {current}"); self.anomalies.push_str(&error) } diff --git a/uplink/src/collector/process.rs b/uplink/src/collector/process.rs index d2250bfd..f1aed754 100644 --- a/uplink/src/collector/process.rs +++ b/uplink/src/collector/process.rs @@ -82,7 +82,7 @@ impl ProcessHandler { pub async fn start(mut self) -> Result<(), Error> { loop { let action = self.actions_rx.recv_async().await?; - let command = String::from("tools/") + &action.name; + let command = format!("tools/{}", action.name); let deadline = match &action.deadline { Some(d) => *d, _ => { From fe7a9c2aec135109a271cd0f5278ffb8a746a02d Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Sun, 14 Jan 2024 10:43:23 +0530 Subject: [PATCH 16/20] feat: track stream-wise compression stats in serializer (#320) * feat: track compression stats in serializer * feat: Track serialization and compression times in nanos (#321) * feat: track serialization and compression times * feat: calculate average times * fix: don't panic * fix: serialize as seconds for more precision * log: calculate averages for times * style: use box to satisfy clippy --- uplink/src/base/mod.rs | 3 +- uplink/src/base/monitor/mod.rs | 37 ++++--- uplink/src/base/serializer/metrics.rs | 87 ++++++++++++++++- uplink/src/base/serializer/mod.rs | 134 +++++++++++++++++++------- uplink/src/lib.rs | 10 +- 5 files changed, 219 insertions(+), 52 deletions(-) diff --git a/uplink/src/base/mod.rs b/uplink/src/base/mod.rs index 527763a0..5508478c 100644 --- a/uplink/src/base/mod.rs +++ b/uplink/src/base/mod.rs @@ -173,7 +173,8 @@ pub struct InstallerConfig { #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct StreamMetricsConfig { pub enabled: bool, - pub topic: String, + pub bridge_topic: String, + pub serializer_topic: String, pub blacklist: Vec, #[serde_as(as = "DurationSeconds")] pub timeout: Duration, diff --git a/uplink/src/base/monitor/mod.rs b/uplink/src/base/monitor/mod.rs index 662402a9..d3bf7531 100644 --- a/uplink/src/base/monitor/mod.rs +++ b/uplink/src/base/monitor/mod.rs @@ -5,9 +5,9 @@ use flume::{Receiver, RecvError}; use rumqttc::{AsyncClient, ClientError, QoS, Request}; use tokio::select; -use crate::base::bridge::StreamMetrics; use crate::Config; +use super::bridge::StreamMetrics; use super::mqtt::MqttMetrics; use super::serializer::SerializerMetrics; @@ -38,8 +38,10 @@ impl Monitor { pub async fn start(&self) -> Result<(), Error> { let stream_metrics_config = self.config.stream_metrics.clone(); - let stream_metrics_topic = stream_metrics_config.topic; - let mut stream_metrics = Vec::with_capacity(10); + let bridge_stream_metrics_topic = stream_metrics_config.bridge_topic; + let mut bridge_stream_metrics = Vec::with_capacity(10); + let serializer_stream_metrics_topic = stream_metrics_config.serializer_topic; + let mut serializer_stream_metrics = Vec::with_capacity(10); let serializer_metrics_config = self.config.serializer_metrics.clone(); let serializer_metrics_topic = serializer_metrics_config.topic; @@ -58,18 +60,31 @@ impl Monitor { continue; } - stream_metrics.push(o); - let v = serde_json::to_string(&stream_metrics).unwrap(); + bridge_stream_metrics.push(o); + let v = serde_json::to_string(&bridge_stream_metrics).unwrap(); - stream_metrics.clear(); - self.client.publish(&stream_metrics_topic, QoS::AtLeastOnce, false, v).await.unwrap(); + bridge_stream_metrics.clear(); + self.client.publish(&bridge_stream_metrics_topic, QoS::AtLeastOnce, false, v).await.unwrap(); } o = self.serializer_metrics_rx.recv_async() => { let o = o?; - serializer_metrics.push(o); - let v = serde_json::to_string(&serializer_metrics).unwrap(); - serializer_metrics.clear(); - self.client.publish(&serializer_metrics_topic, QoS::AtLeastOnce, false, v).await.unwrap(); + match o { + SerializerMetrics::Main(o) => { + serializer_metrics.push(o); + let v = serde_json::to_string(&serializer_metrics).unwrap(); + serializer_metrics.clear(); + self.client.publish(&serializer_metrics_topic, QoS::AtLeastOnce, false, v).await.unwrap(); + } + SerializerMetrics::Stream(o) => { + if stream_metrics_config.blacklist.contains(&o.stream) { + continue; + } + serializer_stream_metrics.push(o); + let v = serde_json::to_string(&serializer_stream_metrics).unwrap(); + serializer_stream_metrics.clear(); + self.client.publish(&serializer_stream_metrics_topic, QoS::AtLeastOnce, false, v).await.unwrap(); + } + } } o = self.mqtt_metrics_rx.recv_async() => { let o = o?; diff --git a/uplink/src/base/serializer/metrics.rs b/uplink/src/base/serializer/metrics.rs index 68e1fc43..a0380230 100644 --- a/uplink/src/base/serializer/metrics.rs +++ b/uplink/src/base/serializer/metrics.rs @@ -1,10 +1,13 @@ +use std::time::Duration; + use serde::Serialize; +use serde_with::{serde_as, DurationSeconds}; use crate::base::clock; /// Metrics information relating to the operation of the `Serializer`, all values are reset on metrics flush #[derive(Debug, Serialize, Clone)] -pub struct SerializerMetrics { +pub struct Metrics { timestamp: u128, sequence: u32, /// One of **Catchup**, **Normal**, **Slow** or **Crash** @@ -27,9 +30,9 @@ pub struct SerializerMetrics { pub sent_size: usize, } -impl SerializerMetrics { +impl Metrics { pub fn new(mode: &str) -> Self { - SerializerMetrics { + Metrics { timestamp: clock(), sequence: 1, mode: mode.to_owned(), @@ -99,3 +102,81 @@ impl SerializerMetrics { self.errors = 0; } } + +#[serde_as] +#[derive(Debug, Serialize, Clone)] +pub struct StreamMetrics { + pub timestamp: u128, + pub sequence: u32, + pub stream: String, + pub serialized_data_size: usize, + pub compressed_data_size: usize, + #[serde(skip)] + pub serializations: u32, + #[serde_as(as = "DurationSeconds")] + pub total_serialization_time: Duration, + #[serde_as(as = "DurationSeconds")] + pub avg_serialization_time: Duration, + #[serde(skip)] + pub compressions: u32, + #[serde_as(as = "DurationSeconds")] + pub total_compression_time: Duration, + #[serde_as(as = "DurationSeconds")] + pub avg_compression_time: Duration, +} + +impl StreamMetrics { + pub fn new(name: &str) -> Self { + StreamMetrics { + stream: name.to_owned(), + timestamp: clock(), + sequence: 1, + serialized_data_size: 0, + compressed_data_size: 0, + serializations: 0, + total_serialization_time: Duration::ZERO, + avg_serialization_time: Duration::ZERO, + compressions: 0, + total_compression_time: Duration::ZERO, + avg_compression_time: Duration::ZERO, + } + } + + pub fn add_serialized_sizes(&mut self, data_size: usize, compressed_data_size: Option) { + self.serialized_data_size += data_size; + self.compressed_data_size += compressed_data_size.unwrap_or(data_size); + } + + pub fn add_serialization_time(&mut self, serialization_time: Duration) { + self.serializations += 1; + self.total_serialization_time += serialization_time; + } + + pub fn add_compression_time(&mut self, compression_time: Duration) { + self.compressions += 1; + self.total_compression_time += compression_time; + } + + // Should be called before serializing metrics to ensure averages are computed. + // Averages aren't calculated for ever `add_*` call to save on costs. + pub fn prepare_snapshot(&mut self) { + self.avg_serialization_time = self + .total_serialization_time + .checked_div(self.serializations) + .unwrap_or(Duration::ZERO); + self.avg_compression_time = + self.total_compression_time.checked_div(self.compressions).unwrap_or(Duration::ZERO); + } + + pub fn prepare_next(&mut self) { + self.timestamp = clock(); + self.sequence += 1; + self.serialized_data_size = 0; + self.compressed_data_size = 0; + } +} + +pub enum SerializerMetrics { + Main(Box), + Stream(Box), +} diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index 18145dc1..35ac7c8f 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -16,7 +16,7 @@ use tokio::{select, time::interval}; use crate::base::Compression; use crate::{Config, Package}; -pub use metrics::SerializerMetrics; +pub use metrics::{Metrics, SerializerMetrics, StreamMetrics}; use super::{default_file_size, StreamConfig}; @@ -171,10 +171,7 @@ impl StorageHandler { .or_insert_with(|| Storage::new(&stream.topic, default_file_size())) } - fn next( - &mut self, - metrics: &mut SerializerMetrics, - ) -> Option<(&Arc, &mut Storage)> { + fn next(&mut self, metrics: &mut Metrics) -> Option<(&Arc, &mut Storage)> { let storages = self.map.iter_mut(); for (stream, storage) in storages { @@ -274,9 +271,10 @@ pub struct Serializer { collector_rx: Receiver>, client: C, storage_handler: StorageHandler, - metrics: SerializerMetrics, + metrics: Metrics, metrics_tx: Sender, pending_metrics: VecDeque, + stream_metrics: HashMap, /// Control handles ctrl_rx: Receiver, ctrl_tx: Sender, @@ -299,7 +297,8 @@ impl Serializer { collector_rx, client, storage_handler, - metrics: SerializerMetrics::new("catchup"), + metrics: Metrics::new("catchup"), + stream_metrics: HashMap::new(), metrics_tx, pending_metrics: VecDeque::with_capacity(3), ctrl_tx, @@ -325,7 +324,7 @@ impl Serializer { return Ok(()); }; let stream_config = data.stream_config(); - let publish = construct_publish(data)?; + let publish = construct_publish(data, &mut self.stream_metrics)?; let storage = self.storage_handler.select(&stream_config); match write_to_disk(publish, storage) { Ok(Some(deleted)) => debug!("Lost segment = {deleted}"), @@ -352,7 +351,7 @@ impl Serializer { loop { // Collect next data packet and write to disk let data = self.collector_rx.recv_async().await?; - let publish = construct_publish(data)?; + let publish = construct_publish(data, &mut self.stream_metrics)?; let storage = self.storage_handler.select(&stream); match write_to_disk(publish, storage) { Ok(Some(deleted)) => debug!("Lost segment = {deleted}"), @@ -381,7 +380,7 @@ impl Serializer { data = self.collector_rx.recv_async() => { let data = data?; let stream = data.stream_config(); - let publish = construct_publish(data)?; + let publish = construct_publish(data, &mut self.stream_metrics)?; let storage = self.storage_handler.select(&stream); match write_to_disk(publish, storage) { Ok(Some(deleted)) => { @@ -410,7 +409,7 @@ impl Serializer { } }, _ = interval.tick() => { - check_metrics(&mut self.metrics, &self.storage_handler); + check_metrics(&mut self.metrics, &mut self.stream_metrics, &self.storage_handler); } // Transition into crash mode when uplink is shutting down Ok(SerializerShutdown) = self.ctrl_rx.recv_async() => { @@ -422,6 +421,7 @@ impl Serializer { save_and_prepare_next_metrics( &mut self.pending_metrics, &mut self.metrics, + &mut self.stream_metrics, &self.storage_handler, ); let v = v?; @@ -458,6 +458,7 @@ impl Serializer { save_and_prepare_next_metrics( &mut self.pending_metrics, &mut self.metrics, + &mut self.stream_metrics, &self.storage_handler, ); return Ok(Status::Normal); @@ -474,7 +475,7 @@ impl Serializer { data = self.collector_rx.recv_async() => { let data = data?; let stream = data.stream_config(); - let publish = construct_publish(data)?; + let publish = construct_publish(data, &mut self.stream_metrics)?; let storage = self.storage_handler.select(&stream); match write_to_disk(publish, storage) { Ok(Some(deleted)) => { @@ -536,6 +537,7 @@ impl Serializer { save_and_prepare_next_metrics( &mut self.pending_metrics, &mut self.metrics, + &mut self.stream_metrics, &self.storage_handler, ); @@ -553,7 +555,7 @@ impl Serializer { data = self.collector_rx.recv_async() => { let data = data?; let stream = data.stream_config(); - let publish = construct_publish(data)?; + let publish = construct_publish(data, &mut self.stream_metrics)?; let payload_size = publish.payload.len(); debug!("publishing on {} with size = {}", publish.topic, payload_size); match self.client.try_publish(&stream.topic, QoS::AtLeastOnce, false, publish.payload) { @@ -601,7 +603,7 @@ impl Serializer { } self.shutdown()?; - + info!("Serializer has handled all pending packets, shutting down"); Ok(()) @@ -627,7 +629,10 @@ fn lz4_compress(payload: &mut Vec) -> Result<(), Error> { } // Constructs a [Publish] packet given a [Package] element. Updates stream metrics as necessary. -fn construct_publish(data: Box) -> Result { +fn construct_publish( + data: Box, + stream_metrics: &mut HashMap, +) -> Result { let stream_name = data.stream_name().as_ref().to_owned(); let stream_config = data.stream_config(); let point_count = data.len(); @@ -635,12 +640,30 @@ fn construct_publish(data: Box) -> Result { trace!("Data received on stream: {stream_name}; message count = {point_count}; batching latency = {batch_latency}"); let topic = stream_config.topic.clone(); + + let metrics = stream_metrics + .entry(stream_name.clone()) + .or_insert_with(|| StreamMetrics::new(&stream_name)); + + let serialization_start = Instant::now(); let mut payload = data.serialize()?; + let serialization_time = serialization_start.elapsed(); + metrics.add_serialization_time(serialization_time); + + let data_size = payload.len(); + let mut compressed_data_size = None; if let Compression::Lz4 = stream_config.compression { + let compression_start = Instant::now(); lz4_compress(&mut payload)?; + let compression_time = compression_start.elapsed(); + metrics.add_compression_time(compression_time); + + compressed_data_size = Some(payload.len()); } + metrics.add_serialized_sizes(data_size, compressed_data_size); + Ok(Publish::new(topic, QoS::AtLeastOnce, payload)) } @@ -661,7 +684,11 @@ fn write_to_disk( Ok(deleted) } -fn check_metrics(metrics: &mut SerializerMetrics, storage_handler: &StorageHandler) { +fn check_metrics( + metrics: &mut Metrics, + stream_metrics: &mut HashMap, + storage_handler: &StorageHandler, +) { use pretty_bytes::converter::convert; let mut inmemory_write_size = 0; let mut inmemory_read_size = 0; @@ -691,11 +718,24 @@ fn check_metrics(metrics: &mut SerializerMetrics, storage_handler: &StorageHandl convert(metrics.write_memory as f64), convert(metrics.read_memory as f64), ); + + for metrics in stream_metrics.values_mut() { + metrics.prepare_snapshot(); + info!( + "{:>17}: serialized_data_size = {} compressed_data_size = {} avg_serialization_time = {}us avg_compression_time = {}us", + metrics.stream, + convert(metrics.serialized_data_size as f64), + convert(metrics.compressed_data_size as f64), + metrics.avg_serialization_time.as_micros(), + metrics.avg_compression_time.as_micros() + ); + } } fn save_and_prepare_next_metrics( pending: &mut VecDeque, - metrics: &mut SerializerMetrics, + metrics: &mut Metrics, + stream_metrics: &mut HashMap, storage_handler: &StorageHandler, ) { let mut inmemory_write_size = 0; @@ -715,15 +755,22 @@ fn save_and_prepare_next_metrics( metrics.set_disk_files(file_count); metrics.set_disk_utilized(disk_utilized); - let m = metrics.clone(); - pending.push_back(m); + let m = Box::new(metrics.clone()); + pending.push_back(SerializerMetrics::Main(m)); metrics.prepare_next(); + + for metrics in stream_metrics.values_mut() { + metrics.prepare_snapshot(); + let m = Box::new(metrics.clone()); + pending.push_back(SerializerMetrics::Stream(m)); + metrics.prepare_next(); + } } // // Enable actual metrics timers when there is data. This method is called every minute by the bridge fn check_and_flush_metrics( pending: &mut VecDeque, - metrics: &mut SerializerMetrics, + metrics: &mut Metrics, metrics_tx: &Sender, storage_handler: &StorageHandler, ) -> Result<(), flume::TrySendError> { @@ -748,20 +795,37 @@ fn check_and_flush_metrics( // Send pending metrics. This signifies state change while let Some(metrics) = pending.get(0) { - // Always send pending metrics. They represent state changes - info!( - "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} disk_utilized = {} write_memory = {} read_memory = {}", - metrics.mode, - metrics.batches, - metrics.errors, - metrics.lost_segments, - metrics.disk_files, - convert(metrics.disk_utilized as f64), - convert(metrics.write_memory as f64), - convert(metrics.read_memory as f64), - ); - metrics_tx.try_send(metrics.clone())?; - pending.pop_front(); + match metrics { + SerializerMetrics::Main(metrics) => { + // Always send pending metrics. They represent state changes + info!( + "{:>17}: batches = {:<3} errors = {} lost = {} disk_files = {:<3} disk_utilized = {} write_memory = {} read_memory = {}", + metrics.mode, + metrics.batches, + metrics.errors, + metrics.lost_segments, + metrics.disk_files, + convert(metrics.disk_utilized as f64), + convert(metrics.write_memory as f64), + convert(metrics.read_memory as f64), + ); + metrics_tx.try_send(SerializerMetrics::Main(metrics.clone()))?; + pending.pop_front(); + } + SerializerMetrics::Stream(metrics) => { + // Always send pending metrics. They represent state changes + info!( + "{:>17}: serialized_data_size = {} compressed_data_size = {} avg_serialization_time = {}us avg_compression_time = {}us", + metrics.stream, + convert(metrics.serialized_data_size as f64), + convert(metrics.compressed_data_size as f64), + metrics.avg_serialization_time.as_micros(), + metrics.avg_compression_time.as_micros() + ); + metrics_tx.try_send(SerializerMetrics::Stream(metrics.clone()))?; + pending.pop_front(); + } + } } if metrics.batches() > 0 { @@ -777,7 +841,7 @@ fn check_and_flush_metrics( convert(metrics.read_memory as f64), ); - metrics_tx.try_send(metrics.clone())?; + metrics_tx.try_send(SerializerMetrics::Main(Box::new(metrics.clone())))?; metrics.prepare_next(); } diff --git a/uplink/src/lib.rs b/uplink/src/lib.rs index d16da57b..f87cbe76 100644 --- a/uplink/src/lib.rs +++ b/uplink/src/lib.rs @@ -112,7 +112,8 @@ pub mod config { [stream_metrics] enabled = false - topic = "/tenants/{tenant_id}/devices/{device_id}/events/uplink_stream_metrics/jsonarray" + bridge_topic = "/tenants/{tenant_id}/devices/{device_id}/events/uplink_stream_metrics/jsonarray" + serializer_topic = "/tenants/{tenant_id}/devices/{device_id}/events/uplink_serializer_stream_metrics/jsonarray" blacklist = [] timeout = 10 @@ -172,7 +173,12 @@ pub mod config { } replace_topic_placeholders(&mut config.action_status.topic, tenant_id, device_id); - replace_topic_placeholders(&mut config.stream_metrics.topic, tenant_id, device_id); + replace_topic_placeholders(&mut config.stream_metrics.bridge_topic, tenant_id, device_id); + replace_topic_placeholders( + &mut config.stream_metrics.serializer_topic, + tenant_id, + device_id, + ); replace_topic_placeholders(&mut config.serializer_metrics.topic, tenant_id, device_id); replace_topic_placeholders(&mut config.mqtt_metrics.topic, tenant_id, device_id); From 3ce9b037c19b04a30545c66bdfdfb48aa30da8f5 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 23 Jan 2024 15:50:07 +0530 Subject: [PATCH 17/20] feat: preferential ordering of streams during read from disk (#289) * feat: preferential ordering of streams * test: remove incomplete test * test: reorganize for testing priority --- configs/config.toml | 9 +- uplink/src/base/mod.rs | 26 ++-- uplink/src/base/serializer/mod.rs | 200 ++++++++++++++++++++++++++---- uplink/src/lib.rs | 1 + vd-lib | 1 + 5 files changed, 205 insertions(+), 32 deletions(-) create mode 160000 vd-lib diff --git a/configs/config.toml b/configs/config.toml index f3c81e9f..6df7206a 100644 --- a/configs/config.toml +++ b/configs/config.toml @@ -75,19 +75,23 @@ blacklist = ["cancollector_metrics", "candump_metrics", "pinger"] # should perform on the data transiting through the stream. Currently supported # compression schemes are Lz4 and Disabled. Defaults to Disabled. # - persistence(optional): helps persist relevant information for data recovery purposes, -# used when there is a network/system failure. +# used when there is a network/system failure. +# - priority(optional, u8): Higher prioirity streams get to push their data +# onto the network first. # # In the following config for the device_shadow stream we set buf_size to 1 and mark # it as non-persistent. streams are internally constructed as a map of Name -> Config [streams.device_shadow] topic = "/tenants/{tenant_id}/devices/{device_id}/events/device_shadow/jsonarray" flush_period = 5 +priority = 75 # Example using compression [streams.imu] topic = "/tenants/{tenant_id}/devices/{device_id}/events/imu/jsonarray/lz4" buf_size = 100 compression = "Lz4" +priority = 50 # Configuration details associated with uplink's persistent storage module which writes publish # packets to disk in case of slow or crashed network, for recovery purposes. @@ -121,9 +125,12 @@ persistence = { max_file_count = 3 } # # NOTE: Action statuses are expected on a specifc topic as configured in example below. # This also means that we require a topic to be configured or uplink will error out. +# Given the importance of conveying action status at the earliest to platform, +# it has highest priority by default of 255. [action_status] topic = "/tenants/{tenant_id}/devices/{device_id}/action/status" flush_period = 2 +priority = 255 # Configurations for uplink's built-in file downloader, including the actions that can trigger # a download, the location in file system where uplink will download and store files from the diff --git a/uplink/src/base/mod.rs b/uplink/src/base/mod.rs index 5508478c..73b9422f 100644 --- a/uplink/src/base/mod.rs +++ b/uplink/src/base/mod.rs @@ -1,5 +1,5 @@ +use std::cmp::Ordering; use std::env::current_dir; -use std::hash::Hash; use std::path::PathBuf; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::{collections::HashMap, fmt::Debug}; @@ -64,7 +64,7 @@ pub fn clock() -> u128 { SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() } -#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Deserialize, Serialize, Default, PartialEq, Eq, PartialOrd)] pub enum Compression { #[default] Disabled, @@ -72,7 +72,7 @@ pub enum Compression { } #[serde_as] -#[derive(Debug, Clone, Deserialize, Eq)] +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] pub struct StreamConfig { pub topic: String, #[serde(default = "max_buf_size")] @@ -86,6 +86,8 @@ pub struct StreamConfig { pub compression: Compression, #[serde(default)] pub persistence: Persistence, + #[serde(default)] + pub priority: u8, } impl Default for StreamConfig { @@ -96,23 +98,27 @@ impl Default for StreamConfig { flush_period: default_timeout(), compression: Compression::Disabled, persistence: Persistence::default(), + priority: 0, } } } -impl Hash for StreamConfig { - fn hash(&self, state: &mut H) { - self.topic.hash(state) +impl Ord for StreamConfig { + fn cmp(&self, other: &Self) -> Ordering { + match (self.priority.cmp(&other.priority), self.topic.cmp(&other.topic)) { + (Ordering::Equal, o) => o, + (o, _) => o.reverse(), + } } } -impl PartialEq for StreamConfig { - fn eq(&self, other: &Self) -> bool { - self.topic == other.topic +impl PartialOrd for StreamConfig { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) } } -#[derive(Debug, Clone, Deserialize, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd)] pub struct Persistence { #[serde(default = "default_file_size")] pub max_file_size: usize, diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index 35ac7c8f..0866294a 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -1,6 +1,6 @@ mod metrics; -use std::collections::{HashMap, VecDeque}; +use std::collections::{BTreeMap, HashMap, VecDeque}; use std::io::{self, Write}; use std::time::Instant; use std::{sync::Arc, time::Duration}; @@ -134,14 +134,14 @@ impl MqttClient for AsyncClient { } struct StorageHandler { - map: HashMap, Storage>, + map: BTreeMap, Storage>, // Stream being read from read_stream: Option>, } impl StorageHandler { fn new(config: Arc) -> Result { - let mut map = HashMap::with_capacity(2 * config.streams.len()); + let mut map = BTreeMap::new(); for (stream_name, stream_config) in config.streams.iter() { let mut storage = Storage::new(&stream_config.topic, stream_config.persistence.max_file_size); @@ -870,6 +870,7 @@ impl CtrlTx { #[cfg(test)] mod test { use serde_json::Value; + use tokio::spawn; use std::collections::HashMap; use std::time::Duration; @@ -971,23 +972,17 @@ mod test { } impl MockCollector { - fn new(data_tx: flume::Sender>) -> MockCollector { - MockCollector { - stream: Stream::new( - "hello", - StreamConfig { - topic: "hello/world".to_string(), - buf_size: 1, - ..Default::default() - }, - data_tx, - ), - } + fn new( + stream_name: &str, + stream_config: StreamConfig, + data_tx: flume::Sender>, + ) -> MockCollector { + MockCollector { stream: Stream::new(stream_name, stream_config, data_tx) } } fn send(&mut self, i: u32) -> Result<(), Error> { let payload = Payload { - stream: "hello".to_owned(), + stream: Default::default(), sequence: i, timestamp: 0, payload: serde_json::from_str("{\"msg\": \"Hello, World!\"}")?, @@ -1010,7 +1005,11 @@ mod test { net_rx.recv().unwrap(); }); - let mut collector = MockCollector::new(data_tx); + let (stream_name, stream_config) = ( + "hello", + StreamConfig { topic: "hello/world".to_string(), buf_size: 1, ..Default::default() }, + ); + let mut collector = MockCollector::new(stream_name, stream_config, data_tx); std::thread::spawn(move || { for i in 1..3 { collector.send(i).unwrap(); @@ -1064,7 +1063,11 @@ mod test { net_rx.recv().unwrap(); }); - let mut collector = MockCollector::new(data_tx); + let (stream_name, stream_config) = ( + "hello", + StreamConfig { topic: "hello/world".to_string(), buf_size: 1, ..Default::default() }, + ); + let mut collector = MockCollector::new(stream_name, stream_config, data_tx); // Faster collector, send data every 5s std::thread::spawn(move || { for i in 1..10 { @@ -1092,7 +1095,11 @@ mod test { let config = Arc::new(default_config()); let (mut serializer, data_tx, _) = defaults(config); - let mut collector = MockCollector::new(data_tx); + let (stream_name, stream_config) = ( + "hello", + StreamConfig { topic: "hello/world".to_string(), buf_size: 1, ..Default::default() }, + ); + let mut collector = MockCollector::new(stream_name, stream_config, data_tx); // Faster collector, send data every 5s std::thread::spawn(move || { for i in 1..10 { @@ -1149,7 +1156,11 @@ mod test { .entry(Arc::new(Default::default())) .or_insert(Storage::new("hello/world", 1024)); - let mut collector = MockCollector::new(data_tx); + let (stream_name, stream_config) = ( + "hello", + StreamConfig { topic: "hello/world".to_string(), buf_size: 1, ..Default::default() }, + ); + let mut collector = MockCollector::new(stream_name, stream_config, data_tx); // Run a collector practically once std::thread::spawn(move || { for i in 2..6 { @@ -1204,7 +1215,11 @@ mod test { })) .or_insert(Storage::new("hello/world", 1024)); - let mut collector = MockCollector::new(data_tx); + let (stream_name, stream_config) = ( + "hello", + StreamConfig { topic: "hello/world".to_string(), buf_size: 1, ..Default::default() }, + ); + let mut collector = MockCollector::new(stream_name, stream_config, data_tx); // Run a collector std::thread::spawn(move || { for i in 2..6 { @@ -1230,4 +1245,147 @@ mod test { s => unreachable!("Unexpected status: {:?}", s), } } + + #[tokio::test] + // Ensures that the data of streams are removed on the basis of preference + async fn preferential_send_on_network() { + let mut config = default_config(); + config.stream_metrics.timeout = Duration::from_secs(1000); + config.streams.extend([ + ( + "one".to_owned(), + StreamConfig { topic: "topic/one".to_string(), priority: 1, ..Default::default() }, + ), + ( + "two".to_owned(), + StreamConfig { topic: "topic/two".to_string(), priority: 2, ..Default::default() }, + ), + ( + "top".to_owned(), + StreamConfig { + topic: "topic/top".to_string(), + priority: u8::MAX, + ..Default::default() + }, + ), + ]); + let config = Arc::new(config); + + let (mut serializer, _data_tx, req_rx) = defaults(config.clone()); + + let publish = |topic: String, i: u32| Publish { + dup: false, + qos: QoS::AtMostOnce, + retain: false, + topic, + pkid: 0, + payload: Bytes::from(i.to_string()), + }; + + let mut one = serializer + .storage_handler + .map + .entry(Arc::new(StreamConfig { + topic: "topic/one".to_string(), + priority: 1, + ..Default::default() + })) + .or_insert_with(|| unreachable!()); + write_to_disk(publish("topic/one".to_string(), 1), &mut one).unwrap(); + write_to_disk(publish("topic/one".to_string(), 10), &mut one).unwrap(); + + let top = serializer + .storage_handler + .map + .entry(Arc::new(StreamConfig { + topic: "topic/top".to_string(), + priority: u8::MAX, + ..Default::default() + })) + .or_insert_with(|| unreachable!()); + write_to_disk(publish("topic/top".to_string(), 100), top).unwrap(); + write_to_disk(publish("topic/top".to_string(), 1000), top).unwrap(); + + let two = serializer + .storage_handler + .map + .entry(Arc::new(StreamConfig { + topic: "topic/two".to_string(), + priority: 2, + ..Default::default() + })) + .or_insert_with(|| unreachable!()); + write_to_disk(publish("topic/two".to_string(), 3), two).unwrap(); + + let mut default = serializer + .storage_handler + .map + .entry(Arc::new(StreamConfig { + topic: "topic/default".to_string(), + priority: 0, + ..Default::default() + })) + .or_insert(Storage::new("topic/default", 1024)); + write_to_disk(publish("topic/default".to_string(), 0), &mut default).unwrap(); + write_to_disk(publish("topic/default".to_string(), 2), &mut default).unwrap(); + + // run serializer in the background + spawn(async { serializer.start().await.unwrap() }); + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/top"); + assert_eq!(payload, "100"); + } + _ => unreachable!(), + } + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/top"); + assert_eq!(payload, "1000"); + } + _ => unreachable!(), + } + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/two"); + assert_eq!(payload, "3"); + } + _ => unreachable!(), + } + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/one"); + assert_eq!(payload, "1"); + } + _ => unreachable!(), + } + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/one"); + assert_eq!(payload, "10"); + } + _ => unreachable!(), + } + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/default"); + assert_eq!(payload, "0"); + } + _ => unreachable!(), + } + + match req_rx.recv_async().await.unwrap() { + Request::Publish(Publish { topic, payload, .. }) => { + assert_eq!(topic, "topic/default"); + assert_eq!(payload, "2"); + } + _ => unreachable!(), + } + } } diff --git a/uplink/src/lib.rs b/uplink/src/lib.rs index f87cbe76..a72727a8 100644 --- a/uplink/src/lib.rs +++ b/uplink/src/lib.rs @@ -130,6 +130,7 @@ pub mod config { topic = "/tenants/{tenant_id}/devices/{device_id}/action/status" buf_size = 1 flush_period = 2 + priority = 255 # highest priority for quick delivery of action status info to platform [streams.device_shadow] topic = "/tenants/{tenant_id}/devices/{device_id}/events/device_shadow/jsonarray" diff --git a/vd-lib b/vd-lib new file mode 160000 index 00000000..1e71aa44 --- /dev/null +++ b/vd-lib @@ -0,0 +1 @@ +Subproject commit 1e71aa442b0e9c9deb6aba46bff1e535e93cebf7 From c17b8c3a7c3ffcbf574ca7a5f3769510441ba2d2 Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 23 Jan 2024 21:22:26 +0530 Subject: [PATCH 18/20] chore: cleanup and version update --- Cargo.lock | 2 +- uplink/Cargo.toml | 2 +- vd-lib | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 160000 vd-lib diff --git a/Cargo.lock b/Cargo.lock index 40dab31e..6090b33c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3176,7 +3176,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "uplink" -version = "2.9.0" +version = "2.10.0" dependencies = [ "anyhow", "async-trait", diff --git a/uplink/Cargo.toml b/uplink/Cargo.toml index 40168d91..7b6fa99e 100644 --- a/uplink/Cargo.toml +++ b/uplink/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "uplink" -version = "2.9.0" +version = "2.10.0" authors = ["tekjar "] edition = "2021" diff --git a/vd-lib b/vd-lib deleted file mode 160000 index 1e71aa44..00000000 --- a/vd-lib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1e71aa442b0e9c9deb6aba46bff1e535e93cebf7 From c23eab687ed247d210fea3fdb39f4b0d02a7488a Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Mon, 29 Jan 2024 23:20:21 +0530 Subject: [PATCH 19/20] ci: clippy suggestion --- tools/utils/src/push_to_uplink.rs | 2 +- uplink/src/base/serializer/mod.rs | 2 +- uplink/src/collector/systemstats.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/utils/src/push_to_uplink.rs b/tools/utils/src/push_to_uplink.rs index 4d292286..4e882de7 100644 --- a/tools/utils/src/push_to_uplink.rs +++ b/tools/utils/src/push_to_uplink.rs @@ -17,7 +17,7 @@ async fn main() { fn argv_to_payload(pairs: &[String]) -> Value { // nlici - let stream = pairs.get(0).unwrap(); + let stream = pairs.first().unwrap(); let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64; let kv_count = pairs.len() - 1; assert_eq!(kv_count % 2, 0); diff --git a/uplink/src/base/serializer/mod.rs b/uplink/src/base/serializer/mod.rs index 0866294a..5ed189df 100644 --- a/uplink/src/base/serializer/mod.rs +++ b/uplink/src/base/serializer/mod.rs @@ -794,7 +794,7 @@ fn check_and_flush_metrics( metrics.set_disk_utilized(disk_utilized); // Send pending metrics. This signifies state change - while let Some(metrics) = pending.get(0) { + while let Some(metrics) = pending.front() { match metrics { SerializerMetrics::Main(metrics) => { // Always send pending metrics. They represent state changes diff --git a/uplink/src/collector/systemstats.rs b/uplink/src/collector/systemstats.rs index cf40fb56..d795515d 100644 --- a/uplink/src/collector/systemstats.rs +++ b/uplink/src/collector/systemstats.rs @@ -613,7 +613,7 @@ impl StatCollector { self.sys.refresh_processes(); let timestamp = clock() as u64; for (&id, p) in self.sys.processes() { - let name = p.cmd().get(0).map(|s| s.to_string()).unwrap_or(p.name().to_string()); + let name = p.cmd().first().map(|s| s.to_string()).unwrap_or(p.name().to_string()); if self.config.system_stats.process_names.contains(&name) { let payload = self.processes.push(id.as_u32(), p, name, timestamp); From f601a9bf5baf8cd71fba74b48767afbac45571ed Mon Sep 17 00:00:00 2001 From: Devdutt Shenoi Date: Tue, 6 Feb 2024 22:08:32 +0530 Subject: [PATCH 20/20] refactor: action registration (#325) * refactor: action registration * refactor: make it readable, rm `mut` --- uplink/src/base/bridge/mod.rs | 21 +++++++++++---------- uplink/src/lib.rs | 21 +++++++-------------- uplink/src/main.rs | 28 ++++++++++++---------------- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/uplink/src/base/bridge/mod.rs b/uplink/src/base/bridge/mod.rs index d6e261e9..9f3a2a91 100644 --- a/uplink/src/base/bridge/mod.rs +++ b/uplink/src/base/bridge/mod.rs @@ -1,4 +1,4 @@ -use flume::{Receiver, Sender}; +use flume::{bounded, Receiver, Sender}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -101,20 +101,21 @@ impl Bridge { (self.actions.ctrl_tx(), self.data.ctrl_tx()) } - pub fn register_action_route( - &mut self, - route: ActionRoute, - actions_tx: Sender, - ) -> Result<(), Error> { - self.actions.register_action_route(route, actions_tx) + pub fn register_action_route(&mut self, route: ActionRoute) -> Result, Error> { + let (actions_tx, actions_rx) = bounded(1); + self.actions.register_action_route(route, actions_tx)?; + + Ok(actions_rx) } pub fn register_action_routes, V: IntoIterator>( &mut self, routes: V, - actions_tx: Sender, - ) -> Result<(), Error> { - self.actions.register_action_routes(routes, actions_tx) + ) -> Result, Error> { + let (actions_tx, actions_rx) = bounded(1); + self.actions.register_action_routes(routes, actions_tx)?; + + Ok(actions_rx) } } diff --git a/uplink/src/lib.rs b/uplink/src/lib.rs index a72727a8..6bfff3f5 100644 --- a/uplink/src/lib.rs +++ b/uplink/src/lib.rs @@ -427,14 +427,12 @@ impl Uplink { let route = ActionRoute { name: "launch_shell".to_owned(), timeout: Duration::from_secs(10) }; - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_route(route, actions_tx)?; + let actions_rx = bridge.register_action_route(route)?; let tunshell_client = TunshellClient::new(actions_rx, bridge_tx.clone()); spawn_named_thread("Tunshell Client", move || tunshell_client.start()); if !self.config.downloader.actions.is_empty() { - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_routes(&self.config.downloader.actions, actions_tx)?; + let actions_rx = bridge.register_action_routes(&self.config.downloader.actions)?; let file_downloader = FileDownloader::new(self.config.clone(), actions_rx, bridge_tx.clone())?; spawn_named_thread("File Downloader", || file_downloader.start()); @@ -444,8 +442,7 @@ impl Uplink { spawn_named_thread("Device Shadow Generator", move || device_shadow.start()); if !self.config.ota_installer.actions.is_empty() { - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_routes(&self.config.ota_installer.actions, actions_tx)?; + let actions_rx = bridge.register_action_routes(&self.config.ota_installer.actions)?; let ota_installer = OTAInstaller::new(self.config.ota_installer.clone(), actions_rx, bridge_tx.clone()); spawn_named_thread("OTA Installer", move || ota_installer.start()); @@ -457,8 +454,7 @@ impl Uplink { name: "journalctl_config".to_string(), timeout: Duration::from_secs(10), }; - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_route(route, actions_tx)?; + let actions_rx = bridge.register_action_route(route)?; let logger = JournalCtl::new(config, actions_rx, bridge_tx.clone()); spawn_named_thread("Logger", || { if let Err(e) = logger.start() { @@ -473,8 +469,7 @@ impl Uplink { name: "journalctl_config".to_string(), timeout: Duration::from_secs(10), }; - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_route(route, actions_tx)?; + let actions_rx = bridge.register_action_route(route)?; let logger = Logcat::new(config, actions_rx, bridge_tx.clone()); spawn_named_thread("Logger", || { if let Err(e) = logger.start() { @@ -489,8 +484,7 @@ impl Uplink { }; if !self.config.processes.is_empty() { - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_routes(&self.config.processes, actions_tx)?; + let actions_rx = bridge.register_action_routes(&self.config.processes)?; let process_handler = ProcessHandler::new(actions_rx, bridge_tx.clone()); spawn_named_thread("Process Handler", || { if let Err(e) = process_handler.start() { @@ -500,8 +494,7 @@ impl Uplink { } if !self.config.script_runner.is_empty() { - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_routes(&self.config.script_runner, actions_tx)?; + let actions_rx = bridge.register_action_routes(&self.config.script_runner)?; let script_runner = ScriptRunner::new(actions_rx, bridge_tx); spawn_named_thread("Script Runner", || { if let Err(e) = script_runner.start() { diff --git a/uplink/src/main.rs b/uplink/src/main.rs index 4b42ae21..e06aff13 100644 --- a/uplink/src/main.rs +++ b/uplink/src/main.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use std::time::Duration; use anyhow::Error; -use flume::bounded; use log::info; use structopt::StructOpt; use tokio::time::sleep; @@ -131,25 +130,22 @@ fn main() -> Result<(), Error> { let mut tcpapps = vec![]; for (app, cfg) in config.tcpapps.clone() { - let mut route_rx = None; - if !cfg.actions.is_empty() { - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_routes(&cfg.actions, actions_tx)?; - route_rx = Some(actions_rx) - } + let route_rx = if !cfg.actions.is_empty() { + let actions_rx = bridge.register_action_routes(&cfg.actions)?; + Some(actions_rx) + } else { + None + }; tcpapps.push(TcpJson::new(app, cfg, route_rx, bridge.bridge_tx())); } - let simulator_actions = config.simulator.as_ref().and_then(|cfg| { - let mut route_rx = None; - if !cfg.actions.is_empty() { - let (actions_tx, actions_rx) = bounded(1); - bridge.register_action_routes(&cfg.actions, actions_tx).unwrap(); - route_rx = Some(actions_rx) + let simulator_actions = match &config.simulator { + Some(cfg) if !cfg.actions.is_empty() => { + let actions_rx = bridge.register_action_routes(&cfg.actions)?; + Some(actions_rx) } - - route_rx - }); + _ => None, + }; let ctrl_tx = uplink.spawn(bridge)?;