diff --git a/Cargo.lock b/Cargo.lock index 63f8203..34e7f78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ checksum = "f728064aca1c318585bf4bb04ffcfac9e75e508ab4e8b1bd9ba5dfe04e2cbed5" dependencies = [ "actix-rt", "actix_derive", - "bitflags", + "bitflags 1.3.2", "bytes", "crossbeam-channel", "futures-core", @@ -32,7 +32,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytes", "futures-core", "futures-sink", @@ -55,7 +55,7 @@ dependencies = [ "actix-utils", "ahash 0.8.3", "base64 0.21.1", - "bitflags", + "bitflags 1.3.2", "brotli", "bytes", "bytestring", @@ -374,6 +374,28 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + [[package]] name = "async-trait" version = "0.1.68" @@ -402,6 +424,51 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde 1.0.163", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "base64" version = "0.13.1" @@ -429,6 +496,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.10.4" @@ -530,7 +603,7 @@ checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" dependencies = [ "anstream", "anstyle", - "bitflags", + "bitflags 1.3.2", "clap_lex", "strsim", ] @@ -720,6 +793,7 @@ dependencies = [ "actix-web-codegen-const-routes", "actix-web-httpauth", "anyhow", + "async-stream", "async-trait", "base64 0.13.1", "byteorder", @@ -733,10 +807,14 @@ dependencies = [ "maplit", "openraft", "pretty_env_logger 0.4.0", + "prost", "reqwest", "serde 1.0.163", "serde_json", "tokio", + "tokio-stream", + "tonic", + "tonic-build", "tracing", "tracing-subscriber", "url", @@ -828,6 +906,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + [[package]] name = "encoding_rs" version = "0.8.32" @@ -864,24 +948,19 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -893,6 +972,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.26" @@ -1055,7 +1140,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -1068,6 +1153,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "heck" version = "0.4.1" @@ -1098,6 +1189,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" version = "0.2.9" @@ -1171,6 +1271,18 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1207,7 +1319,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", ] [[package]] @@ -1244,10 +1366,19 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix", + "rustix 0.37.19", "windows-sys 0.48.0", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.6" @@ -1291,7 +1422,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec", - "bitflags", + "bitflags 1.3.2", "cfg-if", "ryu", "static_assertions", @@ -1299,9 +1430,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libmcaptcha" @@ -1335,6 +1466,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "local-channel" version = "0.1.3" @@ -1387,6 +1524,12 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "mcaptcha_pow_sha256" version = "0.4.0" @@ -1433,6 +1576,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + [[package]] name = "native-tls" version = "0.2.11" @@ -1603,7 +1752,7 @@ version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1682,6 +1831,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + [[package]] name = "pin-project" version = "1.1.0" @@ -1746,6 +1905,16 @@ dependencies = [ "log", ] +[[package]] +name = "prettyplease" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282" +dependencies = [ + "proc-macro2", + "syn 2.0.16", +] + [[package]] name = "proc-macro2" version = "1.0.58" @@ -1755,6 +1924,60 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck", + "itertools", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.16", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1844,7 +2067,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1853,7 +2076,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1946,14 +2169,33 @@ version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", "windows-sys 0.48.0", ] +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.13" @@ -1990,7 +2232,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2179,6 +2421,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "tempfile" version = "3.5.0" @@ -2188,7 +2436,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.19", "windows-sys 0.45.0", ] @@ -2292,6 +2540,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-macros" version = "2.1.0" @@ -2324,6 +2582,17 @@ dependencies = [ "tokio", ] +[[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.8" @@ -2347,6 +2616,72 @@ dependencies = [ "serde 1.0.163", ] +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.1", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2602,6 +2937,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.28", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2666,6 +3013,15 @@ dependencies = [ "windows-targets 0.48.0", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -2696,6 +3052,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -2708,6 +3079,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -2720,6 +3097,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -2732,6 +3115,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -2744,6 +3133,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -2756,6 +3151,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -2768,6 +3169,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -2780,6 +3187,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[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.10.1" diff --git a/Cargo.toml b/Cargo.toml index 9206b7d..033f0b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "dcache" version = "0.1.0" edition = "2021" +build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -32,10 +33,15 @@ reqwest = { version = "0.11.9", features = ["json"] } tokio = { version = "1.0", default-features = false, features = ["sync"] } tracing-subscriber = { version = "0.3.0", features = ["env-filter"] } actix = "0.13.0" +tonic = { version = "0.10.2", features = ["transport", "channel"] } +prost = "0.12.3" +tokio-stream = "0.1.14" +async-stream = "0.3.5" [build-dependencies] serde_json = "1" +tonic-build = "0.10.2" [dev-dependencies] actix-rt = "2.7.0" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..bec50d6 --- /dev/null +++ b/build.rs @@ -0,0 +1,10 @@ +fn main() -> Result<(), Box> { + // tonic_build::configure() + // .out_dir("protoout") + // .compile( + // &["proto/dcache/dcache.proto"], + // &["proto/dcache"], + // )?; + tonic_build::compile_protos("proto/dcache/dcache.proto")?; + Ok(()) +} diff --git a/check.sh b/check.sh new file mode 100755 index 0000000..758cf64 --- /dev/null +++ b/check.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +protoc \ +--proto_path=${PWD}/proto \ +--proto_path=${PWD}/bufbuild \ +--go_out=${PWD} \ +--go-grpc_out=${PWD} \ +--validate_out="lang=rust:${PWD}" \ +${PWD}/proto/dcache/dcache.proto diff --git a/proto/dcache/dcache.proto b/proto/dcache/dcache.proto new file mode 100644 index 0000000..e5ddde8 --- /dev/null +++ b/proto/dcache/dcache.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; + +package dcache; + +//message GetRequest { string key = 1; } +// +//message GetReply { +// bool ok = 1; +// string value = 2; +//} + +message Level { + uint32 visitor_threshold = 301; + uint32 difficulty_factor= 302; +} + +message Defense { + repeated Level levels = 401; +} +message MCaptcha { + uint32 visitor_threshold = 501; + uint64 duration = 502; + Defense defense = 503; +} + +message AddCaptcha { + string id = 601; + MCaptcha mcaptcha = 602; +} + + +message RenameCaptcha { + string name = 701; + string rename_to = 702; +} + + +message CachePoW { + string string= 801; + uint32 difficulty_factor = 802; + uint64 duration = 803; + string key = 804; +} + +message CacheResult { + string token = 817; + string key = 818; + uint64 duration= 819; +} + +message DeleteCaptchaResult { + string token = 821; +} + + +message DcacheRequest { + oneof DcacheRequest { + string AddVisitor = 1; + AddCaptcha add_captcha = 2; + RenameCaptcha rename_captcha = 3; + string remove_captcha = 4; + CachePoW cache_pow = 5; + + + + + + + string delete_pow = 6; + CacheResult cache_result = 7; + DeleteCaptchaResult delete_captcha_result = 8; + } +} + +message AddVisitorResult { + uint64 duration = 901; + uint32 difficulty_factor = 902; +} + +message OptionAddVisitorResult { + optional AddVisitorResult result = 911; + +} + +message DcacheResponse { + oneof DcacheResponse { + OptionAddVisitorResult option_add_visitor_result = 1; + uint32 empty = 2; + } +} + +message RaftRequest { + string data = 1; +} + +message RaftReply { + string data = 1; + string error = 2; +} +// +//message HandshakeRequest { +// uint64 protocol_version = 1; +// bytes payload = 2; +//} +// +//message HandshakeResponse { +// uint64 protocol_version = 1; +// bytes payload = 2; +//} +message Learner { + uint64 id = 1; + string addr = 2; +} + +service DcacheService { + + rpc AddLearner(Learner) returns (RaftReply) {} + rpc Write(RaftRequest) returns (RaftReply) {} +// rpc Get(GetRequest) returns (GetReply) {} + + /// Forward a request to other + rpc Forward(RaftRequest) returns (RaftReply) {} + + // raft RPC + + rpc AppendEntries(RaftRequest) returns (RaftReply); + rpc InstallSnapshot(RaftRequest) returns (RaftReply); + rpc vote(RaftRequest) returns (RaftReply); +} + +//service Dcache { +// // handshake +// rpc Handshake(HandshakeRequest) returns (HandshakeResponse); +// +// // message +// rpc WriteMsg(RaftRequest) returns (RaftReply); +//// rpc ReadMsg(GetRequest) returns (GetReply); +//} diff --git a/src/lib.rs b/src/lib.rs index df65628..343cc4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,10 +38,13 @@ use crate::network::raft_network_impl::DcacheNetwork; use crate::store::DcacheRequest; use crate::store::DcacheResponse; use crate::store::DcacheStore; +use tonic::transport::Server; pub mod app; pub mod network; +mod server; pub mod store; +pub mod types; pub type DcacheNodeId = u64; @@ -120,18 +123,44 @@ pub async fn start_example_raft_node( .unwrap(); raft.enable_heartbeat(true); raft.enable_elect(true); + + let captcha = serde_json::json!({ + "AddCaptcha": { + "id": "test_1", + "mcaptcha": { + "visitor_threshold": 0, + "defense": { + "levels": [ + {"visitor_threshold": 50, "difficulty_factor": 500}, + {"visitor_threshold": 5000, "difficulty_factor": 50000}, + ], + "current_visitor_threshold": 0, + }, + "duration": 30, + }}}); + #[derive(serde::Serialize)] + struct X { + data: String, + } + let x = X { + data: serde_json::to_string(&captcha).unwrap(), + }; + println!("{}", serde_json::to_string(&x).unwrap()); + // raft.enable_tick(true); // Create an application that will store all the instances created above, this will // be later used on the actix-web services. - let app = Data::new(DcacheApp { + let app = DcacheApp { id: node_id, addr: http_addr.clone(), raft, store, config, network, - }); + }; + let app = Data::new(app); + let dcache_service = crate::server::MyDcacheImpl::new(app.clone()); if introducer_addr == http_addr { app.init().await.unwrap(); @@ -139,47 +168,68 @@ pub async fn start_example_raft_node( let app_copy = app.clone(); // Start the actix-web server. - let server = HttpServer::new(move || { - App::new() - .wrap(Logger::default()) - .wrap(Logger::new("%a %{User-Agent}i")) - .wrap(middleware::Compress::default()) - .app_data(app.clone()) - // raft internal RPC - .service(raft::append) - .service(raft::snapshot) - .service(raft::vote) - // admin API - .service(management::init) - .service(management::add_learner) - .service(management::change_membership) - .service(management::metrics) - // application API - .service(api::write) - .service(api::state) - .service(api::read) - .service(api::pipeline_read) - .service(api::pipeline_write) - // .service(api::consistent_read) - }); + // let server = HttpServer::new(move || { + // App::new() + // .wrap(Logger::default()) + // .wrap(Logger::new("%a %{User-Agent}i")) + // .wrap(middleware::Compress::default()) + // .app_data(app.clone()) + // // raft internal RPC + // .service(raft::append) + // .service(raft::snapshot) + // .service(raft::vote) + // // admin API + // .service(management::init) + // .service(management::add_learner) + // .service(management::change_membership) + // .service(management::metrics) + // // application API + // .service(api::write) + // .service(api::state) + // .service(api::read) + // .service(api::pipeline_read) + // .service(api::pipeline_write) + // // .service(api::consistent_read) + // }); + // + // let x = server.bind(&http_addr)?; - let x = server.bind(&http_addr)?; + // let server_fut = tokio::spawn(x.run()); + use crate::server::dcache::dcache_service_server::DcacheServiceServer; + let svc = DcacheServiceServer::new(dcache_service); + + let x = Server::builder() + .add_service(svc) + .serve(http_addr.clone().parse().unwrap()); + let server_fut = tokio::spawn(x); - let server_fut = tokio::spawn(x.run()); tokio::time::sleep(std::time::Duration::new(3, 0)).await; - let req: (DcacheNodeId, String) = (node_id, http_addr); - let c = reqwest::Client::new(); - c.post(format!("http://{}/add-learner", introducer_addr)) - .json(&req) - .send() + // let req: (DcacheNodeId, String) = (node_id, http_addr); + // let c = reqwest::Client::new(); + // c.post(format!("http://{}/add-learner", introducer_addr)) + // .json(&req) + // .send() + // .await + // .unwrap(); + // let health_job = tokio::spawn(DcacheApp::health_job(app_copy)); + + let url = format!("http://{}", introducer_addr); + use crate::server::dcache::dcache_service_client::DcacheServiceClient; + use crate::server::dcache::Learner; + use crate::server::dcache::RaftRequest; + let mut client = DcacheServiceClient::connect(url).await.unwrap(); + client + .add_learner(Learner { + id: node_id, + addr: http_addr, + }) .await .unwrap(); - // let health_job = tokio::spawn(DcacheApp::health_job(app_copy)); let health_metrics_handle = crate::network::management::HealthMetrics::spawn(app_copy, 5, manager_rx).await; - server_fut.await??; + server_fut.await?.unwrap(); health_metrics_handle.abort(); // health_job.abort(); Ok(()) diff --git a/src/network/raft_network_impl.rs b/src/network/raft_network_impl.rs index 7bc2c8d..fd480b8 100644 --- a/src/network/raft_network_impl.rs +++ b/src/network/raft_network_impl.rs @@ -43,17 +43,28 @@ use reqwest::Client; use serde::de::DeserializeOwned; use serde::Serialize; use tokio::sync::mpsc::Sender; +use tonic::transport::channel::Channel; use super::management::HealthStatus; +use super::raft::snapshot; use crate::DcacheNodeId; use crate::DcacheTypeConfig; +use crate::server::dcache::dcache_service_client::DcacheServiceClient; +use crate::server::dcache::{RaftReply, RaftRequest}; + #[derive(Clone)] pub struct DcacheNetwork { pub signal: Sender, pub client: Client, } +pub enum RPCType { + Vote, + Snapshot, + Append, +} + impl DcacheNetwork { pub fn new(signal: Sender, client: Client) -> Self { Self { signal, client } @@ -64,6 +75,7 @@ impl DcacheNetwork { target_node: &BasicNode, uri: &str, req: Req, + event: RPCType, ) -> Result> where Req: Serialize, @@ -72,34 +84,79 @@ impl DcacheNetwork { { let addr = &target_node.addr; - let url = format!("http://{}/{}", addr, uri); + //let url = format!("http://{}/{}", addr, uri); + let url = format!("http://{}", addr); - tracing::debug!("send_rpc to url: {}", url); + let mut client = DcacheServiceClient::connect(url).await.unwrap(); - let resp = match self.client.post(url).json(&req).send().await { - Ok(resp) => Ok(resp), + let res = match event { + RPCType::Vote => { + client + .vote(RaftRequest { + data: serde_json::to_string(&req).unwrap(), + }) + .await + } + + RPCType::Snapshot => { + client + .install_snapshot(RaftRequest { + data: serde_json::to_string(&req).unwrap(), + }) + .await + } + + RPCType::Append => { + client + .append_entries(RaftRequest { + data: serde_json::to_string(&req).unwrap(), + }) + .await + } + }; + + match res { + Ok(res) => { + let signal2 = self.signal.clone(); + let fut = async move { + let _ = signal2.send(HealthStatus::Healthy(target)).await; + }; + tokio::spawn(fut); + let res = res.into_inner(); + Ok(serde_json::from_str(&res.data).unwrap()) + } Err(e) => { - self.signal.send(HealthStatus::Down(target)).await; + let _ = self.signal.send(HealthStatus::Down(target)).await; Err(RPCError::Network(NetworkError::new(&e))) } - }?; - - tracing::debug!("client.post() is sent"); - - let res: Result = resp - .json() - .await - .map_err(|e| RPCError::Network(NetworkError::new(&e)))?; - - let res = res.map_err(|e| RPCError::RemoteError(RemoteError::new(target, e))); - if res.is_ok() { - let signal2 = self.signal.clone(); - let fut = async move { - let _ = signal2.send(HealthStatus::Healthy(target)).await; - }; - tokio::spawn(fut); } - res + + // tracing::debug!("send_rpc to url: {}", url); + // + // let resp = match self.client.post(url).json(&req).send().await { + // Ok(resp) => Ok(resp), + // Err(e) => { + // self.signal.send(HealthStatus::Down(target)).await; + // Err(RPCError::Network(NetworkError::new(&e))) + // } + // }?; + // + // tracing::debug!("client.post() is sent"); + // + // let res: Result = resp + // .json() + // .await + // .map_err(|e| RPCError::Network(NetworkError::new(&e)))?; + // + // let res = res.map_err(|e| RPCError::RemoteError(RemoteError::new(target, e))); + // if res.is_ok() { + // let signal2 = self.signal.clone(); + // let fut = async move { + // let _ = signal2.send(HealthStatus::Healthy(target)).await; + // }; + // tokio::spawn(fut); + // } + // res } } @@ -134,7 +191,13 @@ impl RaftNetwork for DcacheNetworkConnection { RPCError>, > { self.owner - .send_rpc(self.target, &self.target_node, "raft-append", req) + .send_rpc( + self.target, + &self.target_node, + "raft-append", + req, + RPCType::Append, + ) .await } @@ -146,7 +209,13 @@ impl RaftNetwork for DcacheNetworkConnection { RPCError>, > { self.owner - .send_rpc(self.target, &self.target_node, "raft-snapshot", req) + .send_rpc( + self.target, + &self.target_node, + "raft-snapshot", + req, + RPCType::Append, + ) .await } @@ -158,7 +227,13 @@ impl RaftNetwork for DcacheNetworkConnection { RPCError>, > { self.owner - .send_rpc(self.target, &self.target_node, "raft-vote", req) + .send_rpc( + self.target, + &self.target_node, + "raft-vote", + req, + RPCType::Vote, + ) .await } } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..f8b2d9d --- /dev/null +++ b/src/server.rs @@ -0,0 +1,88 @@ +use actix_web::web::Data; +use openraft::BasicNode; +use tokio_stream::StreamExt; +use tonic::{transport::Server, Request, Response, Status}; + +use dcache::dcache_service_server::DcacheService; +use dcache::{Learner, RaftReply, RaftRequest}; + +use crate::app::DcacheApp; + +pub mod dcache { + tonic::include_proto!("dcache"); // The string specified here must match the proto package name +} + +#[derive(Clone)] +pub struct MyDcacheImpl { + app: Data, +} + +impl MyDcacheImpl { + pub fn new(app: Data) -> Self { + Self { app } + } +} + +#[tonic::async_trait] +impl DcacheService for MyDcacheImpl { + async fn add_learner( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + //let req = request.into_inner(); + //let req = serde_json::from_str(&req.data).unwrap(); + //let res = self.app.raft.client_write(req).await; + //Ok(Response::new(res.into())) + let req = request.into_inner(); + let node_id = req.id; + let node = BasicNode { + addr: req.addr.clone(), + }; + let res = self.app.raft.add_learner(node_id, node, true).await; + Ok(Response::new(res.into())) + } + + async fn write( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + let req = request.into_inner(); + let req = serde_json::from_str(&req.data).unwrap(); + let res = self.app.raft.client_write(req).await; + Ok(Response::new(res.into())) + } + /// / Forward a request to other + async fn forward( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + unimplemented!(); + } + async fn append_entries( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + let req = request.into_inner(); + let req = serde_json::from_str(&req.data).unwrap(); + let res = self.app.raft.append_entries(req).await; + Ok(Response::new(res.into())) + } + async fn install_snapshot( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + let req = request.into_inner(); + let req = serde_json::from_str(&req.data).unwrap(); + let res = self.app.raft.install_snapshot(req).await; + Ok(Response::new(res.into())) + } + async fn vote( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + let req = request.into_inner(); + let req = serde_json::from_str(&req.data).unwrap(); + let res = self.app.raft.vote(req).await; + Ok(Response::new(res.into())) + } +} diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..68d6e0a --- /dev/null +++ b/src/types.rs @@ -0,0 +1,52 @@ +use std::sync::Arc; + +use openraft::raft::AppendEntriesRequest; +use openraft::raft::InstallSnapshotRequest; +use openraft::raft::VoteRequest; +use serde::de::DeserializeOwned; +use serde::Deserialize; +use serde::Serialize; + +use crate::server::dcache::{RaftReply, RaftRequest}; +use crate::DcacheNodeId; + +impl From for Result +where + T: DeserializeOwned, + E: DeserializeOwned, +{ + fn from(msg: RaftReply) -> Self { + if !msg.data.is_empty() { + let resp: T = serde_json::from_str(&msg.data).expect("fail to deserialize"); + Ok(resp) + } else { + let err: E = serde_json::from_str(&msg.error).expect("fail to deserialize"); + Err(err) + } + } +} + +impl From> for RaftReply +where + T: Serialize, + E: Serialize, +{ + fn from(r: Result) -> Self { + match r { + Ok(x) => { + let data = serde_json::to_string(&x).expect("fail to serialize"); + RaftReply { + data, + error: Default::default(), + } + } + Err(e) => { + let error = serde_json::to_string(&e).expect("fail to serialize"); + RaftReply { + data: Default::default(), + error, + } + } + } + } +}