diff --git a/Cargo.lock b/Cargo.lock index ecf988bd4a3..bcaa901c5df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,982 +4,1317 @@ name = "adler32" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" [[package]] name = "aho-corasick" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4", ] [[package]] name = "arc-swap" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" + +[[package]] +name = "arc-swap" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" + +[[package]] +name = "arrayref" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" [[package]] name = "arrayvec" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", ] +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" + [[package]] name = "arrow" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "398bc55d60097e7b7e9be67d1cb03cb41e5bf4901381607ba0fca8b1328584d6" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "libc", + "serde_json", ] [[package]] name = "async-speed-limit" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8960ff0e84c4330f6d3d882fad4a3d292cdb1729b1acbc1c22dab0af0f77e6f1" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-io", + "futures-timer", + "pin-project-lite", ] [[package]] name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "termion", + "winapi 0.3.4", ] [[package]] name = "autocfg" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" dependencies = [ - "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys", + "cfg-if", + "dbghelp-sys", + "kernel32-sys", + "libc", + "rustc-demangle", + "winapi 0.2.8", ] [[package]] name = "backtrace" version = "0.3.38" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" dependencies = [ - "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", ] [[package]] name = "backtrace-sys" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", ] [[package]] name = "base64" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "621fc7ecb8008f86d7fb9b95356cd692ce9514b80a86d85b397f32a22da7b9e2" +dependencies = [ + "byteorder 1.2.7", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "batch-system" +version = "0.1.0" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.0", + "crossbeam 0.7.1", + "derive_more 0.15.0", + "slog", + "slog-global", + "tikv_util", ] [[package]] name = "bindgen" version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cexpr", + "cfg-if", + "clang-sys", + "clap", + "env_logger", + "lazy_static 1.4.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "which 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "peeking_take_while", + "proc-macro2 1.0.6", + "quote 1.0.2", + "regex", + "rustc-hash", + "shlex", + "which 3.0.0", ] [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "blake2b_simd" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" +dependencies = [ + "arrayref", + "arrayvec 0.5.1", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder 1.2.7", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] [[package]] name = "bstr" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0", + "memchr", + "regex-automata", + "serde", ] [[package]] name = "build_const" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ca3a1755927e5b00c3fe43250053b957b5c074d9f17782b88ef7aa0fb4dfe2" [[package]] name = "byteorder" version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" [[package]] name = "bytes" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "either", + "iovec", ] [[package]] name = "bzip2-sys" version = "0.1.7" -source = "git+https://github.com/alexcrichton/bzip2-rs.git#96cc4909a1a180a62ca8e3716785dc6f7a7f9ac0" +source = "git+https://github.com/alexcrichton/bzip2-rs.git#a8ee5cb4d0587409d03b4367bbfa8d7d6266378e" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", ] [[package]] name = "c2-chacha" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", ] [[package]] name = "callgrind" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7f788eaf239475a3c1e1acf89951255a46c4b9b46cf3e866fc4d0707b4b9e36" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "valgrind_request 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "valgrind_request", ] [[package]] name = "cast" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" [[package]] name = "cc" version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" dependencies = [ - "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver", + "num_cpus", ] [[package]] name = "cexpr" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 4.2.3", ] [[package]] name = "cfg-if" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" [[package]] name = "chashmap" version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff41a3c2c1e39921b9003de14bf0439c7b63a9039637c291e1a64925d8ddfa45" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref", + "parking_lot 0.4.8", ] [[package]] name = "chrono" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits 0.2.5", + "serde", + "time", ] [[package]] name = "chrono-tz" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e430fad0384e4defc3dc6b1223d1b886087a8bf9b7080e5ae027f73851ea15" dependencies = [ - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parse-zoneinfo 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "parse-zoneinfo", ] [[package]] name = "clang-sys" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" dependencies = [ - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "glob", + "libc", + "libloading", ] [[package]] name = "clap" version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term", + "atty", + "bitflags", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", + "yaml-rust", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "cmake" version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", ] [[package]] name = "codec" version = "0.0.1" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "panic_hook 0.0.1", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", + "byteorder 1.2.7", + "bytes", + "failure", + "libc", + "panic_hook", + "protobuf", + "rand 0.6.5", + "static_assertions 0.3.1", + "tikv_alloc", ] +[[package]] +name = "constant_time_eq" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" + [[package]] name = "cookie" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626" dependencies = [ - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time", + "url 1.7.2", ] [[package]] name = "cop_codegen" version = "0.0.1" dependencies = [ - "darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "darling", + "heck", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.15.33", ] [[package]] name = "cop_datatype" version = "0.0.1" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "enum-primitive-derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", - "tipb 0.0.1 (git+https://github.com/pingcap/tipb.git?branch=release-3.1)", + "bitflags", + "enum-primitive-derive", + "failure", + "num-traits 0.2.5", + "tikv_alloc", + "tipb", +] + +[[package]] +name = "core-foundation" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +dependencies = [ + "core-foundation-sys", + "libc", ] +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + [[package]] name = "cpuprofiler" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f07976bb6821459632d7a18d97ccca005cb5c552f251f822c7c1781c1d7035" dependencies = [ - "error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain", + "lazy_static 0.2.8", ] [[package]] name = "crc" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" dependencies = [ - "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "build_const", ] [[package]] name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "crc64fast" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a82510de0a7cadd51dc68ff17da70aea0c80157f902230f9b157cecc2566318" [[package]] name = "criterion" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot 0.3.1", + "csv", + "itertools 0.8.2", + "lazy_static 1.4.0", + "libc", + "num-traits 0.2.5", + "rand_core 0.3.1", + "rand_os 0.1.3", + "rand_xoshiro 0.1.0", + "rayon", + "rayon-core", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] name = "criterion" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "cast", + "clap", + "criterion-plot 0.4.0", + "csv", + "itertools 0.8.2", + "lazy_static 1.4.0", + "num-traits 0.2.5", + "rand_core 0.5.1", + "rand_os 0.2.2", + "rand_xoshiro 0.3.1", + "rayon", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] name = "criterion-papi" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402c80822a64e66751efaca958ac1047a301c9455dce110c8ef1e9b8ecb931" dependencies = [ - "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "libpapi_sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.0", + "libc", + "libpapi_sys", ] [[package]] name = "criterion-plot" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "cast", + "itertools 0.8.2", ] [[package]] name = "criterion-plot" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2" dependencies = [ - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cast", + "itertools 0.8.2", ] [[package]] name = "crossbeam" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c92ff2d7a202d592f5a412d75cf421495c913817781c1cb383bf12a77e185f" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "crossbeam-channel", + "crossbeam-deque 0.6.2", + "crossbeam-epoch 0.6.1", + "crossbeam-utils", + "lazy_static 1.4.0", + "num_cpus", + "parking_lot 0.6.4", ] [[package]] name = "crossbeam" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b14492071ca110999a20bf90e3833406d5d66bfd93b4e52ec9539025ff43fe0d" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "crossbeam-channel", + "crossbeam-deque 0.7.1", + "crossbeam-epoch 0.7.1", + "crossbeam-queue", + "crossbeam-utils", ] [[package]] name = "crossbeam-channel" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", ] [[package]] name = "crossbeam-deque" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe1b6f945f824c7a25afe44f62e25d714c0cc523f8e99d8db5cd1026e1269d3" dependencies = [ - "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.6.1", + "crossbeam-utils", ] [[package]] name = "crossbeam-deque" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.1", + "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.7", + "cfg-if", + "crossbeam-utils", + "lazy_static 1.4.0", + "memoffset", + "scopeguard", ] [[package]] name = "crossbeam-epoch" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.7", + "cfg-if", + "crossbeam-utils", + "lazy_static 1.4.0", + "memoffset", + "scopeguard", ] [[package]] name = "crossbeam-queue" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", ] [[package]] name = "crossbeam-utils" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "lazy_static 1.4.0", +] + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array", + "subtle", ] [[package]] name = "csv" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" dependencies = [ - "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr", + "csv-core", + "itoa", + "ryu 1.0.2", + "serde", ] [[package]] name = "csv-core" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "darling" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6" dependencies = [ - "darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c" dependencies = [ - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv", + "ident_case", + "proc-macro2 0.4.29", + "quote 0.6.10", + "strsim 0.7.0", + "syn 0.15.33", ] [[package]] name = "darling_macro" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1" dependencies = [ - "darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "darling_core", + "quote 0.6.10", + "syn 0.15.33", ] [[package]] name = "dbghelp-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "derive_more" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b" +dependencies = [ + "quote 0.5.2", + "rustc_version 0.2.2", + "syn 0.13.11", +] + +[[package]] +name = "derive_more" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" +dependencies = [ + "lazy_static 1.4.0", + "proc-macro2 0.4.29", + "quote 0.6.10", + "regex", + "rustc_version 0.2.2", + "syn 0.15.33", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" dependencies = [ - "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_users", + "winapi 0.3.4", ] [[package]] name = "either" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" [[package]] name = "engine" version = "0.0.1" dependencies = [ - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvproto 0.0.1 (git+https://github.com/pingcap/kvproto.git?branch=release-3.1)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.3.2", + "kvproto", + "lazy_static 1.4.0", "prometheus 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "raft 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rocksdb 0.3.0 (git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-global 0.1.0 (git+https://github.com/breeswish/slog-global.git?rev=91904ade)", - "sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", - "tikv_util 0.1.0", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", + "quick-error 1.2.2", + "raft", + "rocksdb", + "serde", + "serde_derive", + "slog", + "slog-global", + "sys-info", + "tempdir", + "tikv_alloc", + "tikv_util", + "time", + "toml", ] [[package]] name = "enum-primitive-derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd" dependencies = [ - "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.32", + "quote 0.3.15", + "syn 0.11.11", ] [[package]] name = "env_logger" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "humantime", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex", + "termcolor", ] [[package]] name = "error-chain" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143" dependencies = [ - "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.2.3", ] [[package]] name = "external_storage" version = "0.0.1" dependencies = [ - "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvproto 0.0.1 (git+https://github.com/pingcap/kvproto.git?branch=release-3.1)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-global 0.1.0 (git+https://github.com/breeswish/slog-global.git?rev=91904ade)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "futures 0.1.29", + "futures 0.3.1", + "futures-executor", + "futures-io", + "futures-util", + "kvproto", + "rand 0.7.2", + "rusoto_core", + "rusoto_credential", + "rusoto_mock", + "rusoto_s3", + "rust-ini", + "slog", + "slog-global", + "tempfile", + "tikv_alloc", + "tokio", + "url 2.1.0", ] [[package]] name = "fail" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2e1a22c616c8c8c96b6e07c243014551f3ba77291d24c22e0bfea6830c0b4e" dependencies = [ - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14", ] [[package]] name = "fail" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63eec71a3013ee912a0ecb339ff0c5fa5ed9660df04bfefa10c250b885d018c" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5", ] [[package]] name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" dependencies = [ - "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38", + "failure_derive", ] [[package]] name = "failure_derive" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.15.33", + "synstructure", ] +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + [[package]] name = "farmhash" version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f35ce9c8fb9891c75ceadbc330752951a4e369b50af10775955aeb9af3eee34b" [[package]] name = "fixedbitset" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" [[package]] name = "flate2" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96971e4fc2737f211ec8236fe16ac67695838ca3e25567c07b4f837d1f8f829c" dependencies = [ - "flate2-crc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2-crc", + "libc", + "libz-sys", + "miniz_oxide_c_api", ] [[package]] name = "flate2-crc" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a792245eaed7747984647ce20582507985d69ccfacdddcb60bd5f451f21cbc5" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fs2" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237b7991317b8d94391c0a4813b1f74fd81c11352440cd598d2b763ed288bfc1" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "libc", + "winapi 0.2.8", ] [[package]] name = "fs_extra" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" + +[[package]] +name = "futures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" +dependencies = [ + "futures-core", + "futures-sink", +] [[package]] name = "futures-core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" [[package]] name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "num_cpus", ] [[package]] name = "futures-executor" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-task", + "futures-util", ] [[package]] name = "futures-io" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" + +[[package]] +name = "futures-macro" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" +dependencies = [ + "proc-macro-hack", + "proc-macro2 1.0.6", + "quote 1.0.2", + "syn 1.0.8", +] + +[[package]] +name = "futures-sink" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" [[package]] name = "futures-task" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" [[package]] name = "futures-timer" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" [[package]] name = "futures-util" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", + "tokio-io", ] [[package]] name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", ] [[package]] name = "gcc" version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] [[package]] name = "getrandom" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", ] [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "grpcio" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac757a85603e4f8c40a9f94be06a5ad412acab80b39b4e8895ca931b6619910" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "grpcio-sys", + "libc", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", ] [[package]] name = "grpcio-compiler" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373a14f0f994d4c235770f4bb5558be00626844db130a82a70142b8fc5996fc3" dependencies = [ - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", + "protobuf-codegen", ] [[package]] name = "grpcio-sys" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f22fb0327f153acccedbe91894dd0fb15bb6f202d8195665cd206af0402b0" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.52 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "cmake", + "libc", + "openssl-sys", + "pkg-config", ] [[package]] name = "h2" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac030ae20dee464c5d0f36544d8b914a6bc606da44a57e052d2b0f5dae129e0" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "bytes", + "fnv", + "futures 0.1.29", + "http", + "indexmap", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "slab", + "string", + "tokio-io", ] [[package]] name = "hashbrown" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b7d419d0622ae02fe5da6b9a5e1964b610a65bb37923b976aeebb6dbb8f86e" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "scopeguard", + "serde", ] [[package]] name = "heck" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" dependencies = [ - "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation", ] [[package]] name = "hex" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + +[[package]] +name = "hex" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" + +[[package]] +name = "hmac" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" +dependencies = [ + "crypto-mac", + "digest", +] [[package]] name = "hpack" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -988,207 +1323,248 @@ dependencies = [ name = "http" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "fnv", + "itoa", ] [[package]] name = "http-body" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "http", + "tokio-buf", ] [[package]] name = "httparse" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae" [[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2", ] [[package]] name = "hyper" version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9bf64f730d6ee4b0528a5f0a316363da9d8104318731509d4ccc86248f82b3" dependencies = [ - "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie", + "httparse", + "language-tags", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mime", + "num_cpus", + "rustc-serialize", + "solicit", + "time", + "traitobject", + "typeable", + "unicase", + "url 1.7.2", ] [[package]] name = "hyper" version = "0.12.35" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", - "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" +dependencies = [ + "bytes", + "futures 0.1.29", + "futures-cpupool", + "h2", + "http", + "http-body", + "httparse", + "iovec", + "itoa", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "net2", + "rustc_version 0.2.2", + "time", + "tokio", + "tokio-buf", + "tokio-executor", + "tokio-io", + "tokio-reactor", + "tokio-tcp", + "tokio-threadpool", + "tokio-timer", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" +dependencies = [ + "bytes", + "futures 0.1.29", + "hyper 0.12.35", + "native-tls", + "tokio-io", ] [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi 0.2.3", + "unicode-normalization", ] [[package]] name = "idna" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi 0.3.4", + "unicode-normalization", ] [[package]] name = "indexmap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "inferno" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "880c9746895893d66a6b0ecf49d46271e3a0f6763ebbb910cb0dd7c2097a61f3" dependencies = [ - "chashmap 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chashmap", + "crossbeam 0.7.1", + "env_logger", + "fnv", + "indexmap", + "itoa", + "lazy_static 1.4.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-format 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-xml 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)", - "str_stack 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-format", + "num_cpus", + "quick-xml", + "rgb", + "str_stack", + "structopt", ] [[package]] name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.2.8", ] [[package]] name = "isatty" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a118a53ba42790ef25c82bb481ecf36e2da892646cccd361e69a6bb881e19398" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "libc", + "redox_syscall", + "winapi 0.2.8", ] [[package]] name = "itertools" -version = "0.8.0" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" dependencies = [ - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" [[package]] name = "jemalloc-ctl" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e93b0f37e7d735c6b610176d5b1bde8e1621ff3f6f7ac23cdfa4e7f7d0111b5" dependencies = [ - "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "jemalloc-sys", + "libc", ] [[package]] name = "jemalloc-sys" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "fs_extra", + "libc", ] [[package]] name = "jemallocator" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" dependencies = [ - "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "jemalloc-sys", + "libc", ] [[package]] name = "jobserver" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" dependencies = [ - "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1196,134 +1572,142 @@ dependencies = [ name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "kvproto" version = "0.0.1" -source = "git+https://github.com/solotzg/kvproto.git?branch=learner-merge#e3bab7401a5d11d28bb98d4af1c3ee57d8929731" +source = "git+https://github.com/pingcap/kvproto.git?branch=release-3.1#7ccc45d0063f5d09766aa71225b4b1c6d1a3ac3b" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-build 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "raft 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "grpcio", + "hex 0.3.2", + "prost 0.4.0", + "prost-derive 0.4.0", + "protobuf", + "protobuf-build", + "raft", ] -[[package]] -name = "kvproto" -version = "0.0.1" -source = "git+https://github.com/pingcap/kvproto.git?branch=release-3.1#bb43ea8286627d00821d06f1be91f8fc698b4fd9" -replace = "kvproto 0.0.1 (git+https://github.com/solotzg/kvproto.git?branch=learner-merge)" - [[package]] name = "language-tags" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" [[package]] name = "lazy_static" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "lexical-core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "ryu 0.2.8", + "stackvector", + "static_assertions 0.2.5", ] [[package]] name = "libc" version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c" [[package]] name = "libloading" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "winapi 0.3.4", ] [[package]] name = "libpapi_sys" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c687368f5a574f3aaf97cad438fb572a87aa224051e1cd01ad926b1d592886b" dependencies = [ - "bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bindgen", + "num_cpus", ] [[package]] name = "librocksdb_sys" version = "0.1.0" -source = "git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x#e26d5bd6078f0c7196ad56e7f67cef1c09269892" +source = "git+https://github.com/tikv/rust-rocksdb.git?branch=tikv-3.x#7ec1dbd99d906c0098e60ccce41a2adae13fb411" dependencies = [ - "bzip2-sys 0.1.7 (git+https://github.com/alexcrichton/bzip2-rs.git)", - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "libtitan_sys 0.0.1 (git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x)", - "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lz4-sys 1.8.3 (git+https://github.com/busyjay/lz4-rs.git?branch=adjust-build)", - "snappy-sys 0.1.0 (git+https://github.com/busyjay/rust-snappy.git?branch=static-link)", - "zstd-sys 1.4.15+zstd.1.4.4 (git+https://github.com/gyscos/zstd-rs.git)", + "bzip2-sys", + "cc", + "cmake", + "jemalloc-sys", + "libc", + "libtitan_sys", + "libz-sys", + "lz4-sys", + "snappy-sys", + "zstd-sys", ] [[package]] name = "libtitan_sys" version = "0.0.1" -source = "git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x#e26d5bd6078f0c7196ad56e7f67cef1c09269892" +source = "git+https://github.com/tikv/rust-rocksdb.git?branch=tikv-3.x#7ec1dbd99d906c0098e60ccce41a2adae13fb411" dependencies = [ - "bzip2-sys 0.1.7 (git+https://github.com/alexcrichton/bzip2-rs.git)", - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lz4-sys 1.8.3 (git+https://github.com/busyjay/lz4-rs.git?branch=adjust-build)", - "snappy-sys 0.1.0 (git+https://github.com/busyjay/rust-snappy.git?branch=static-link)", - "zstd-sys 1.4.15+zstd.1.4.4 (git+https://github.com/gyscos/zstd-rs.git)", + "bzip2-sys", + "cc", + "cmake", + "libc", + "libz-sys", + "lz4-sys", + "snappy-sys", + "zstd-sys", ] [[package]] name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] name = "lock_api" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref", + "scopeguard", ] [[package]] @@ -1338,6 +1722,7 @@ dependencies = [ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" replace = "log 0.3.9 (git+https://github.com/busyjay/log?branch=use-static-module)" [[package]] @@ -1345,24 +1730,25 @@ name = "log" version = "0.4.6" source = "git+https://github.com/busyjay/log?branch=revert-to-static#20502c573a4941d58a77d30c013ffbcf616686ac" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "log" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" replace = "log 0.4.6 (git+https://github.com/busyjay/log?branch=revert-to-static)" [[package]] name = "log_wrappers" version = "0.0.1" dependencies = [ - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvproto 0.0.1 (git+https://github.com/pingcap/kvproto.git?branch=release-3.1)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", + "hex 0.3.2", + "kvproto", + "slog", + "slog-term", + "tikv_alloc", ] [[package]] @@ -1370,55 +1756,67 @@ name = "lz4-sys" version = "1.8.3" source = "git+https://github.com/busyjay/lz4-rs.git?branch=adjust-build#5a8afe4010c67899fc7af876a58d67fd6269bf81" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", ] [[package]] name = "match_template" version = "0.0.1" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.15.33", ] [[package]] name = "matches" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e" [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "memmap" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "winapi 0.3.4", ] [[package]] name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" [[package]] name = "mime" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c93a4bd787ddc6e7833c519b73a50883deb5863d76d9b71eb8216fb7f94e66" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1427,267 +1825,357 @@ dependencies = [ name = "miniz_oxide" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32", ] [[package]] name = "miniz_oxide_c_api" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "crc", + "libc", + "miniz_oxide", ] [[package]] name = "mio" version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "lazycell", + "libc", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-named-pipes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio", + "miow 0.3.3", + "winapi 0.3.4", ] [[package]] name = "mio-uds" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" dependencies = [ - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec", + "libc", + "mio", ] [[package]] name = "miow" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "miow" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" +dependencies = [ + "socket2", + "winapi 0.3.4", ] [[package]] name = "more-asserts" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf21d96e87e5d48e3b50ab1512142f2fbe06fc48b7b032dead87fbfcb83f9a89" [[package]] name = "multimap" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" + +[[package]] +name = "multimap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" +dependencies = [ + "serde", +] [[package]] name = "murmur3" version = "0.4.0" source = "git+https://github.com/pingcap/murmur3.git#4af9e1a8f2d4206d90d81f11e513fb03c87208bf" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", +] + +[[package]] +name = "native-tls" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" +dependencies = [ + "lazy_static 1.4.0", + "libc", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "winapi 0.3.4", ] [[package]] name = "nix" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if", + "libc", + "void", ] [[package]] name = "nix" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "cfg-if", + "libc", + "void", ] [[package]] name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" [[package]] name = "nom" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" [[package]] name = "nom" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" [[package]] name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", + "version_check", ] [[package]] name = "nom" version = "5.0.0-beta1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6527f311b2baba609e980e008460ab5ebff6d6da15213bb8eb193b7746eefa24" dependencies = [ - "lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lexical-core", + "memchr", + "version_check", ] [[package]] name = "num" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" dependencies = [ - "num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits 0.2.5", ] [[package]] name = "num-complex" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", ] [[package]] name = "num-format" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.7", + "itoa", ] [[package]] name = "num-integer" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", ] [[package]] name = "num-iter" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits 0.2.5", ] [[package]] name = "num-rational" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits 0.2.5", ] [[package]] name = "num-traits" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51eab148f171aefad295f8cece636fc488b9b392ef544da31ea4b8ef6b9e9c39" [[package]] name = "num-traits" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" [[package]] name = "num_cpus" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "openssl" -version = "0.10.25" +version = "0.10.28" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.52 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cfg-if", + "foreign-types", + "lazy_static 1.4.0", + "libc", + "openssl-sys", ] +[[package]] +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" + [[package]] name = "openssl-src" version = "111.6.0+1.1.1d" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9c2da1de8a7a3f860919c01540b03a6db16de042405a8a07a5e9d0b4b825d9c" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", ] [[package]] name = "openssl-sys" -version = "0.9.52" +version = "0.9.54" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-src 111.6.0+1.1.1d (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", ] [[package]] name = "ordered-float" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", ] [[package]] name = "owning_ref" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" dependencies = [ - "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stable_deref_trait", ] [[package]] @@ -1698,159 +2186,195 @@ version = "0.0.1" name = "parking_lot" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref", + "parking_lot_core 0.2.14", ] [[package]] name = "parking_lot" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" dependencies = [ - "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api", + "parking_lot_core 0.3.1", ] [[package]] name = "parking_lot_core" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "rand 0.4.2", + "smallvec", + "winapi 0.3.4", ] [[package]] name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "rand 0.5.5", + "rustc_version 0.2.2", + "smallvec", + "winapi 0.3.4", ] [[package]] name = "parse-zoneinfo" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "089a398ccdcdd77b8c38909d5a1e4b67da1bc4c9dbfe6d5b536c828eddb779e5" dependencies = [ - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex", ] [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "petgraph" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" dependencies = [ - "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fixedbitset", ] [[package]] name = "pin-project-lite" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" [[package]] name = "pin-utils" version = "0.1.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" [[package]] name = "pkg-config" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" [[package]] name = "pprof" version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c794c3b7ab21a9954fde0cd48085deccf624f14cf3d9c137f35f1aa3a3ca5d60" dependencies = [ - "backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "inferno 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.38", + "bytes", + "inferno", + "lazy_static 1.4.0", + "libc", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memmap", + "nix 0.15.0", + "prost 0.5.0", + "prost-build", + "prost-derive 0.5.0", + "quick-error 1.2.2", + "rustc-demangle", + "spin 0.5.2", + "tempfile", ] [[package]] name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "proc-macro-error" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6", + "quote 1.0.2", + "syn 1.0.8", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" +dependencies = [ + "proc-macro2 1.0.6", + "quote 1.0.2", + "syn 1.0.8", +] + +[[package]] +name = "proc-macro-nested" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" + [[package]] name = "proc-macro2" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0", ] [[package]] name = "proc-macro2" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0", ] [[package]] name = "proc-macro2" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0", ] [[package]] name = "procinfo" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42e8578852a3306838981aedad8c5642ba794929aa12af0c9eb6c072b77af6c" dependencies = [ - "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.5.1", + "libc", + "nom 1.2.4", + "rustc_version 0.1.7", ] [[package]] @@ -1858,21 +2382,21 @@ name = "procinfo" version = "0.4.2" source = "git+https://github.com/tikv/procinfo-rs#ac3841d271fe2e4e865afdce60bb6a166044f7c7" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "libc", + "nom 2.2.1", + "rustc_version 0.2.2", ] [[package]] name = "profiler" version = "0.0.1" dependencies = [ - "callgrind 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", - "valgrind_request 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "callgrind", + "cpuprofiler", + "lazy_static 1.4.0", + "tikv_alloc", + "valgrind_request", ] [[package]] @@ -1880,653 +2404,942 @@ name = "prometheus" version = "0.4.2" source = "git+https://github.com/birdstorm/rust-prometheus?branch=0.4.2#5ffb2fc8c51648435efd15594ebc7dcafbc2cb85" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "procinfo 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "fnv", + "hyper 0.9.18", + "lazy_static 0.2.8", + "libc", + "procinfo 0.3.1", + "protobuf", + "quick-error 0.2.2", + "spin 0.4.9", ] [[package]] name = "prometheus" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760293453bee1de0a12987422d7c4885f7ee933e4417bb828ed23f7d05c3c390" replace = "prometheus 0.4.2 (git+https://github.com/birdstorm/rust-prometheus?branch=0.4.2)" [[package]] name = "prometheus-static-metric" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2b4a6a1ae793e7eb6773a5301a5a08e8929ea5517b677c93e57ce2d0973c02" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0", + "proc-macro2 0.3.8", + "quote 0.5.2", + "syn 0.13.11", +] + +[[package]] +name = "prost" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f36c478cd43382388dfc3a3679af175c03d19ed8039e79a3e4447e944cd3f3" +dependencies = [ + "byteorder 1.2.7", + "bytes", ] [[package]] name = "prost" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "bytes", + "prost-derive 0.5.0", ] [[package]] name = "prost-build" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "heck", + "itertools 0.8.2", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.4.0", + "petgraph", + "prost 0.5.0", + "prost-types", + "tempfile", + "which 2.0.1", +] + +[[package]] +name = "prost-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9787d1977ea72e8066d58e46ae66100324a2815e677897fe78dfe54958f48252" +dependencies = [ + "failure", + "itertools 0.7.11", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.14.9", ] [[package]] name = "prost-derive" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "failure", + "itertools 0.8.2", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.15.33", ] [[package]] name = "prost-types" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "prost 0.5.0", ] [[package]] name = "protobuf" version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc4570f22641ed8c65326d54832ce1536e9ddf0ccb7a8c836cbe780d7e23537" [[package]] name = "protobuf-build" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a94ea746889322eb33b6977db6ffe82b1decaac1804958b9179245fc45dc4b6" dependencies = [ - "grpcio-compiler 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "protoc-grpcio 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protoc-rust 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "grpcio-compiler", + "protoc-grpcio", + "protoc-rust", + "quote 0.6.10", + "regex", + "syn 0.15.33", ] [[package]] name = "protobuf-codegen" version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c12a571137dc99703cb46fa21f185834fc5578a65836573fcff127f7b53f41e1" dependencies = [ - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", ] [[package]] name = "protoc" version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1a649b870f7fe03c965bf2fa6728361f6abbb6f3b72079515af8cb56d769cf" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "protoc-grpcio" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9798b534614b71d780778b1508410826073b5a1ca111a090f1f3fd3ac663ef6" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio-compiler 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protoc 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure", + "grpcio-compiler", + "protobuf", + "protobuf-codegen", + "protoc", + "tempfile", ] [[package]] name = "protoc-rust" version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14565959d6394858759919e011675edc2e851c37cf1095fa7d313409368c1e63" dependencies = [ - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protoc 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", + "protobuf-codegen", + "protoc", + "tempdir", ] [[package]] name = "quick-error" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ac990ab4e038dd8481a5e3fd00641067fcfc674ad663f3222752ed5284e05d4" [[package]] name = "quick-error" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" [[package]] name = "quick-xml" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd45021132c1cb5540995e93fcc2cf5a874ef84f9639168fb6819caa023d4be" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" dependencies = [ - "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.8", ] [[package]] name = "quote" version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.29", ] [[package]] name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6", ] [[package]] name = "raft" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43648985159f2c4c25f934182a63b0dd4c5cc06a5ae96e5d40e12c3a3785abde" dependencies = [ - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "fxhash", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", + "quick-error 1.2.2", + "rand 0.5.5", ] [[package]] name = "rand" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "rand" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon", + "libc", + "winapi 0.3.4", ] [[package]] name = "rand" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi", + "fuchsia-zircon", + "libc", + "rand_core 0.2.2", + "winapi 0.3.4", ] [[package]] name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.6", + "libc", + "rand_chacha 0.1.0", + "rand_core 0.4.0", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os 0.1.3", + "rand_pcg", + "rand_xorshift", + "winapi 0.3.4", ] [[package]] name = "rand" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" dependencies = [ - "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha 0.2.1", + "rand_core 0.5.1", + "rand_hc 0.2.0", ] [[package]] name = "rand_chacha" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", + "rustc_version 0.2.2", ] [[package]] name = "rand_chacha" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha", + "rand_core 0.5.1", ] [[package]] name = "rand_core" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0", ] [[package]] name = "rand_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rand_isaac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_jitter" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "rand_core 0.4.0", + "winapi 0.3.4", ] [[package]] name = "rand_os" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.0", + "rdrand", + "winapi 0.3.4", ] [[package]] name = "rand_os" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a" dependencies = [ - "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "rand_core 0.5.1", ] [[package]] name = "rand_pcg" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", + "rustc_version 0.2.2", ] [[package]] name = "rand_xorshift" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_xoshiro" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "rand_core 0.3.1", ] [[package]] name = "rand_xoshiro" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e18c91676f670f6f0312764c759405f13afb98d5d73819840cf72a518487bff" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rayon" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" dependencies = [ - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1", + "either", + "rayon-core", ] [[package]] name = "rayon-core" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" dependencies = [ - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1", + "crossbeam-queue", + "crossbeam-utils", + "lazy_static 1.4.0", + "num_cpus", ] [[package]] name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "redox_syscall" -version = "0.1.27" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" dependencies = [ - "redox_syscall 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall", +] + +[[package]] +name = "redox_users" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" +dependencies = [ + "failure", + "rand_os 0.1.3", + "redox_syscall", + "rust-argon2", ] [[package]] name = "regex" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" dependencies = [ - "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", + "utf8-ranges", ] [[package]] name = "regex-automata" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", ] [[package]] name = "regex-syntax" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" dependencies = [ - "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ucd-util", ] [[package]] name = "remove_dir_all" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4", ] [[package]] name = "rgb" version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb" [[package]] name = "rocksdb" version = "0.3.0" -source = "git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x#e26d5bd6078f0c7196ad56e7f67cef1c09269892" +source = "git+https://github.com/tikv/rust-rocksdb.git?branch=tikv-3.x#7ec1dbd99d906c0098e60ccce41a2adae13fb411" +dependencies = [ + "crc", + "libc", + "librocksdb_sys", +] + +[[package]] +name = "rusoto_core" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d1ecfe8dac29878a713fbc4c36b0a84a48f7a6883541841cdff9fdd2ba7dfb" +dependencies = [ + "base64 0.11.0", + "bytes", + "futures 0.1.29", + "http", + "hyper 0.12.35", + "hyper-tls", + "lazy_static 1.4.0", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rusoto_credential", + "rusoto_signature", + "rustc_version 0.2.2", + "serde", + "serde_derive", + "serde_json", + "time", + "tokio", + "tokio-timer", + "xml-rs", +] + +[[package]] +name = "rusoto_credential" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8632e41d289db90dd40d0389c71a23c5489e3afd448424226529113102e2a002" dependencies = [ - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "librocksdb_sys 0.1.0 (git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x)", + "chrono", + "dirs", + "futures 0.1.29", + "hyper 0.12.35", + "lazy_static 1.4.0", + "regex", + "serde", + "serde_derive", + "serde_json", + "shlex", + "tokio-process", + "tokio-timer", +] + +[[package]] +name = "rusoto_mock" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c2c0c4ad473d33c7469e04d1ef316ea8ae399232a1b72ef2e6a89a97bf880e" +dependencies = [ + "chrono", + "futures 0.1.29", + "http", + "rusoto_core", + "serde", + "serde_json", +] + +[[package]] +name = "rusoto_s3" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fedcadf3d73c2925b05d547b66787f2219c5e727a98c893fff5cf2197dbd678" +dependencies = [ + "bytes", + "futures 0.1.29", + "rusoto_core", + "xml-rs", +] + +[[package]] +name = "rusoto_signature" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7063a70614eb4b36f49bcf4f6f6bb30cc765e3072b317d6afdfe51e7a9f482d1" +dependencies = [ + "base64 0.11.0", + "bytes", + "futures 0.1.29", + "hex 0.4.0", + "hmac", + "http", + "hyper 0.12.35", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "md5", + "percent-encoding 2.1.0", + "rusoto_credential", + "rustc_version 0.2.2", + "serde", + "sha2", + "time", + "tokio", +] + +[[package]] +name = "rust-argon2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" +dependencies = [ + "base64 0.10.0", + "blake2b_simd", + "crossbeam-utils", ] [[package]] name = "rust-crypto" version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" +dependencies = [ + "gcc", + "libc", + "rand 0.3.14", + "rustc-serialize", + "time", +] + +[[package]] +name = "rust-ini" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c96a7d6722944454c68ff2ba2a252a4e9b0635c03dd510fdf482a2c8981cbf2" dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.8.0", ] [[package]] name = "rustc-demangle" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" [[package]] name = "rustc-hash" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", ] [[package]] name = "rustc-serialize" version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" [[package]] name = "rustc_version" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" dependencies = [ - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.1.20", ] [[package]] name = "rustc_version" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0", ] [[package]] name = "ryu" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" [[package]] name = "ryu" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" [[package]] name = "safemem" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" [[package]] name = "same-file" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" dependencies = [ - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" +dependencies = [ + "lazy_static 1.4.0", + "winapi 0.3.4", ] [[package]] name = "scoped-tls" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" [[package]] name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" + +[[package]] +name = "security-framework" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" +dependencies = [ + "core-foundation-sys", +] [[package]] name = "semver" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" [[package]] name = "serde_derive" -version = "1.0.81" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6", + "quote 1.0.2", + "syn 1.0.8", ] [[package]] name = "serde_json" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu 0.2.8", + "serde", ] [[package]] name = "servo_arc" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", ] [[package]] name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signal" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106428d9d96840ecdec5208c13ab8a4e28c38da1e0ccf2909fb44e41b992f897" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "nix 0.11.0", +] + +[[package]] +name = "signal-hook" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9c17dd3ba2d36023a5c9472ecddeda07e27fd0b05436e8c1e0c8f178185652" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +dependencies = [ + "arc-swap 0.4.4", + "libc", ] [[package]] name = "slab" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" [[package]] name = "slog" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e4f1d0276ac7d448d98db16f0dab0220c24d4842d88ce4dad4b306fa234f1d" [[package]] name = "slog-async" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" dependencies = [ - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "slog", + "take_mut", + "thread_local", ] [[package]] @@ -2534,40 +3347,43 @@ name = "slog-global" version = "0.1.0" source = "git+https://github.com/breeswish/slog-global.git?rev=91904ade#91904adec6e602df234e30560e98ef281d81eb84" dependencies = [ - "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap 0.3.7", + "lazy_static 1.4.0", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slog", ] [[package]] name = "slog-term" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5951a808c40f419922ee014c15b6ae1cd34d963538b57d8a4778b9ca3fff1e0b" dependencies = [ - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "isatty", + "slog", + "term", + "thread_local", ] [[package]] name = "slog_derive" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.15.33", ] [[package]] name = "smallvec" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit", ] [[package]] @@ -2575,17 +3391,30 @@ name = "snappy-sys" version = "0.1.0" source = "git+https://github.com/busyjay/rust-snappy.git?branch=static-link#8c12738bad811397600455d6982aff754ea2ac44" dependencies = [ - "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake", + "libc", + "pkg-config", +] + +[[package]] +name = "socket2" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.4", ] [[package]] name = "solicit" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2" dependencies = [ - "hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hpack", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2593,432 +3422,481 @@ dependencies = [ name = "spin" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b5646825922b96b5d7d676b5bb3458a54498e96ed7b0ce09dc43a07038fea4" [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "stable_deref_trait" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" [[package]] name = "stackvector" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c77bf85fbc036484c97b008276d539d9ebff9dfbde37b632ebcd5b8746b6" dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable", ] [[package]] name = "static_assertions" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" [[package]] name = "static_assertions" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1" [[package]] name = "str_stack" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" [[package]] name = "string" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98998cced76115b1da46f63388b909d118a37ae0be0f82ad35773d4a4bc9d18d" [[package]] name = "strsim" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" [[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.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c167b61c7d4c126927f5346a4327ce20abf8a186b8041bbeb1ce49e5db49587b" dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "structopt-derive", ] [[package]] name = "structopt-derive" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "519621841414165d2ad0d4c92be8f41844203f2b67e245f9345a5a12d40c69d7" dependencies = [ - "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro-error", + "proc-macro2 1.0.6", + "quote 1.0.2", + "syn 1.0.8", ] +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + [[package]] name = "syn" version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15", + "synom", + "unicode-xid 0.0.4", ] [[package]] name = "syn" version = "0.13.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" dependencies = [ - "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.8", + "quote 0.5.2", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +dependencies = [ + "proc-macro2 0.4.29", + "quote 0.6.10", + "unicode-xid 0.1.0", ] [[package]] name = "syn" version = "0.15.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec52cd796e5f01d0067225a5392e70084acc4c0013fa71d55166d38a8b307836" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.29", + "quote 0.6.10", + "unicode-xid 0.1.0", ] [[package]] name = "syn" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.6", + "quote 1.0.2", + "unicode-xid 0.2.0", ] [[package]] name = "synom" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4", ] [[package]] name = "synstructure" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" dependencies = [ - "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.29", + "quote 0.6.10", + "syn 0.15.33", + "unicode-xid 0.1.0", ] [[package]] name = "sys-info" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d6cf7b349b6a6daaf7a3797227e2f4108c8dd398e0aca7e29b9fb239948541" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", ] [[package]] name = "take_mut" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" [[package]] name = "tcmalloc" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375205113d84a1c5eeed67beaa0ce08e41be1a9d5acc3425ad2381fddd9d819b" dependencies = [ - "tcmalloc-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tcmalloc-sys", ] [[package]] name = "tcmalloc-sys" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b7ad73e635dd232c2c2106d59269f59a61de421cc6b95252d2d932094ff1f40" [[package]] name = "tempdir" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b62933a3f96cd559700662c34f8bab881d9e3540289fb4f368419c7f13a5aa9" dependencies = [ - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14", ] [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "rand 0.7.2", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.4", ] [[package]] name = "term" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7", + "winapi 0.3.4", ] [[package]] name = "termcolor" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" dependencies = [ - "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wincolor", ] [[package]] name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_syscall", + "redox_termios", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0", ] [[package]] name = "tiflash-proxy" version = "0.0.1" dependencies = [ - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "engine 0.0.1", - "fail 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fs2 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kvproto 0.0.1 (git+https://github.com/pingcap/kvproto.git?branch=release-3.1)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "clap", + "engine", + "fail 0.3.0", + "fs2", + "futures 0.1.29", + "grpcio", + "hex 0.3.2", + "kvproto", + "libc", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "raft 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "signal 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-global 0.1.0 (git+https://github.com/breeswish/slog-global.git?rev=91904ade)", - "tikv 4.1.0-alpha", - "tikv_alloc 0.1.0", - "tikv_util 0.1.0", - "toml 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "vlog 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.11.0", + "protobuf", + "raft", + "rand 0.6.5", + "serde", + "serde_json", + "signal", + "slog", + "slog-global", + "tikv", + "tikv_alloc", + "tikv_util", + "toml", + "url 1.7.2", + "vlog", ] [[package]] name = "tikv" version = "4.1.0-alpha" dependencies = [ - "arrow 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono-tz 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "codec 0.0.1", - "cop_codegen 0.0.1", - "cop_datatype 0.0.1", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crc64fast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-papi 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "engine 0.0.1", - "external_storage 0.0.1", - "fail 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "farmhash 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fs2 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvproto 0.0.1 (git+https://github.com/pingcap/kvproto.git?branch=release-3.1)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow", + "backtrace 0.2.3", + "base64 0.10.0", + "batch-system", + "bitflags", + "byteorder 1.2.7", + "bytes", + "chrono", + "chrono-tz", + "codec", + "cop_codegen", + "cop_datatype", + "crc32fast", + "crc64fast", + "criterion 0.2.11", + "criterion-papi", + "crossbeam 0.5.0", + "derive_more 0.11.0", + "engine", + "external_storage", + "fail 0.2.0", + "farmhash", + "flate2", + "fs2", + "futures 0.1.29", + "futures-cpupool", + "futures-executor", + "futures-util", + "grpcio", + "hashbrown", + "hex 0.3.2", + "hyper 0.12.35", + "indexmap", + "kvproto", + "lazy_static 1.4.0", + "libc", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "log_wrappers 0.0.1", - "match_template 0.0.1", - "more-asserts 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "murmur3 0.4.0 (git+https://github.com/pingcap/murmur3.git)", - "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "panic_hook 0.0.1", - "pprof 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", - "procinfo 0.4.2 (git+https://github.com/tikv/procinfo-rs)", - "profiler 0.0.1", + "log_wrappers", + "match_template", + "more-asserts", + "murmur3", + "nix 0.11.0", + "nom 5.0.0-beta1", + "num", + "num-traits 0.2.5", + "ordered-float", + "panic_hook", + "pprof", + "procinfo 0.4.2", + "profiler", "prometheus 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "prometheus-static-metric 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "raft 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "servo_arc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "signal 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-global 0.1.0 (git+https://github.com/breeswish/slog-global.git?rev=91904ade)", - "slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", - "tikv_util 0.1.0", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tipb 0.0.1 (git+https://github.com/pingcap/tipb.git?branch=release-3.1)", - "tipb_helper 0.0.1", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "twoway 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "utime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vlog 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "zipf 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prometheus-static-metric", + "prost 0.5.0", + "protobuf", + "quick-error 1.2.2", + "raft", + "rand 0.6.5", + "rand_xorshift", + "regex", + "rust-crypto", + "safemem", + "serde", + "serde_derive", + "serde_json", + "servo_arc", + "signal", + "slog", + "slog-async", + "slog-global", + "slog-term", + "slog_derive", + "smallvec", + "sys-info", + "tempdir", + "tikv_alloc", + "tikv_util", + "time", + "tipb", + "tipb_helper", + "tokio-core", + "tokio-executor", + "tokio-threadpool", + "tokio-timer", + "toml", + "twoway", + "url 1.7.2", + "utime", + "uuid", + "vlog", + "zipf", ] [[package]] name = "tikv_alloc" version = "0.1.0" dependencies = [ - "jemalloc-ctl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "jemalloc-ctl", + "jemalloc-sys", + "jemallocator", + "libc", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tcmalloc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tcmalloc", + "tempdir", ] [[package]] name = "tikv_util" version = "0.1.0" dependencies = [ - "async-speed-limit 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "async-speed-limit", + "backtrace 0.2.3", + "byteorder 1.2.7", + "chrono", + "crc32fast", + "crossbeam 0.5.0", + "futures 0.1.29", + "futures-cpupool", + "grpcio", + "hashbrown", + "hex 0.3.2", + "indexmap", + "lazy_static 1.4.0", + "libc", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)", - "panic_hook 0.0.1", - "procinfo 0.4.2 (git+https://github.com/tikv/procinfo-rs)", + "openssl", + "panic_hook", + "procinfo 0.4.2", "prometheus 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "prometheus-static-metric 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "raft 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-global 0.1.0 (git+https://github.com/breeswish/slog-global.git?rev=91904ade)", - "slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tikv_alloc 0.1.0", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "utime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prometheus-static-metric", + "protobuf", + "quick-error 1.2.2", + "raft", + "rand 0.6.5", + "regex", + "serde", + "serde_derive", + "serde_json", + "slog", + "slog-async", + "slog-global", + "slog-term", + "tempdir", + "tikv_alloc", + "time", + "tokio-core", + "tokio-executor", + "tokio-threadpool", + "tokio-timer", + "toml", + "url 1.7.2", + "utime", ] [[package]] name = "time" version = "0.1.38" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "libc", + "redox_syscall", + "winapi 0.2.8", ] [[package]] name = "tinytemplate" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655088894274afb52b807bd3c87072daa1fedd155068b8705cabfd628956115" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "serde_json", ] [[package]] @@ -3026,865 +3904,618 @@ name = "tipb" version = "0.0.1" source = "git+https://github.com/pingcap/tipb.git?branch=release-3.1#e3fa30d76f02de374b00dcb3f6288a4fccb9e0ca" dependencies = [ - "protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf", ] [[package]] name = "tipb_helper" version = "0.0.1" dependencies = [ - "codec 0.0.1", - "cop_datatype 0.0.1", - "tipb 0.0.1 (git+https://github.com/pingcap/tipb.git?branch=release-3.1)", + "codec", + "cop_datatype", + "tipb", ] [[package]] name = "tokio" -version = "0.1.14" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "mio", + "num_cpus", + "tokio-codec", + "tokio-current-thread", + "tokio-executor", + "tokio-fs", + "tokio-io", + "tokio-reactor", + "tokio-sync", + "tokio-tcp", + "tokio-threadpool", + "tokio-timer", + "tokio-udp", + "tokio-uds", ] [[package]] name = "tokio-buf" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "either", + "futures 0.1.29", ] [[package]] name = "tokio-codec" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "tokio-io", ] [[package]] name = "tokio-core" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "iovec", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "mio", + "scoped-tls", + "tokio", + "tokio-executor", + "tokio-io", + "tokio-reactor", + "tokio-timer", ] [[package]] name = "tokio-current-thread" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "tokio-executor", ] [[package]] name = "tokio-executor" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", + "futures 0.1.29", ] [[package]] name = "tokio-fs" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "tokio-io", + "tokio-threadpool", ] [[package]] name = "tokio-io" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-process" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbd6ef1b8cc2bd2c2b580d882774d443ebb1c6ceefe35ba9ea4ab586c89dbe8" +dependencies = [ + "crossbeam-queue", + "futures 0.1.29", + "lazy_static 1.4.0", + "libc", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio", + "mio-named-pipes", + "tokio-io", + "tokio-reactor", + "tokio-signal", + "winapi 0.3.4", +] + [[package]] name = "tokio-reactor" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502b625acb4ee13cbb3b90b8ca80e0addd263ddacf6931666ef751e610b07fb5" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", + "futures 0.1.29", + "lazy_static 1.4.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "mio", + "num_cpus", + "parking_lot 0.6.4", + "slab", + "tokio-executor", + "tokio-io", +] + +[[package]] +name = "tokio-signal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" +dependencies = [ + "futures 0.1.29", + "libc", + "mio", + "mio-uds", + "signal-hook", + "tokio-executor", + "tokio-io", + "tokio-reactor", + "winapi 0.3.4", +] + +[[package]] +name = "tokio-sync" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" +dependencies = [ + "fnv", + "futures 0.1.29", ] [[package]] name = "tokio-tcp" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "iovec", + "mio", + "tokio-io", + "tokio-reactor", ] [[package]] name = "tokio-threadpool" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ca01319dea1e376a001e8dc192d42ebde6dd532532a5bad988ac37db365b19" dependencies = [ - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1", + "crossbeam-queue", + "crossbeam-utils", + "futures 0.1.29", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus", + "rand 0.6.5", + "slab", + "tokio-executor", ] [[package]] name = "tokio-timer" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", + "futures 0.1.29", + "slab", + "tokio-executor", ] [[package]] name = "tokio-udp" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio", + "tokio-io", + "tokio-reactor", ] [[package]] name = "tokio-uds" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ce87382f6c1a24b513a72c048b2c8efe66cb5161c9061d00bee510f08dc168" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures 0.1.29", + "iovec", + "libc", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio", + "mio-uds", + "tokio-codec", + "tokio-io", + "tokio-reactor", ] [[package]] name = "toml" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f84e29784a306d290f4468689f7fa250870f33118fdec09fa818998c6288625" dependencies = [ - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "traitobject" version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616" [[package]] name = "try-lock" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "twoway" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "766345ed3891b291d01af307cd3ad2992a4261cb6c0c7e665cd3e01cf379dd24" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unchecked-index 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", + "unchecked-index", ] [[package]] name = "typeable" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" + +[[package]] +name = "typenum" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" [[package]] name = "ucd-util" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" [[package]] name = "unchecked-index" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" [[package]] name = "unicase" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764" dependencies = [ - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.1.7", ] [[package]] name = "unicode-bidi" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", ] [[package]] name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" dependencies = [ - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", ] [[package]] name = "unicode-normalization" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" dependencies = [ - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec", ] [[package]] name = "unicode-segmentation" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" [[package]] name = "unicode-width" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" [[package]] name = "unicode-xid" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "unreachable" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "void", ] [[package]] name = "url" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" dependencies = [ - "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.1.0", + "matches", + "percent-encoding 1.0.0", ] [[package]] name = "url" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" dependencies = [ - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.2.0", + "matches", + "percent-encoding 2.1.0", ] [[package]] name = "utf8-ranges" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" [[package]] name = "utime" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9c0ddf7a5a39cd0c316dac124303d71fa197f8607027546c3be3e1c6f7bd9b" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "libc", + "winapi 0.2.8", ] [[package]] name = "uuid" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "rand 0.4.2", + "serde", ] [[package]] name = "valgrind_request" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0fb139b14473e1350e34439c888e44c805f37b4293d17f87ea920a66a20a99a" [[package]] name = "vcpkg" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" [[package]] name = "vlog" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2266fcb904c50fb17fda4c9a751a1715629ecf8b21f4c9d78b4890fb71525d71" [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "walkdir" version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" dependencies = [ - "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file", + "winapi 0.3.4", + "winapi-util", ] [[package]] name = "want" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock", ] [[package]] name = "wasi" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" [[package]] name = "which" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "failure", + "libc", ] [[package]] name = "which" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240a31163872f7e8e49f35b42b58485e35355b07eb009d9f3686733541339a69" dependencies = [ - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[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.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4", ] [[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 = "wincolor" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4", + "winapi-util", ] [[package]] name = "ws2_32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] +[[package]] +name = "xml-rs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" + +[[package]] +name = "yaml-rust" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" + [[package]] name = "zipf" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2057772d87bedea0efd93842ee0e0f52fc0c313c556d5fa8ee787771c051a61f" dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5", ] [[package]] name = "zstd-sys" version = "1.4.15+zstd.1.4.4" -source = "git+https://github.com/gyscos/zstd-rs.git#c0e8491d460311117bacd0262374f8b973ec8b69" -dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum arrow 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398bc55d60097e7b7e9be67d1cb03cb41e5bf4901381607ba0fca8b1328584d6" -"checksum async-speed-limit 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8960ff0e84c4330f6d3d882fad4a3d292cdb1729b1acbc1c22dab0af0f77e6f1" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" -"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5" -"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" -"checksum base64 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "621fc7ecb8008f86d7fb9b95356cd692ce9514b80a86d85b397f32a22da7b9e2" -"checksum bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75" -"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" -"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" -"checksum byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e4ca3a1755927e5b00c3fe43250053b957b5c074d9f17782b88ef7aa0fb4dfe2" -"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" -"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bzip2-sys 0.1.7 (git+https://github.com/alexcrichton/bzip2-rs.git)" = "" -"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum callgrind 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f7f788eaf239475a3c1e1acf89951255a46c4b9b46cf3e866fc4d0707b4b9e36" -"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" -"checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" -"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" -"checksum chashmap 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff41a3c2c1e39921b9003de14bf0439c7b63a9039637c291e1a64925d8ddfa45" -"checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0" -"checksum chrono-tz 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e0e430fad0384e4defc3dc6b1223d1b886087a8bf9b7080e5ae027f73851ea15" -"checksum clang-sys 0.28.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" -"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" -"checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626" -"checksum cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "33f07976bb6821459632d7a18d97ccca005cb5c552f251f822c7c1781c1d7035" -"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -"checksum crc64fast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a82510de0a7cadd51dc68ff17da70aea0c80157f902230f9b157cecc2566318" -"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" -"checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6" -"checksum criterion-papi 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd402c80822a64e66751efaca958ac1047a301c9455dce110c8ef1e9b8ecb931" -"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" -"checksum criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eccdc6ce8bbe352ca89025bee672aa6d24f4eb8c53e3a8b5d1bc58011da072a2" -"checksum crossbeam 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1c92ff2d7a202d592f5a412d75cf421495c913817781c1cb383bf12a77e185f" -"checksum crossbeam 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b14492071ca110999a20bf90e3833406d5d66bfd93b4e52ec9539025ff43fe0d" -"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" -"checksum crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe1b6f945f824c7a25afe44f62e25d714c0cc523f8e99d8db5cd1026e1269d3" -"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" -"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" -"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" -"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" -"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" -"checksum darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6" -"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c" -"checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1" -"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" -"checksum derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b" -"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" -"checksum enum-primitive-derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd" -"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" -"checksum error-chain 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5c82c815138e278b8dcdeffc49f27ea6ffb528403e9dea4194f2e3dd40b143" -"checksum fail 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd2e1a22c616c8c8c96b6e07c243014551f3ba77291d24c22e0bfea6830c0b4e" -"checksum fail 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f63eec71a3013ee912a0ecb339ff0c5fa5ed9660df04bfefa10c250b885d018c" -"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" -"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" -"checksum farmhash 1.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f35ce9c8fb9891c75ceadbc330752951a4e369b50af10775955aeb9af3eee34b" -"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" -"checksum flate2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96971e4fc2737f211ec8236fe16ac67695838ca3e25567c07b4f837d1f8f829c" -"checksum flate2-crc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a792245eaed7747984647ce20582507985d69ccfacdddcb60bd5f451f21cbc5" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fs2 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "237b7991317b8d94391c0a4813b1f74fd81c11352440cd598d2b763ed288bfc1" -"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" -"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" -"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" -"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" -"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" -"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -"checksum grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9ac757a85603e4f8c40a9f94be06a5ad412acab80b39b4e8895ca931b6619910" -"checksum grpcio-compiler 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373a14f0f994d4c235770f4bb5558be00626844db130a82a70142b8fc5996fc3" -"checksum grpcio-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7b2f22fb0327f153acccedbe91894dd0fb15bb6f202d8195665cd206af0402b0" -"checksum h2 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1ac030ae20dee464c5d0f36544d8b914a6bc606da44a57e052d2b0f5dae129e0" -"checksum hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "64b7d419d0622ae02fe5da6b9a5e1964b610a65bb37923b976aeebb6dbb8f86e" -"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" -"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58" -"checksum http 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf" -"checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -"checksum httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46534074dbb80b070d60a5cb8ecadd8963a00a438ae1a95268850a7ef73b67ae" -"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -"checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" -"checksum hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9bf64f730d6ee4b0528a5f0a316363da9d8104318731509d4ccc86248f82b3" -"checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" -"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220" -"checksum inferno 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "880c9746895893d66a6b0ecf49d46271e3a0f6763ebbb910cb0dd7c2097a61f3" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a118a53ba42790ef25c82bb481ecf36e2da892646cccd361e69a6bb881e19398" -"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum jemalloc-ctl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e93b0f37e7d735c6b610176d5b1bde8e1621ff3f6f7ac23cdfa4e7f7d0111b5" -"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" -"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" -"checksum jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b1d42ef453b30b7387e113da1c83ab1605d90c5b4e0eb8e96d016ed3b8c160" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum kvproto 0.0.1 (git+https://github.com/pingcap/kvproto.git?branch=release-3.1)" = "" -"checksum kvproto 0.0.1 (git+https://github.com/solotzg/kvproto.git?branch=learner-merge)" = "" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e" -"checksum libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c" -"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" -"checksum libpapi_sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9c687368f5a574f3aaf97cad438fb572a87aa224051e1cd01ad926b1d592886b" -"checksum librocksdb_sys 0.1.0 (git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x)" = "" -"checksum libtitan_sys 0.0.1 (git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x)" = "" -"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" -"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" -"checksum log 0.3.9 (git+https://github.com/busyjay/log?branch=use-static-module)" = "" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.6 (git+https://github.com/busyjay/log?branch=revert-to-static)" = "" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lz4-sys 1.8.3 (git+https://github.com/busyjay/lz4-rs.git?branch=adjust-build)" = "" -"checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e" -"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" -"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5c93a4bd787ddc6e7833c519b73a50883deb5863d76d9b71eb8216fb7f94e66" -"checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" -"checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" -"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" -"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum more-asserts 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf21d96e87e5d48e3b50ab1512142f2fbe06fc48b7b032dead87fbfcb83f9a89" -"checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" -"checksum murmur3 0.4.0 (git+https://github.com/pingcap/murmur3.git)" = "" -"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" -"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" -"checksum nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)" = "6527f311b2baba609e980e008460ab5ebff6d6da15213bb8eb193b7746eefa24" -"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" -"checksum num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" -"checksum num-format 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" -"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" -"checksum num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "51eab148f171aefad295f8cece636fc488b9b392ef544da31ea4b8ef6b9e9c39" -"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" -"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" -"checksum openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449" -"checksum openssl-src 111.6.0+1.1.1d (registry+https://github.com/rust-lang/crates.io-index)" = "b9c2da1de8a7a3f860919c01540b03a6db16de042405a8a07a5e9d0b4b825d9c" -"checksum openssl-sys 0.9.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c977d08e1312e2f7e4b86f9ebaa0ed3b19d1daff75fae88bbb88108afbd801fc" -"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" -"checksum parse-zoneinfo 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "089a398ccdcdd77b8c38909d5a1e4b67da1bc4c9dbfe6d5b536c828eddb779e5" -"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" -"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" -"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" -"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" -"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum pprof 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "c794c3b7ab21a9954fde0cd48085deccf624f14cf3d9c137f35f1aa3a3ca5d60" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" -"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" -"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" -"checksum procinfo 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f42e8578852a3306838981aedad8c5642ba794929aa12af0c9eb6c072b77af6c" -"checksum procinfo 0.4.2 (git+https://github.com/tikv/procinfo-rs)" = "" -"checksum prometheus 0.4.2 (git+https://github.com/birdstorm/rust-prometheus?branch=0.4.2)" = "" -"checksum prometheus 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "760293453bee1de0a12987422d7c4885f7ee933e4417bb828ed23f7d05c3c390" -"checksum prometheus-static-metric 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d2b4a6a1ae793e7eb6773a5301a5a08e8929ea5517b677c93e57ce2d0973c02" -"checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" -"checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" -"checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" -"checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" -"checksum protobuf 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fbc4570f22641ed8c65326d54832ce1536e9ddf0ccb7a8c836cbe780d7e23537" -"checksum protobuf-build 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a94ea746889322eb33b6977db6ffe82b1decaac1804958b9179245fc45dc4b6" -"checksum protobuf-codegen 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c12a571137dc99703cb46fa21f185834fc5578a65836573fcff127f7b53f41e1" -"checksum protoc 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1a649b870f7fe03c965bf2fa6728361f6abbb6f3b72079515af8cb56d769cf" -"checksum protoc-grpcio 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9798b534614b71d780778b1508410826073b5a1ca111a090f1f3fd3ac663ef6" -"checksum protoc-rust 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "14565959d6394858759919e011675edc2e851c37cf1095fa7d313409368c1e63" -"checksum quick-error 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ac990ab4e038dd8481a5e3fd00641067fcfc674ad663f3222752ed5284e05d4" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quick-xml 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cd45021132c1cb5540995e93fcc2cf5a874ef84f9639168fb6819caa023d4be" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" -"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum raft 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "43648985159f2c4c25f934182a63b0dd4c5cc06a5ae96e5d40e12c3a3785abde" -"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" -"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a" -"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -"checksum rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e18c91676f670f6f0312764c759405f13afb98d5d73819840cf72a518487bff" -"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" -"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "80dcf663dc552529b9bfc7bdb30ea12e5fa5d3545137d850a91ad410053f68e9" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" -"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" -"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rgb 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2089e4031214d129e201f8c3c8c2fe97cd7322478a0d1cdf78e7029b0042efdb" -"checksum rocksdb 0.3.0 (git+https://github.com/pingcap/rust-rocksdb.git?branch=tikv-3.x)" = "" -"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" -"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" -"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" -"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" -"checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" -"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" -"checksum serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885" -"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae" -"checksum servo_arc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" -"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" -"checksum signal 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "106428d9d96840ecdec5208c13ab8a4e28c38da1e0ccf2909fb44e41b992f897" -"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" -"checksum slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09e4f1d0276ac7d448d98db16f0dab0220c24d4842d88ce4dad4b306fa234f1d" -"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" -"checksum slog-global 0.1.0 (git+https://github.com/breeswish/slog-global.git?rev=91904ade)" = "" -"checksum slog-term 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5951a808c40f419922ee014c15b6ae1cd34d963538b57d8a4778b9ca3fff1e0b" -"checksum slog_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eff3b513cf2e0d1a60e1aba152dc72bedc5b05585722bb3cebd7bcb1e31b98f" -"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -"checksum snappy-sys 0.1.0 (git+https://github.com/busyjay/rust-snappy.git?branch=static-link)" = "" -"checksum solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "172382bac9424588d7840732b250faeeef88942e37b6e35317dce98cafdd75b2" -"checksum spin 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "37b5646825922b96b5d7d676b5bb3458a54498e96ed7b0ce09dc43a07038fea4" -"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" -"checksum stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c049c77bf85fbc036484c97b008276d539d9ebff9dfbde37b632ebcd5b8746b6" -"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" -"checksum static_assertions 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "389ce475f424f267dbed6479cbd8f126c5e1afb053b0acdaa019c74305fc65d1" -"checksum str_stack 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" -"checksum string 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98998cced76115b1da46f63388b909d118a37ae0be0f82ad35773d4a4bc9d18d" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c167b61c7d4c126927f5346a4327ce20abf8a186b8041bbeb1ce49e5db49587b" -"checksum structopt-derive 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "519621841414165d2ad0d4c92be8f41844203f2b67e245f9345a5a12d40c69d7" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" -"checksum syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)" = "ec52cd796e5f01d0067225a5392e70084acc4c0013fa71d55166d38a8b307836" -"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" -"checksum sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "76d6cf7b349b6a6daaf7a3797227e2f4108c8dd398e0aca7e29b9fb239948541" -"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" -"checksum tcmalloc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "375205113d84a1c5eeed67beaa0ce08e41be1a9d5acc3425ad2381fddd9d819b" -"checksum tcmalloc-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b7ad73e635dd232c2c2106d59269f59a61de421cc6b95252d2d932094ff1f40" -"checksum tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0b62933a3f96cd559700662c34f8bab881d9e3540289fb4f368419c7f13a5aa9" -"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" -"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum tinytemplate 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7655088894274afb52b807bd3c87072daa1fedd155068b8705cabfd628956115" -"checksum tipb 0.0.1 (git+https://github.com/pingcap/tipb.git?branch=release-3.1)" = "" -"checksum tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4790d0be6f4ba6ae4f48190efa2ed7780c9e3567796abdb285003cf39840d9c5" -"checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" -"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e" -"checksum tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "60ae25f6b17d25116d2cba342083abe5255d3c2c79cb21ea11aa049c53bf7c75" -"checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" -"checksum tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "502b625acb4ee13cbb3b90b8ca80e0addd263ddacf6931666ef751e610b07fb5" -"checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" -"checksum tokio-threadpool 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ec5759cf26cf9659555f36c431b515e3d05f66831741c85b4b5d5dfb9cf1323c" -"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" -"checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" -"checksum tokio-uds 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "99ce87382f6c1a24b513a72c048b2c8efe66cb5161c9061d00bee510f08dc168" -"checksum toml 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f84e29784a306d290f4468689f7fa250870f33118fdec09fa818998c6288625" -"checksum traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "07eaeb7689bb7fca7ce15628319635758eda769fed481ecfe6686ddef2600616" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum twoway 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "766345ed3891b291d01af307cd3ad2992a4261cb6c0c7e665cd3e01cf379dd24" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unchecked-index 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" -"checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764" -"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" -"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" -"checksum utime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4a9c0ddf7a5a39cd0c316dac124303d71fa197f8607027546c3be3e1c6f7bd9b" -"checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" -"checksum valgrind_request 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fb139b14473e1350e34439c888e44c805f37b4293d17f87ea920a66a20a99a" -"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum vlog 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2266fcb904c50fb17fda4c9a751a1715629ecf8b21f4c9d78b4890fb71525d71" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" -"checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" -"checksum which 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "240a31163872f7e8e49f35b42b58485e35355b07eb009d9f3686733541339a69" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum zipf 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2057772d87bedea0efd93842ee0e0f52fc0c313c556d5fa8ee787771c051a61f" -"checksum zstd-sys 1.4.15+zstd.1.4.4 (git+https://github.com/gyscos/zstd-rs.git)" = "" +source = "git+https://github.com/gyscos/zstd-rs.git#3df21bbc06a5257967ca7f30ba33a6512e0cde4b" +dependencies = [ + "cc", + "glob", + "itertools 0.8.2", + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 86e6283675e..29d8e693d7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,6 +105,7 @@ engine = { path = "components/engine" } tikv_util = { path = "components/tikv_util" } farmhash = "1.1.5" external_storage = { path = "components/external_storage" } +batch-system = { path = "components/batch-system" } [dependencies.murmur3] git = "https://github.com/pingcap/murmur3.git" @@ -122,7 +123,6 @@ default-features = false [replace] "log:0.3.9" = { git = "https://github.com/busyjay/log", branch = "use-static-module" } "log:0.4.6" = { git = "https://github.com/busyjay/log", branch = "revert-to-static" } -"https://github.com/pingcap/kvproto.git#kvproto:0.0.1" = { git = "https://github.com/solotzg/kvproto.git", branch = "learner-merge" } "prometheus:0.4.2" = { git = "https://github.com/birdstorm/rust-prometheus", branch = "0.4.2" } [dev-dependencies] diff --git a/components/backup/src/writer.rs b/components/backup/src/writer.rs index ec01abe1b4f..aacb1ed335f 100644 --- a/components/backup/src/writer.rs +++ b/components/backup/src/writer.rs @@ -69,14 +69,18 @@ impl Writer { .observe(sst_info.file_size() as f64); let file_name = format!("{}_{}.sst", name, cf); - let reader = Sha256Reader::new(sst_reader) + let (reader, hasher) = Sha256Reader::new(sst_reader) .map_err(|e| Error::Other(box_err!("Sha256 error: {:?}", e)))?; - let mut reader = limiter.limit(AllowStdIo::new(reader)); - storage.write(&file_name, &mut reader)?; - let sha256 = reader - .into_inner() - .into_inner() - .hash() + storage.write( + &file_name, + Box::new(limiter.limit(AllowStdIo::new(reader))), + sst_info.file_size(), + )?; + let sha256 = hasher + .lock() + .unwrap() + .finish() + .map(|digest| digest.to_vec()) .map_err(|e| Error::Other(box_err!("Sha256 error: {:?}", e)))?; let mut file = File::new(); diff --git a/components/batch-system/Cargo.toml b/components/batch-system/Cargo.toml new file mode 100644 index 00000000000..5d22c9961d5 --- /dev/null +++ b/components/batch-system/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "batch-system" +version = "0.1.0" +edition = "2018" + +[dependencies] +crossbeam = "0.7" +tikv_util = { path = "../tikv_util" } +slog = { version = "2.3", features = ["max_level_trace", "release_max_level_debug"] } +slog-global = { version = "0.1", git = "https://github.com/breeswish/slog-global.git", rev = "91904ade" } +derive_more = "0.15.0" + +[dev-dependencies] +criterion = "0.3" + +[[test]] +name = "tests" +path = "tests/cases/mod.rs" +required-features = ["test-runner"] + +[[bench]] +name = "router" +harness = false +required-features = ["test-runner"] + +[[bench]] +name = "batch-system" +harness = false +required-features = ["test-runner"] \ No newline at end of file diff --git a/components/batch-system/benches/batch-system.rs b/components/batch-system/benches/batch-system.rs new file mode 100644 index 00000000000..0c317d7d89b --- /dev/null +++ b/components/batch-system/benches/batch-system.rs @@ -0,0 +1,142 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +#![feature(test)] + +extern crate test; + +use batch_system::test_runner::*; +use batch_system::*; +use criterion::*; +use std::sync::atomic::*; +use std::sync::Arc; + +fn end_hook(tx: &std::sync::mpsc::Sender<()>) -> Message { + let tx = tx.clone(); + Message::Callback(Box::new(move |_| { + tx.send(()).unwrap(); + })) +} + +/// Benches how it performs when many messages are sent to the bench system. +/// +/// A better router and lightweight batch scheduling can lead to better result. +fn bench_spawn_many(c: &mut Criterion) { + let (control_tx, control_fsm) = Runner::new(100000); + let (router, mut system) = batch_system::create_system(2, 2, control_tx, control_fsm); + system.spawn("test".to_owned(), Builder::new()); + const ID_LIMIT: u64 = 32; + const MESSAGE_LIMIT: usize = 256; + for id in 0..ID_LIMIT { + let (normal_tx, normal_fsm) = Runner::new(100000); + let normal_box = BasicMailbox::new(normal_tx, normal_fsm); + router.register(id, normal_box); + } + + let (tx, rx) = std::sync::mpsc::channel(); + c.bench_function("spawn_many", |b| { + b.iter(|| { + for id in 0..ID_LIMIT { + for i in 0..MESSAGE_LIMIT { + router.send(id, Message::Loop(i)).unwrap(); + } + router.send(id, end_hook(&tx)).unwrap(); + } + for _ in 0..ID_LIMIT { + rx.recv().unwrap(); + } + }) + }); + system.shutdown(); +} + +/// Bench how it performs if two hot FSMs are shown up at the same time. +/// +/// A good scheduling algorithm should be able to spread the hot FSMs to +/// all available threads as soon as possible. +fn bench_imbalance(c: &mut Criterion) { + let (control_tx, control_fsm) = Runner::new(100000); + let (router, mut system) = batch_system::create_system(2, 2, control_tx, control_fsm); + system.spawn("test".to_owned(), Builder::new()); + const ID_LIMIT: u64 = 10; + const MESSAGE_LIMIT: usize = 512; + for id in 0..ID_LIMIT { + let (normal_tx, normal_fsm) = Runner::new(100000); + let normal_box = BasicMailbox::new(normal_tx, normal_fsm); + router.register(id, normal_box); + } + + let (tx, rx) = std::sync::mpsc::channel(); + c.bench_function("imbalance", |b| { + b.iter(|| { + for i in 0..MESSAGE_LIMIT { + for id in 0..2 { + router.send(id, Message::Loop(i)).unwrap(); + } + } + for id in 0..2 { + router.send(id, end_hook(&tx)).unwrap(); + } + for _ in 0..2 { + rx.recv().unwrap(); + } + }) + }); + system.shutdown(); +} + +/// Bench how it performs when scheduling a lot of quick tasks during an long-polling +/// tasks. +/// +/// A good scheduling algorithm should not starve the quick tasks. +fn bench_fairness(c: &mut Criterion) { + let (control_tx, control_fsm) = Runner::new(100000); + let (router, mut system) = batch_system::create_system(2, 2, control_tx, control_fsm); + system.spawn("test".to_owned(), Builder::new()); + for id in 0..10 { + let (normal_tx, normal_fsm) = Runner::new(100000); + let normal_box = BasicMailbox::new(normal_tx, normal_fsm); + router.register(id, normal_box); + } + + let (tx, _rx) = std::sync::mpsc::channel(); + let running = Arc::new(AtomicBool::new(true)); + let router1 = router.clone(); + let running1 = running.clone(); + let handle = std::thread::spawn(move || { + while running1.load(Ordering::SeqCst) { + // Using 4 to ensure all worker threads are busy spinning. + for id in 0..4 { + let _ = router1.send(id, Message::Loop(16)); + } + } + tx.send(()).unwrap(); + }); + + let (tx2, rx2) = std::sync::mpsc::channel(); + c.bench_function("fairness", |b| { + b.iter(|| { + for _ in 0..10 { + for id in 4..6 { + router.send(id, Message::Loop(10)).unwrap(); + } + } + for id in 4..6 { + router.send(id, end_hook(&tx2)).unwrap(); + } + for _ in 4..6 { + rx2.recv().unwrap(); + } + }) + }); + running.store(false, Ordering::SeqCst); + system.shutdown(); + let _ = handle.join(); +} + +criterion_group!(fair, bench_fairness); +criterion_group!( + name = load; + config = Criterion::default().sample_size(30); + targets = bench_imbalance, bench_spawn_many +); +criterion_main!(fair, load); diff --git a/components/batch-system/benches/router.rs b/components/batch-system/benches/router.rs new file mode 100644 index 00000000000..03c01e0dd58 --- /dev/null +++ b/components/batch-system/benches/router.rs @@ -0,0 +1,24 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use batch_system::test_runner::*; +use batch_system::*; +use criterion::*; + +fn bench_send(c: &mut Criterion) { + let (control_tx, control_fsm) = Runner::new(100000); + let (router, mut system) = batch_system::create_system(2, 2, control_tx, control_fsm); + system.spawn("test".to_owned(), Builder::new()); + let (normal_tx, normal_fsm) = Runner::new(100000); + let normal_box = BasicMailbox::new(normal_tx, normal_fsm); + router.register(1, normal_box); + + c.bench_function("router::send", |b| { + b.iter(|| { + router.send(1, Message::Loop(0)).unwrap(); + }) + }); + system.shutdown(); +} + +criterion_group!(benches, bench_send); +criterion_main!(benches); diff --git a/src/raftstore/store/fsm/batch.rs b/components/batch-system/src/batch.rs similarity index 68% rename from src/raftstore/store/fsm/batch.rs rename to components/batch-system/src/batch.rs index 6d4041b156c..b185462ccd3 100644 --- a/src/raftstore/store/fsm/batch.rs +++ b/components/batch-system/src/batch.rs @@ -1,50 +1,18 @@ -// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0. +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. //! This is the core implementation of a batch system. Generally there will be two //! different kind of FSMs in TiKV's FSM system. One is normal FSM, which usually //! represents a peer, the other is control FSM, which usually represents something //! that controls how the former is created or metrics are collected. -use super::router::{BasicMailbox, Router}; +use crate::fsm::{Fsm, FsmScheduler}; +use crate::mailbox::BasicMailbox; +use crate::router::Router; use crossbeam::channel::{self, SendError, TryRecvError}; use std::borrow::Cow; use std::thread::{self, JoinHandle}; use tikv_util::mpsc; -/// `FsmScheduler` schedules `Fsm` for later handles. -pub trait FsmScheduler { - type Fsm: Fsm; - - /// Schedule a Fsm for later handles. - fn schedule(&self, fsm: Box); - /// Shutdown the scheduler, which indicates that resources like - /// background thread pool should be released. - fn shutdown(&self); -} - -/// A Fsm is a finite state machine. It should be able to be notified for -/// updating internal state according to incoming messages. -pub trait Fsm { - type Message: Send; - - fn is_stopped(&self) -> bool; - - /// Set a mailbox to Fsm, which should be used to send message to itself. - fn set_mailbox(&mut self, _mailbox: Cow<'_, BasicMailbox>) - where - Self: Sized, - { - } - /// Take the mailbox from Fsm. Implementation should ensure there will be - /// no reference to mailbox after calling this method. - fn take_mailbox(&mut self) -> Option> - where - Self: Sized, - { - None - } -} - /// A unify type for FSMs so that they can be sent to channel easily. enum FsmTypes { Normal(Box), @@ -119,6 +87,7 @@ impl FsmScheduler for ControlScheduler { #[allow(clippy::vec_box)] pub struct Batch { normals: Vec>, + counters: Vec, control: Option>, } @@ -127,6 +96,7 @@ impl Batch { pub fn with_capacity(cap: usize) -> Batch { Batch { normals: Vec::with_capacity(cap), + counters: Vec::with_capacity(cap), control: None, } } @@ -137,7 +107,10 @@ impl Batch { fn push(&mut self, fsm: FsmTypes) -> bool { match fsm { - FsmTypes::Normal(n) => self.normals.push(n), + FsmTypes::Normal(n) => { + self.normals.push(n); + self.counters.push(0); + } FsmTypes::Control(c) => { assert!(self.control.is_none()); self.control = Some(c); @@ -158,6 +131,7 @@ impl Batch { fn clear(&mut self) { self.normals.clear(); + self.counters.clear(); self.control.take(); } @@ -166,21 +140,20 @@ impl Batch { /// Only when channel length is larger than `checked_len` will trigger /// further notification. This function may fail if channel length is /// larger than the given value before FSM is released. - pub fn release(&mut self, index: usize, checked_len: usize) -> bool { + pub fn release(&mut self, index: usize, checked_len: usize) { let mut fsm = self.normals.swap_remove(index); let mailbox = fsm.take_mailbox().unwrap(); mailbox.release(fsm); if mailbox.len() == checked_len { - true + self.counters.swap_remove(index); } else { match mailbox.take_fsm() { - None => true, + None => (), Some(mut s) => { s.set_mailbox(Cow::Owned(mailbox)); let last_index = self.normals.len(); self.normals.push(s); self.normals.swap(index, last_index); - false } } } @@ -191,21 +164,27 @@ impl Batch { /// This method should only be called when the FSM is stopped. /// If there are still messages in channel, the FSM is untouched and /// the function will return false to let caller to keep polling. - pub fn remove(&mut self, index: usize) -> bool { + pub fn remove(&mut self, index: usize) { let mut fsm = self.normals.swap_remove(index); let mailbox = fsm.take_mailbox().unwrap(); if mailbox.is_empty() { mailbox.release(fsm); - true + self.counters.swap_remove(index); } else { fsm.set_mailbox(Cow::Owned(mailbox)); let last_index = self.normals.len(); self.normals.push(fsm); self.normals.swap(index, last_index); - false } } + /// Schedule the normal FSM located at `index`. + pub fn reschedule(&mut self, router: &BatchRouter, index: usize) { + let fsm = self.normals.swap_remove(index); + self.counters.swap_remove(index); + router.normal_scheduler.schedule(fsm); + } + /// Same as `release`, but working on control FSM. pub fn release_control(&mut self, control_box: &BasicMailbox, checked_len: usize) -> bool { let s = self.control.take().unwrap(); @@ -281,6 +260,12 @@ struct Poller { max_batch_size: usize, } +enum ReschedulePolicy { + Release(usize), + Remove, + Schedule, +} + impl> Poller { fn fetch_batch(&mut self, batch: &mut Batch, max_size: usize) { let curr_batch_len = batch.len(); @@ -320,10 +305,11 @@ impl> Poller { // Poll for readiness and forward to handler. Remove stale peer if necessary. fn poll(&mut self) { let mut batch = Batch::with_capacity(self.max_batch_size); - let mut exhausted_fsms = Vec::with_capacity(self.max_batch_size); + let mut reschedule_fsms = Vec::with_capacity(self.max_batch_size); self.fetch_batch(&mut batch, self.max_batch_size); while !batch.is_empty() { + let mut hot_fsm_count = 0; self.handler.begin(batch.len()); if batch.control.is_some() { let len = self.handler.handle_control(batch.control.as_mut().unwrap()); @@ -336,21 +322,34 @@ impl> Poller { if !batch.normals.is_empty() { for (i, p) in batch.normals.iter_mut().enumerate() { let len = self.handler.handle_normal(p); + batch.counters[i] += 1; if p.is_stopped() { - exhausted_fsms.push((i, None)); - } else if len.is_some() { - exhausted_fsms.push((i, len)); + reschedule_fsms.push((i, ReschedulePolicy::Remove)); + } else { + if batch.counters[i] > 3 { + hot_fsm_count += 1; + // We should only reschedule a half of the hot regions, otherwise, + // it's possible all the hot regions are fetched in a batch the + // next time. + if hot_fsm_count % 2 == 0 { + reschedule_fsms.push((i, ReschedulePolicy::Schedule)); + continue; + } + } + if let Some(l) = len { + reschedule_fsms.push((i, ReschedulePolicy::Release(l))); + } } } } self.handler.end(batch.normals_mut()); // Because release use `swap_remove` internally, so using pop here // to remove the correct FSM. - while let Some((r, mark)) = exhausted_fsms.pop() { - if let Some(m) = mark { - batch.release(r, m); - } else { - batch.remove(r); + while let Some((r, mark)) = reschedule_fsms.pop() { + match mark { + ReschedulePolicy::Release(l) => batch.release(r, l), + ReschedulePolicy::Remove => batch.remove(r), + ReschedulePolicy::Schedule => batch.reschedule(&self.router, r), } } // Fetch batch after every round is finished. It's helpful to protect regions @@ -455,154 +454,3 @@ pub fn create_system( }; (router, system) } - -#[cfg(test)] -pub mod tests { - use super::super::router::*; - use super::*; - use std::borrow::Cow; - use std::sync::{Arc, Mutex}; - use std::time::Duration; - - pub type Message = Option>; - - pub struct Runner { - is_stopped: bool, - recv: mpsc::Receiver, - mailbox: Option>, - pub sender: Option>, - } - - impl Fsm for Runner { - type Message = Message; - - fn is_stopped(&self) -> bool { - self.is_stopped - } - - fn set_mailbox(&mut self, mailbox: Cow<'_, BasicMailbox>) { - self.mailbox = Some(mailbox.into_owned()); - } - - fn take_mailbox(&mut self) -> Option> { - self.mailbox.take() - } - } - - #[allow(clippy::type_complexity)] - pub fn new_runner(cap: usize) -> (mpsc::LooseBoundedSender, Box) { - let (tx, rx) = mpsc::loose_bounded(cap); - let fsm = Runner { - is_stopped: false, - recv: rx, - mailbox: None, - sender: None, - }; - (tx, Box::new(fsm)) - } - - #[derive(Add, PartialEq, Debug, Default, AddAssign, Clone, Copy)] - struct HandleMetrics { - begin: usize, - control: usize, - normal: usize, - } - - pub struct Handler { - local: HandleMetrics, - metrics: Arc>, - } - - impl PollHandler for Handler { - fn begin(&mut self, _batch_size: usize) { - self.local.begin += 1; - } - - fn handle_control(&mut self, control: &mut Runner) -> Option { - self.local.control += 1; - while let Ok(r) = control.recv.try_recv() { - if let Some(r) = r { - r(control); - } - } - Some(0) - } - - fn handle_normal(&mut self, normal: &mut Runner) -> Option { - self.local.normal += 1; - while let Ok(r) = normal.recv.try_recv() { - if let Some(r) = r { - r(normal); - } - } - Some(0) - } - - fn end(&mut self, _normals: &mut [Box]) { - let mut c = self.metrics.lock().unwrap(); - *c += self.local; - self.local = HandleMetrics::default(); - } - } - - pub struct Builder { - metrics: Arc>, - } - - impl Builder { - pub fn new() -> Builder { - Builder { - metrics: Arc::default(), - } - } - } - - impl HandlerBuilder for Builder { - type Handler = Handler; - - fn build(&mut self) -> Handler { - Handler { - local: HandleMetrics::default(), - metrics: self.metrics.clone(), - } - } - } - - #[test] - fn test_batch() { - let (control_tx, control_fsm) = new_runner(10); - let (router, mut system) = super::create_system(2, 2, control_tx, control_fsm); - let builder = Builder::new(); - let metrics = builder.metrics.clone(); - system.spawn("test".to_owned(), builder); - let mut expected_metrics = HandleMetrics::default(); - assert_eq!(*metrics.lock().unwrap(), expected_metrics); - let (tx, rx) = mpsc::unbounded(); - let tx_ = tx.clone(); - let r = router.clone(); - router - .send_control(Some(Box::new(move |_: &mut Runner| { - let (tx, runner) = new_runner(10); - let mailbox = BasicMailbox::new(tx, runner); - tx_.send(1).unwrap(); - r.register(1, mailbox); - }))) - .unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_secs(3)), Ok(1)); - let tx_ = tx.clone(); - router - .send( - 1, - Some(Box::new(move |_: &mut Runner| { - tx_.send(2).unwrap(); - })), - ) - .unwrap(); - assert_eq!(rx.recv_timeout(Duration::from_secs(3)), Ok(2)); - system.shutdown(); - expected_metrics.control = 1; - expected_metrics.normal = 1; - expected_metrics.begin = 2; - assert_eq!(*metrics.lock().unwrap(), expected_metrics); - } -} diff --git a/components/batch-system/src/fsm.rs b/components/batch-system/src/fsm.rs new file mode 100644 index 00000000000..e6cf09a2788 --- /dev/null +++ b/components/batch-system/src/fsm.rs @@ -0,0 +1,147 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use crate::mailbox::BasicMailbox; +use std::borrow::Cow; +use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; +use std::{ptr, usize}; + +// The FSM is notified. +const NOTIFYSTATE_NOTIFIED: usize = 0; +// The FSM is idle. +const NOTIFYSTATE_IDLE: usize = 1; +// The FSM is expected to be dropped. +const NOTIFYSTATE_DROP: usize = 2; + +/// `FsmScheduler` schedules `Fsm` for later handles. +pub trait FsmScheduler { + type Fsm: Fsm; + + /// Schedule a Fsm for later handles. + fn schedule(&self, fsm: Box); + /// Shutdown the scheduler, which indicates that resources like + /// background thread pool should be released. + fn shutdown(&self); +} + +/// A Fsm is a finite state machine. It should be able to be notified for +/// updating internal state according to incoming messages. +pub trait Fsm { + type Message: Send; + + fn is_stopped(&self) -> bool; + + /// Set a mailbox to Fsm, which should be used to send message to itself. + fn set_mailbox(&mut self, _mailbox: Cow<'_, BasicMailbox>) + where + Self: Sized, + { + } + /// Take the mailbox from Fsm. Implementation should ensure there will be + /// no reference to mailbox after calling this method. + fn take_mailbox(&mut self) -> Option> + where + Self: Sized, + { + None + } +} + +pub struct FsmState { + status: AtomicUsize, + data: AtomicPtr, +} + +impl FsmState { + pub fn new(data: Box) -> FsmState { + FsmState { + status: AtomicUsize::new(NOTIFYSTATE_IDLE), + data: AtomicPtr::new(Box::into_raw(data)), + } + } + + /// Take the fsm if it's IDLE. + pub fn take_fsm(&self) -> Option> { + let previous_state = + self.status + .compare_and_swap(NOTIFYSTATE_IDLE, NOTIFYSTATE_NOTIFIED, Ordering::AcqRel); + if previous_state != NOTIFYSTATE_IDLE { + return None; + } + + let p = self.data.swap(ptr::null_mut(), Ordering::AcqRel); + if !p.is_null() { + Some(unsafe { Box::from_raw(p) }) + } else { + panic!("inconsistent status and data, something should be wrong."); + } + } + + /// Notify fsm via a `FsmScheduler`. + #[inline] + pub fn notify>( + &self, + scheduler: &S, + mailbox: Cow<'_, BasicMailbox>, + ) { + match self.take_fsm() { + None => {} + Some(mut n) => { + n.set_mailbox(mailbox); + scheduler.schedule(n); + } + } + } + + /// Put the owner back to the state. + /// + /// It's not required that all messages should be consumed before + /// releasing a fsm. However, a fsm is guaranteed to be notified only + /// when new messages arrives after it's released. + #[inline] + pub fn release(&self, fsm: Box) { + let previous = self.data.swap(Box::into_raw(fsm), Ordering::AcqRel); + let mut previous_status = NOTIFYSTATE_NOTIFIED; + if previous.is_null() { + previous_status = self.status.compare_and_swap( + NOTIFYSTATE_NOTIFIED, + NOTIFYSTATE_IDLE, + Ordering::AcqRel, + ); + match previous_status { + NOTIFYSTATE_NOTIFIED => return, + NOTIFYSTATE_DROP => { + let ptr = self.data.swap(ptr::null_mut(), Ordering::AcqRel); + unsafe { Box::from_raw(ptr) }; + return; + } + _ => {} + } + } + panic!("invalid release state: {:?} {}", previous, previous_status); + } + + /// Clear the fsm. + #[inline] + pub fn clear(&self) { + match self.status.swap(NOTIFYSTATE_DROP, Ordering::AcqRel) { + NOTIFYSTATE_NOTIFIED | NOTIFYSTATE_DROP => return, + _ => {} + } + + let ptr = self.data.swap(ptr::null_mut(), Ordering::SeqCst); + if !ptr.is_null() { + unsafe { + Box::from_raw(ptr); + } + } + } +} + +impl Drop for FsmState { + fn drop(&mut self) { + let ptr = self.data.swap(ptr::null_mut(), Ordering::SeqCst); + if !ptr.is_null() { + unsafe { Box::from_raw(ptr) }; + } + } +} diff --git a/components/batch-system/src/lib.rs b/components/batch-system/src/lib.rs new file mode 100644 index 00000000000..ff784fa7ebc --- /dev/null +++ b/components/batch-system/src/lib.rs @@ -0,0 +1,33 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +#[macro_use( + slog_kv, + slog_info, + slog_debug, + slog_warn, + slog_record, + slog_b, + slog_log, + slog_record_static +)] +extern crate slog; +#[macro_use] +extern crate slog_global; +#[macro_use] +extern crate tikv_util; +#[cfg(feature = "test-runner")] +#[macro_use] +extern crate derive_more; + +mod batch; +mod fsm; +mod mailbox; +mod router; + +#[cfg(feature = "test-runner")] +pub mod test_runner; + +pub use self::batch::{create_system, BatchRouter, BatchSystem, HandlerBuilder, PollHandler}; +pub use self::fsm::Fsm; +pub use self::mailbox::{BasicMailbox, Mailbox}; +pub use self::router::Router; diff --git a/components/batch-system/src/mailbox.rs b/components/batch-system/src/mailbox.rs new file mode 100644 index 00000000000..5da0492a6a8 --- /dev/null +++ b/components/batch-system/src/mailbox.rs @@ -0,0 +1,130 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use crate::fsm::{Fsm, FsmScheduler, FsmState}; +use crossbeam::channel::{SendError, TrySendError}; +use std::borrow::Cow; +use std::sync::Arc; +use tikv_util::mpsc; + +/// A basic mailbox. +/// +/// Every mailbox should have one and only one owner, who will receive all +/// messages sent to this mailbox. +/// +/// When a message is sent to a mailbox, its owner will be checked whether it's +/// idle. An idle owner will be scheduled via `FsmScheduler` immediately, which +/// will drive the fsm to poll for messages. +pub struct BasicMailbox { + sender: mpsc::LooseBoundedSender, + state: Arc>, +} + +impl BasicMailbox { + #[inline] + pub fn new( + sender: mpsc::LooseBoundedSender, + fsm: Box, + ) -> BasicMailbox { + BasicMailbox { + sender, + state: Arc::new(FsmState::new(fsm)), + } + } + + pub(crate) fn is_connected(&self) -> bool { + self.sender.is_sender_connected() + } + + pub(crate) fn release(&self, fsm: Box) { + self.state.release(fsm) + } + + pub(crate) fn take_fsm(&self) -> Option> { + self.state.take_fsm() + } + + #[inline] + pub fn len(&self) -> usize { + self.sender.len() + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.sender.is_empty() + } + + /// Force sending a message despite the capacity limit on channel. + #[inline] + pub fn force_send>( + &self, + msg: Owner::Message, + scheduler: &S, + ) -> Result<(), SendError> { + self.sender.force_send(msg)?; + self.state.notify(scheduler, Cow::Borrowed(self)); + Ok(()) + } + + /// Try to send a message to the mailbox. + /// + /// If there are too many pending messages, function may fail. + #[inline] + pub fn try_send>( + &self, + msg: Owner::Message, + scheduler: &S, + ) -> Result<(), TrySendError> { + self.sender.try_send(msg)?; + self.state.notify(scheduler, Cow::Borrowed(self)); + Ok(()) + } + + /// Close the mailbox explicitly. + #[inline] + pub(crate) fn close(&self) { + self.sender.close_sender(); + self.state.clear(); + } +} + +impl Clone for BasicMailbox { + #[inline] + fn clone(&self) -> BasicMailbox { + BasicMailbox { + sender: self.sender.clone(), + state: self.state.clone(), + } + } +} + +/// A more high level mailbox. +pub struct Mailbox +where + Owner: Fsm, + Scheduler: FsmScheduler, +{ + mailbox: BasicMailbox, + scheduler: Scheduler, +} + +impl Mailbox +where + Owner: Fsm, + Scheduler: FsmScheduler, +{ + pub fn new(mailbox: BasicMailbox, scheduler: Scheduler) -> Mailbox { + Mailbox { mailbox, scheduler } + } + + /// Force sending a message despite channel capacity limit. + #[inline] + pub fn force_send(&self, msg: Owner::Message) -> Result<(), SendError> { + self.mailbox.force_send(msg, &self.scheduler) + } + + /// Try to send a message. + #[inline] + pub fn try_send(&self, msg: Owner::Message) -> Result<(), TrySendError> { + self.mailbox.try_send(msg, &self.scheduler) + } +} diff --git a/components/batch-system/src/router.rs b/components/batch-system/src/router.rs new file mode 100644 index 00000000000..18059654380 --- /dev/null +++ b/components/batch-system/src/router.rs @@ -0,0 +1,267 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use crate::fsm::{Fsm, FsmScheduler}; +use crate::mailbox::{BasicMailbox, Mailbox}; +use crossbeam::channel::{SendError, TrySendError}; +use std::cell::Cell; +use std::sync::{Arc, Mutex}; +use tikv_util::collections::HashMap; +use tikv_util::Either; + +enum CheckDoResult { + NotExist, + Invalid, + Valid(T), +} + +/// Router route messages to its target mailbox. +/// +/// Every fsm has a mailbox, hence it's necessary to have an address book +/// that can deliver messages to specified fsm, which is exact router. +/// +/// In our abstract model, every batch system has two different kind of +/// fsms. First is normal fsm, which does the common work like peers in a +/// raftstore model or apply delegate in apply model. Second is control fsm, +/// which does some work that requires a global view of resources or creates +/// missing fsm for specified address. Normal fsm and control fsm can have +/// different scheduler, but this is not required. +pub struct Router { + normals: Arc>>>, + caches: Cell>>, + pub(super) control_box: BasicMailbox, + // TODO: These two schedulers should be unified as single one. However + // it's not possible to write FsmScheduler + FsmScheduler + // for now. + pub(crate) normal_scheduler: Ns, + control_scheduler: Cs, +} + +impl Router +where + N: Fsm, + C: Fsm, + Ns: FsmScheduler + Clone, + Cs: FsmScheduler + Clone, +{ + pub(super) fn new( + control_box: BasicMailbox, + normal_scheduler: Ns, + control_scheduler: Cs, + ) -> Router { + Router { + normals: Arc::default(), + caches: Cell::default(), + control_box, + normal_scheduler, + control_scheduler, + } + } + + /// A helper function that tries to unify a common access pattern to + /// mailbox. + /// + /// Generally, when sending a message to a mailbox, cache should be + /// check first, if not found, lock should be acquired. + /// + /// Returns None means there is no mailbox inside the normal registry. + /// Some(None) means there is expected mailbox inside the normal registry + /// but it returns None after apply the given function. Some(Some) means + /// the given function returns Some and cache is updated if it's invalid. + #[inline] + fn check_do(&self, addr: u64, mut f: F) -> CheckDoResult + where + F: FnMut(&BasicMailbox) -> Option, + { + let caches = unsafe { &mut *self.caches.as_ptr() }; + let mut connected = true; + if let Some(mailbox) = caches.get(&addr) { + match f(mailbox) { + Some(r) => return CheckDoResult::Valid(r), + None => { + connected = false; + } + } + } + + let mailbox = { + let mut boxes = self.normals.lock().unwrap(); + match boxes.get_mut(&addr) { + Some(mailbox) => mailbox.clone(), + None => { + drop(boxes); + if !connected { + caches.remove(&addr); + } + return CheckDoResult::NotExist; + } + } + }; + + let res = f(&mailbox); + match res { + Some(r) => { + caches.insert(addr, mailbox); + CheckDoResult::Valid(r) + } + None => { + if !connected { + caches.remove(&addr); + } + CheckDoResult::Invalid + } + } + } + + /// Register a mailbox with given address. + pub fn register(&self, addr: u64, mailbox: BasicMailbox) { + let mut normals = self.normals.lock().unwrap(); + if let Some(mailbox) = normals.insert(addr, mailbox) { + mailbox.close(); + } + } + + pub fn register_all(&self, mailboxes: Vec<(u64, BasicMailbox)>) { + let mut normals = self.normals.lock().unwrap(); + normals.reserve(mailboxes.len()); + for (addr, mailbox) in mailboxes { + if let Some(m) = normals.insert(addr, mailbox) { + m.close(); + } + } + } + + /// Get the mailbox of specified address. + pub fn mailbox(&self, addr: u64) -> Option> { + let res = self.check_do(addr, |mailbox| { + if mailbox.is_connected() { + Some(Mailbox::new(mailbox.clone(), self.normal_scheduler.clone())) + } else { + None + } + }); + match res { + CheckDoResult::Valid(r) => Some(r), + _ => None, + } + } + + /// Get the mailbox of control fsm. + pub fn control_mailbox(&self) -> Mailbox { + Mailbox::new(self.control_box.clone(), self.control_scheduler.clone()) + } + + /// Try to send a message to specified address. + /// + /// If Either::Left is returned, then the message is sent. Otherwise, + /// it indicates mailbox is not found. + #[inline] + pub fn try_send( + &self, + addr: u64, + msg: N::Message, + ) -> Either>, N::Message> { + let mut msg = Some(msg); + let res = self.check_do(addr, |mailbox| { + let m = msg.take().unwrap(); + match mailbox.try_send(m, &self.normal_scheduler) { + Ok(()) => Some(Ok(())), + r @ Err(TrySendError::Full(_)) => { + // TODO: report channel full + Some(r) + } + Err(TrySendError::Disconnected(m)) => { + msg = Some(m); + None + } + } + }); + match res { + CheckDoResult::Valid(r) => Either::Left(r), + CheckDoResult::Invalid => Either::Left(Err(TrySendError::Disconnected(msg.unwrap()))), + CheckDoResult::NotExist => Either::Right(msg.unwrap()), + } + } + + /// Send the message to specified address. + #[inline] + pub fn send(&self, addr: u64, msg: N::Message) -> Result<(), TrySendError> { + match self.try_send(addr, msg) { + Either::Left(res) => res, + Either::Right(m) => Err(TrySendError::Disconnected(m)), + } + } + + /// Force sending message to specified address despite the capacity + /// limit of mailbox. + #[inline] + pub fn force_send(&self, addr: u64, msg: N::Message) -> Result<(), SendError> { + match self.send(addr, msg) { + Ok(()) => Ok(()), + Err(TrySendError::Full(m)) => { + let caches = unsafe { &mut *self.caches.as_ptr() }; + caches[&addr].force_send(m, &self.normal_scheduler) + } + Err(TrySendError::Disconnected(m)) => Err(SendError(m)), + } + } + + /// Force sending message to control fsm. + #[inline] + pub fn send_control(&self, msg: C::Message) -> Result<(), TrySendError> { + match self.control_box.try_send(msg, &self.control_scheduler) { + Ok(()) => Ok(()), + r @ Err(TrySendError::Full(_)) => { + // TODO: record metrics. + r + } + r => r, + } + } + + /// Try to notify all normal fsm a message. + pub fn broadcast_normal(&self, mut msg_gen: impl FnMut() -> N::Message) { + let mailboxes = self.normals.lock().unwrap(); + for mailbox in mailboxes.values() { + let _ = mailbox.force_send(msg_gen(), &self.normal_scheduler); + } + } + + /// Try to notify all fsm that the cluster is being shutdown. + pub fn broadcast_shutdown(&self) { + info!("broadcasting shutdown"); + unsafe { &mut *self.caches.as_ptr() }.clear(); + let mut mailboxes = self.normals.lock().unwrap(); + for (addr, mailbox) in mailboxes.drain() { + debug!("[region {}] shutdown mailbox", addr); + mailbox.close(); + } + self.control_box.close(); + self.normal_scheduler.shutdown(); + self.control_scheduler.shutdown(); + } + + /// Close the mailbox of address. + pub fn close(&self, addr: u64) { + info!("[region {}] shutdown mailbox", addr); + unsafe { &mut *self.caches.as_ptr() }.remove(&addr); + let mut mailboxes = self.normals.lock().unwrap(); + if let Some(mb) = mailboxes.remove(&addr) { + mb.close(); + } + } +} + +impl Clone for Router { + fn clone(&self) -> Router { + Router { + normals: self.normals.clone(), + caches: Cell::default(), + control_box: self.control_box.clone(), + // These two schedulers should be unified as single one. However + // it's not possible to write FsmScheduler + FsmScheduler + // for now. + normal_scheduler: self.normal_scheduler.clone(), + control_scheduler: self.control_scheduler.clone(), + } + } +} diff --git a/components/batch-system/src/test_runner.rs b/components/batch-system/src/test_runner.rs new file mode 100644 index 00000000000..d6a7609f9ab --- /dev/null +++ b/components/batch-system/src/test_runner.rs @@ -0,0 +1,133 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +//! A sample Handler for test and micro-benchmark purpose. + +use crate::*; +use std::borrow::Cow; +use std::sync::{Arc, Mutex}; +use tikv_util::mpsc; + +/// Message `Runner` can accepts. +pub enum Message { + /// `Runner` will do simple calculation for the given times. + Loop(usize), + /// `Runner` will call the callback directly. + Callback(Box), +} + +/// A simple runner used for benchmarking only. +pub struct Runner { + is_stopped: bool, + recv: mpsc::Receiver, + mailbox: Option>, + pub sender: Option>, + /// Result of the calculation triggered by `Message::Loop`. + /// Stores it inside `Runner` to avoid accidental optimization. + res: usize, +} + +impl Fsm for Runner { + type Message = Message; + + fn is_stopped(&self) -> bool { + self.is_stopped + } + + fn set_mailbox(&mut self, mailbox: Cow<'_, BasicMailbox>) { + self.mailbox = Some(mailbox.into_owned()); + } + + fn take_mailbox(&mut self) -> Option> { + self.mailbox.take() + } +} + +impl Runner { + pub fn new(cap: usize) -> (mpsc::LooseBoundedSender, Box) { + let (tx, rx) = mpsc::loose_bounded(cap); + let fsm = Box::new(Runner { + is_stopped: false, + recv: rx, + mailbox: None, + sender: None, + res: 0, + }); + (tx, fsm) + } +} + +#[derive(Add, PartialEq, Debug, Default, AddAssign, Clone, Copy)] +pub struct HandleMetrics { + pub begin: usize, + pub control: usize, + pub normal: usize, +} + +pub struct Handler { + local: HandleMetrics, + metrics: Arc>, +} + +impl Handler { + fn handle(&mut self, r: &mut Runner) -> Option { + for _ in 0..16 { + match r.recv.try_recv() { + Ok(Message::Loop(count)) => { + // Some calculation to represent a CPU consuming work + for _ in 0..count { + r.res *= count; + r.res %= count + 1; + } + } + Ok(Message::Callback(cb)) => cb(r), + Err(_) => break, + } + } + Some(0) + } +} + +impl PollHandler for Handler { + fn begin(&mut self, _batch_size: usize) { + self.local.begin += 1; + } + + fn handle_control(&mut self, control: &mut Runner) -> Option { + self.local.control += 1; + self.handle(control) + } + + fn handle_normal(&mut self, normal: &mut Runner) -> Option { + self.local.normal += 1; + self.handle(normal) + } + + fn end(&mut self, _normals: &mut [Box]) { + let mut c = self.metrics.lock().unwrap(); + *c += self.local; + self.local = HandleMetrics::default(); + } +} + +pub struct Builder { + pub metrics: Arc>, +} + +impl Builder { + pub fn new() -> Builder { + Builder { + metrics: Arc::default(), + } + } +} + +impl HandlerBuilder for Builder { + type Handler = Handler; + + fn build(&mut self) -> Handler { + Handler { + local: HandleMetrics::default(), + metrics: self.metrics.clone(), + } + } +} diff --git a/components/batch-system/tests/cases/batch.rs b/components/batch-system/tests/cases/batch.rs new file mode 100644 index 00000000000..71569640f62 --- /dev/null +++ b/components/batch-system/tests/cases/batch.rs @@ -0,0 +1,43 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use batch_system::test_runner::*; +use batch_system::*; +use std::time::Duration; +use tikv_util::mpsc; + +#[test] +fn test_batch() { + let (control_tx, control_fsm) = Runner::new(10); + let (router, mut system) = batch_system::create_system(2, 2, control_tx, control_fsm); + let builder = Builder::new(); + let metrics = builder.metrics.clone(); + system.spawn("test".to_owned(), builder); + let mut expected_metrics = HandleMetrics::default(); + assert_eq!(*metrics.lock().unwrap(), expected_metrics); + let (tx, rx) = mpsc::unbounded(); + let tx_ = tx.clone(); + let r = router.clone(); + router + .send_control(Message::Callback(Box::new(move |_: &mut Runner| { + let (tx, runner) = Runner::new(10); + let mailbox = BasicMailbox::new(tx, runner); + r.register(1, mailbox); + tx_.send(1).unwrap(); + }))) + .unwrap(); + assert_eq!(rx.recv_timeout(Duration::from_secs(3)), Ok(1)); + router + .send( + 1, + Message::Callback(Box::new(move |_: &mut Runner| { + tx.send(2).unwrap(); + })), + ) + .unwrap(); + assert_eq!(rx.recv_timeout(Duration::from_secs(3)), Ok(2)); + system.shutdown(); + expected_metrics.control = 1; + expected_metrics.normal = 1; + expected_metrics.begin = 2; + assert_eq!(*metrics.lock().unwrap(), expected_metrics); +} diff --git a/components/batch-system/tests/cases/mod.rs b/components/batch-system/tests/cases/mod.rs new file mode 100644 index 00000000000..22eda9f01ab --- /dev/null +++ b/components/batch-system/tests/cases/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +mod batch; +mod router; diff --git a/components/batch-system/tests/cases/router.rs b/components/batch-system/tests/cases/router.rs new file mode 100644 index 00000000000..41080f415e2 --- /dev/null +++ b/components/batch-system/tests/cases/router.rs @@ -0,0 +1,123 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use batch_system::test_runner::*; +use batch_system::*; +use crossbeam::channel::*; +use std::sync::atomic::*; +use std::sync::Arc; +use std::time::Duration; +use tikv_util::mpsc; + +fn counter_closure(counter: &Arc) -> Message { + let c = counter.clone(); + Message::Callback(Box::new(move |_: &mut Runner| { + c.fetch_add(1, Ordering::SeqCst); + })) +} + +fn noop() -> Message { + Message::Callback(Box::new(|_| ())) +} + +fn unreachable() -> Message { + Message::Callback(Box::new(|_: &mut Runner| unreachable!())) +} + +#[test] +fn test_basic() { + let (control_tx, mut control_fsm) = Runner::new(10); + let (control_drop_tx, control_drop_rx) = mpsc::unbounded(); + control_fsm.sender = Some(control_drop_tx); + let (router, mut system) = batch_system::create_system(2, 2, control_tx, control_fsm); + let builder = Builder::new(); + system.spawn("test".to_owned(), builder); + + // Missing mailbox should report error. + match router.force_send(1, unreachable()) { + Err(SendError(_)) => (), + Ok(_) => panic!("send should fail"), + } + match router.send(1, unreachable()) { + Err(TrySendError::Disconnected(_)) => (), + Ok(_) => panic!("send should fail"), + Err(TrySendError::Full(_)) => panic!("expect disconnected."), + } + + let (tx, rx) = mpsc::unbounded(); + let router_ = router.clone(); + // Control mailbox should be connected. + router + .send_control(Message::Callback(Box::new(move |_: &mut Runner| { + let (sender, mut runner) = Runner::new(10); + let (tx1, rx1) = mpsc::unbounded(); + runner.sender = Some(tx1); + let mailbox = BasicMailbox::new(sender, runner); + router_.register(1, mailbox); + tx.send(rx1).unwrap(); + }))) + .unwrap(); + let runner_drop_rx = rx.recv_timeout(Duration::from_secs(3)).unwrap(); + + // Registered mailbox should be connected. + router.force_send(1, noop()).unwrap(); + router.send(1, noop()).unwrap(); + + // Send should respect capacity limit, while force_send not. + let (tx, rx) = mpsc::unbounded(); + router + .send( + 1, + Message::Callback(Box::new(move |_: &mut Runner| { + rx.recv_timeout(Duration::from_secs(100)).unwrap(); + })), + ) + .unwrap(); + let counter = Arc::new(AtomicUsize::new(0)); + let sent_cnt = (0..) + .take_while(|_| router.send(1, counter_closure(&counter)).is_ok()) + .count(); + match router.send(1, counter_closure(&counter)) { + Err(TrySendError::Full(_)) => {} + Err(TrySendError::Disconnected(_)) => panic!("mailbox should still be connected."), + Ok(_) => panic!("send should fail"), + } + router.force_send(1, counter_closure(&counter)).unwrap(); + tx.send(1).unwrap(); + // Flush. + let (tx, rx) = mpsc::unbounded(); + router + .force_send( + 1, + Message::Callback(Box::new(move |_: &mut Runner| { + tx.send(1).unwrap(); + })), + ) + .unwrap(); + rx.recv_timeout(Duration::from_secs(100)).unwrap(); + + let c = counter.load(Ordering::SeqCst); + assert_eq!(c, sent_cnt + 1); + + // close should release resources. + assert_eq!(runner_drop_rx.try_recv(), Err(TryRecvError::Empty)); + router.close(1); + assert_eq!( + runner_drop_rx.recv_timeout(Duration::from_secs(3)), + Err(RecvTimeoutError::Disconnected) + ); + match router.send(1, unreachable()) { + Err(TrySendError::Disconnected(_)) => (), + Ok(_) => panic!("send should fail."), + Err(TrySendError::Full(_)) => panic!("sender should be closed"), + } + match router.force_send(1, unreachable()) { + Err(SendError(_)) => (), + Ok(_) => panic!("send should fail."), + } + assert_eq!(control_drop_rx.try_recv(), Err(TryRecvError::Empty)); + system.shutdown(); + assert_eq!( + control_drop_rx.recv_timeout(Duration::from_secs(3)), + Err(RecvTimeoutError::Disconnected) + ); +} diff --git a/components/engine/Cargo.toml b/components/engine/Cargo.toml index 92b33cfe40c..477a809bd18 100644 --- a/components/engine/Cargo.toml +++ b/components/engine/Cargo.toml @@ -32,7 +32,7 @@ default-features = false features = ["nightly"] [dependencies.engine_rocksdb] -git = "https://github.com/pingcap/rust-rocksdb.git" +git = "https://github.com/tikv/rust-rocksdb.git" package = "rocksdb" branch = "tikv-3.x" diff --git a/components/external_storage/Cargo.toml b/components/external_storage/Cargo.toml index e9fb72752d4..7cba9d1c6f5 100644 --- a/components/external_storage/Cargo.toml +++ b/components/external_storage/Cargo.toml @@ -5,14 +5,29 @@ edition = "2018" publish = false [dependencies] +futures = "0.3" futures-io = "0.3" -futures-util = { version = "0.3", default-features = false, features = ["io"] } +futures-util = { version = "0.3", default-features = false, features = ["io", "io-compat"] } futures-executor = "0.3" +futures01 = { version = "0.1.29", package = "futures" } +rand = "0.7" slog = { version = "2.3", features = ["max_level_trace", "release_max_level_debug"] } # better to not use slog-global, but pass in the logger slog-global = { version = "0.1", git = "https://github.com/breeswish/slog-global.git", rev = "91904ade" } -tempfile = "3.0" -rand = "0.6.5" -url = "2.0" tikv_alloc = { path = "../tikv_alloc", default-features = false } +url = "2.0" kvproto = { git = "https://github.com/pingcap/kvproto.git", branch = "release-3.1", default-features = false } +rusoto_core = { version = "0.42.0" } +rusoto_s3 = { version = "0.42.0" } +rusoto_credential = { version = "0.42.0" } +tokio = { version = "0.1.22", default-features = false, features = ["codec"] } + +[features] +prost-codec = ["kvproto/prost-codec"] +protobuf-codec = ["kvproto/protobuf-codec"] + +[dev-dependencies] +rusoto_mock = "0.42.0" +tempfile = "3.0" +clap = { version = "2.32", features = ["yaml"] } +rust-ini = "0.14.0" diff --git a/components/external_storage/examples/scli.rs b/components/external_storage/examples/scli.rs new file mode 100644 index 00000000000..61fae36fc08 --- /dev/null +++ b/components/external_storage/examples/scli.rs @@ -0,0 +1,161 @@ +use std::fs::File; +use std::io::{Error, ErrorKind, Result}; +use std::path::Path; +use std::sync::Arc; + +use clap::{App, ArgMatches}; +use external_storage::{ + create_storage, make_local_backend, make_noop_backend, make_s3_backend, ExternalStorage, +}; +use futures::executor::block_on; +use futures_util::io::{copy, AllowStdIo}; +use ini::ini::Ini; +use kvproto::backup::S3; + +static CMD: &str = r#" +name: storagecli +version: "0.1" +about: an example using storage to save and load a file + +settings: + - ArgRequiredElseHelp + - SubcommandRequiredElseHelp + +args: + - storage: + help: storage backend + short: s + long: storage + takes_value: true + case_insensitive: true + possible_values: ["noop", "local", "s3"] + required: true + - file: + help: local file to load from or save to + short: f + long: file + takes_value: true + required: true + - name: + help: remote name of the file to load from or save to + short: n + long: name + takes_value: true + required: true + - path: + help: path to use for local storage + short: p + long: path + takes_value: true + - credential_file: + help: credential file path. For S3, use ~/.aws/credentials + short: c + long: credential_file + takes_value: true + - region: + help: remote region + short: r + long: region + takes_value: true + - bucket: + help: remote bucket name + short: b + long: bucket + takes_value: true + - prefix: + help: remote path prefix + short: x + long: prefix + takes_value: true + +subcommands: + - save: + about: save file to storage + - load: + about: load file from storage +"#; + +fn create_s3_storage(matches: &ArgMatches) -> Result> { + let mut config = S3::default(); + match matches.value_of("credential_file") { + Some(credential_file) => { + let ini = Ini::load_from_file(credential_file).map_err(|e| { + Error::new( + ErrorKind::Other, + format!("Failed to parse credential file as ini: {}", e), + ) + })?; + let props = ini + .section(Some("default")) + .ok_or_else(|| Error::new(ErrorKind::Other, "fail to parse section"))?; + config.access_key = props + .get("aws_access_key_id") + .ok_or_else(|| Error::new(ErrorKind::Other, "fail to parse credential"))? + .clone(); + config.secret_access_key = props + .get("aws_secret_access_key") + .ok_or_else(|| Error::new(ErrorKind::Other, "fail to parse credential"))? + .clone(); + } + _ => return Err(Error::new(ErrorKind::Other, "missing credential_file")), + } + if let Some(region) = matches.value_of("region") { + config.region = region.to_string(); + } else { + return Err(Error::new(ErrorKind::Other, "missing region")); + } + if let Some(bucket) = matches.value_of("bucket") { + config.bucket = bucket.to_string(); + } else { + return Err(Error::new(ErrorKind::Other, "missing bucket")); + } + if let Some(prefix) = matches.value_of("prefix") { + config.prefix = prefix.to_string(); + } + create_storage(&make_s3_backend(config)) +} + +fn process() -> Result<()> { + let yaml = &clap::YamlLoader::load_from_str(CMD).unwrap()[0]; + let app = App::from_yaml(yaml); + let matches = app.get_matches(); + + let storage = match matches.value_of("storage") { + Some("noop") => create_storage(&make_noop_backend())?, + Some("local") => match matches.value_of("path") { + Some(path) => create_storage(&make_local_backend(Path::new(&path)))?, + _ => return Err(Error::new(ErrorKind::Other, "missing path")), + }, + Some("s3") => create_s3_storage(&matches)?, + _ => return Err(Error::new(ErrorKind::Other, "storage unrecognized")), + }; + + let file_path = matches.value_of("file").unwrap(); + let name = matches.value_of("name").unwrap(); + match matches.subcommand_name() { + Some("save") => { + let file = File::open(file_path)?; + let file_size = file.metadata()?.len(); + storage.write(name, Box::new(AllowStdIo::new(file)), file_size)?; + } + Some("load") => { + let mut file = AllowStdIo::new(File::create(file_path)?); + let reader = storage.read(name)?; + block_on(copy(reader, &mut file))?; + } + _ => return Err(Error::new(ErrorKind::Other, "subcommand unrecognized")), + } + + Ok(()) +} + +fn main() { + match process() { + Ok(()) => { + println!("done"); + } + Err(e) => { + println!("error: {}", e); + } + } +} diff --git a/components/external_storage/src/lib.rs b/components/external_storage/src/lib.rs index 7fd7e48278d..6ecfc0dcfd2 100644 --- a/components/external_storage/src/lib.rs +++ b/components/external_storage/src/lib.rs @@ -29,12 +29,14 @@ use std::sync::Arc; use futures_io::AsyncRead; use kvproto::backup::StorageBackend_oneof_backend as Backend; -use kvproto::backup::{Noop, StorageBackend}; +use kvproto::backup::{Noop, StorageBackend, S3}; mod local; pub use local::LocalStorage; mod noop; pub use noop::NoopStorage; +mod s3; +pub use s3::S3Storage; /// Create a new storage from the given storage backend description. pub fn create_storage(backend: &StorageBackend) -> io::Result> { @@ -43,7 +45,8 @@ pub fn create_storage(backend: &StorageBackend) -> io::Result Ok(Arc::new(NoopStorage::new()) as _), + Some(Backend::noop(_)) => Ok(Arc::new(NoopStorage::default()) as _), + Some(Backend::s3(config)) => S3Storage::new(config).map(|s| Arc::new(s) as _), _ => { let u = url_of_backend(backend); error!("unknown storage"; "scheme" => u.scheme()); @@ -95,18 +98,35 @@ pub fn make_noop_backend() -> StorageBackend { backend } +// Creates a S3 `StorageBackend` +pub fn make_s3_backend(config: S3) -> StorageBackend { + let mut backend = StorageBackend::default(); + backend.set_s3(config); + backend +} + /// An abstraction of an external storage. // TODO: these should all be returning a future (i.e. async fn). pub trait ExternalStorage: Sync + Send + 'static { /// Write all contents of the read to the given path. - fn write(&self, name: &str, reader: &mut (dyn AsyncRead + Unpin)) -> io::Result<()>; + fn write( + &self, + name: &str, + reader: Box, + content_length: u64, + ) -> io::Result<()>; /// Read all contents of the given path. fn read(&self, name: &str) -> io::Result>; } impl ExternalStorage for Arc { - fn write(&self, name: &str, reader: &mut (dyn AsyncRead + Unpin)) -> io::Result<()> { - (**self).write(name, reader) + fn write( + &self, + name: &str, + reader: Box, + content_length: u64, + ) -> io::Result<()> { + (**self).write(name, reader, content_length) } fn read(&self, name: &str) -> io::Result> { (**self).read(name) diff --git a/components/external_storage/src/local.rs b/components/external_storage/src/local.rs index d9af8bd6390..90398805618 100644 --- a/components/external_storage/src/local.rs +++ b/components/external_storage/src/local.rs @@ -55,7 +55,12 @@ impl LocalStorage { } impl ExternalStorage for LocalStorage { - fn write(&self, name: &str, reader: &mut (dyn AsyncRead + Unpin)) -> io::Result<()> { + fn write( + &self, + name: &str, + reader: Box, + _content_length: u64, + ) -> io::Result<()> { // Storage does not support dir, // "a/a.sst", "/" and "" will return an error. if Path::new(name) @@ -119,19 +124,20 @@ mod tests { .starts_with(LOCAL_STORAGE_TMP_FILE_SUFFIX)); // Test save_file - let magic_contents = b"5678".to_vec(); - ls.write("a.log", &mut magic_contents.clone().as_slice()) + let magic_contents: &[u8] = b"5678"; + let content_length = magic_contents.len() as u64; + ls.write("a.log", Box::new(magic_contents), content_length) .unwrap(); assert_eq!(fs::read(path.join("a.log")).unwrap(), magic_contents); // Names contain parent is not allowed. - ls.write("a/a.log", &mut magic_contents.clone().as_slice()) + ls.write("a/a.log", Box::new(magic_contents), content_length) .unwrap_err(); // Empty name is not allowed. - ls.write("", &mut magic_contents.clone().as_slice()) + ls.write("", Box::new(magic_contents), content_length) .unwrap_err(); // root is not allowed. - ls.write("/", &mut magic_contents.clone().as_slice()) + ls.write("/", Box::new(magic_contents), content_length) .unwrap_err(); } } diff --git a/components/external_storage/src/noop.rs b/components/external_storage/src/noop.rs index 64bb4fd0277..fafe149c445 100644 --- a/components/external_storage/src/noop.rs +++ b/components/external_storage/src/noop.rs @@ -11,19 +11,16 @@ use super::ExternalStorage; /// A storage saves files into void. /// It is mainly for test use. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct NoopStorage {} -impl NoopStorage { - /// Create a new noop storage in the given path. - pub fn new() -> NoopStorage { - info!("create noop storage"); - NoopStorage {} - } -} - impl ExternalStorage for NoopStorage { - fn write(&self, _name: &str, reader: &mut (dyn AsyncRead + Unpin)) -> io::Result<()> { + fn write( + &self, + _name: &str, + reader: Box, + _content_length: u64, + ) -> io::Result<()> { // we must still process the entire reader to run the SHA-256 hasher. block_on(copy(reader, &mut AllowStdIo::new(io::sink()))).map(drop) } @@ -40,11 +37,16 @@ mod tests { #[test] fn test_noop_storage() { - let noop = NoopStorage::new(); + let noop = NoopStorage::default(); // Test save_file - let mut magic_contents: &[u8] = b"5678"; - noop.write("a.log", &mut magic_contents).unwrap(); + let magic_contents: &[u8] = b"5678"; + noop.write( + "a.log", + Box::new(magic_contents), + magic_contents.len() as u64, + ) + .unwrap(); let mut reader = noop.read("a.log").unwrap(); let mut buf = vec![]; block_on(reader.read_to_end(&mut buf)).unwrap(); diff --git a/components/external_storage/src/s3.rs b/components/external_storage/src/s3.rs new file mode 100644 index 00000000000..6c3beba8fd6 --- /dev/null +++ b/components/external_storage/src/s3.rs @@ -0,0 +1,212 @@ +// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0. + +use std::io::{Error, ErrorKind, Result}; + +use futures01::stream::Stream; +use futures_io::AsyncRead; +use futures_util::compat::AsyncRead01CompatExt; +use futures_util::io::AsyncReadExt; +use tokio::codec::{BytesCodec, FramedRead}; + +use rusoto_core::region; +use rusoto_core::request::DispatchSignedRequest; +use rusoto_core::request::{HttpClient, HttpConfig}; +use rusoto_core::{ByteStream, RusotoError}; +use rusoto_credential::{DefaultCredentialsProvider, StaticProvider}; +use rusoto_s3::*; + +use super::ExternalStorage; +use kvproto::backup::S3 as Config; + +/// S3 compatible storage +#[derive(Clone)] +pub struct S3Storage { + config: Config, + client: S3Client, +} + +impl S3Storage { + /// Create a new S3 storage for the given config. + pub fn new(config: &Config) -> Result { + // This can greatly improve performance dealing with payloads greater + // than 100MB. See https://github.com/rusoto/rusoto/pull/1227 + // for more information. + let mut http_config = HttpConfig::new(); + http_config.read_buf_size(1024 * 1024 * 2); + let http_dispatcher = HttpClient::new_with_config(http_config).unwrap(); + + S3Storage::with_request_dispatcher(config, http_dispatcher) + } + + fn with_request_dispatcher(config: &Config, dispatcher: D) -> Result + where + D: DispatchSignedRequest + Send + Sync + 'static, + D::Future: Send, + { + if config.bucket.is_empty() { + return Err(Error::new(ErrorKind::InvalidInput, "missing bucket name")); + } + let region = if config.endpoint.is_empty() { + config.region.parse::().map_err(|e| { + Error::new( + ErrorKind::InvalidInput, + format!("invalid region format {}: {}", config.region, e), + ) + })? + } else { + region::Region::Custom { + name: config.region.clone(), + endpoint: config.endpoint.clone(), + } + }; + let client = if config.access_key.is_empty() || config.secret_access_key.is_empty() { + let cred_provider = DefaultCredentialsProvider::new().map_err(|e| { + Error::new( + ErrorKind::PermissionDenied, + format!("unable to get credentials: {}", e), + ) + })?; + S3Client::new_with(dispatcher, cred_provider, region) + } else { + let cred_provider = StaticProvider::new( + config.access_key.clone(), + config.secret_access_key.clone(), + None, /* token */ + None, /* valid_for */ + ); + S3Client::new_with(dispatcher, cred_provider, region) + }; + Ok(S3Storage { + config: config.clone(), + client, + }) + } + + fn maybe_prefix_key(&self, key: &str) -> String { + if !self.config.prefix.is_empty() { + return format!("{}/{}", self.config.prefix, key); + } + key.to_owned() + } +} + +impl ExternalStorage for S3Storage { + fn write( + &self, + name: &str, + reader: Box, + content_length: u64, + ) -> Result<()> { + let key = self.maybe_prefix_key(name); + debug!("save file to s3 storage"; "key" => %key); + let get_var = |s: &String| { + if s.is_empty() { + None + } else { + Some(s.clone()) + } + }; + let req = PutObjectRequest { + key, + bucket: self.config.bucket.clone(), + body: Some(ByteStream::new( + FramedRead::new(reader.compat(), BytesCodec::new()).map(|bytes| bytes.freeze()), + )), + content_length: Some(content_length as i64), + acl: get_var(&self.config.acl), + server_side_encryption: get_var(&self.config.sse), + storage_class: get_var(&self.config.storage_class), + ..Default::default() + }; + self.client + .put_object(req) + .sync() + .map(|_| ()) + .map_err(|e| Error::new(ErrorKind::Other, format!("failed to put object {}", e))) + } + + fn read(&self, name: &str) -> Result> { + let key = self.maybe_prefix_key(name); + debug!("read file from s3 storage"; "key" => %key); + let req = GetObjectRequest { + key, + bucket: self.config.bucket.clone(), + ..Default::default() + }; + self.client + .get_object(req) + .sync() + .map(|out| Box::new(out.body.unwrap().into_async_read().compat()) as _) + .map_err(|e| match e { + RusotoError::Service(GetObjectError::NoSuchKey(key)) => Error::new( + ErrorKind::NotFound, + format!("not key {} not at bucket {}", key, self.config.bucket), + ), + e => Error::new(ErrorKind::Other, format!("failed to get object {}", e)), + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use rusoto_core::signature::SignedRequest; + use rusoto_mock::MockRequestDispatcher; + + #[test] + fn test_s3_config() { + let mut config = Config::default(); + config.set_region("ap-southeast-2".to_string()); + config.set_bucket("mybucket".to_string()); + config.set_prefix("myprefix".to_string()); + config.set_access_key("abc".to_string()); + config.set_secret_access_key("xyz".to_string()); + let cases = vec![ + // missing both region and endpoint + { + let mut config = config.clone(); + config.set_region("".to_string()); + config + }, + ]; + for case in cases { + let dispatcher = MockRequestDispatcher::with_status(200); + let r = S3Storage::with_request_dispatcher(&case, dispatcher); + assert!(r.is_err()); + } + let dispatcher = MockRequestDispatcher::with_status(200); + assert!(S3Storage::with_request_dispatcher(&config, dispatcher).is_ok()); + } + + #[test] + fn test_s3_storage() { + let magic_contents = "5678"; + let mut config = Config::default(); + config.set_region("ap-southeast-2".to_string()); + config.set_bucket("mybucket".to_string()); + config.set_prefix("myprefix".to_string()); + config.set_access_key("abc".to_string()); + config.set_secret_access_key("xyz".to_string()); + + let dispatcher = MockRequestDispatcher::with_status(200).with_request_checker( + move |req: &SignedRequest| { + assert_eq!(req.region.name(), "ap-southeast-2"); + assert_eq!(req.path(), "/mybucket/myprefix/mykey"); + // PutObject is translated to HTTP PUT. + assert_eq!(req.payload.is_some(), req.method() == "PUT"); + }, + ); + let s = S3Storage::with_request_dispatcher(&config, dispatcher).unwrap(); + s.write( + "mykey", + Box::new(magic_contents.as_bytes()), + magic_contents.len() as u64, + ) + .unwrap(); + let mut reader = s.read("mykey").unwrap(); + let mut buf = Vec::new(); + let ret = futures::executor::block_on(reader.read_to_end(&mut buf)); + assert!(ret.unwrap() == 0); + assert!(buf.is_empty()); + } +} diff --git a/components/test_raftstore/src/cluster.rs b/components/test_raftstore/src/cluster.rs index 0bc2cdb345e..277d40ae1fd 100644 --- a/components/test_raftstore/src/cluster.rs +++ b/components/test_raftstore/src/cluster.rs @@ -21,6 +21,7 @@ use engine::CF_DEFAULT; use tikv::config::TiKvConfig; use tikv::pd::PdClient; use tikv::raftstore::store::fsm::{create_raft_batch_system, RaftBatchSystem, RaftRouter}; +use tikv::raftstore::store::transport::CasualRouter; use tikv::raftstore::store::*; use tikv::raftstore::{Error, Result}; use tikv::server::Result as ServerResult; @@ -845,16 +846,16 @@ impl Cluster { let leader = self.leader_of_region(region.get_id()).unwrap(); let router = self.sim.rl().get_router(leader.get_store_id()).unwrap(); let split_key = split_key.to_vec(); - router - .send( - region.get_id(), - PeerMsg::CasualMessage(CasualMessage::SplitRegion { - region_epoch: region.get_region_epoch().clone(), - split_keys: vec![split_key.clone()], - callback: cb, - }), - ) - .unwrap(); + CasualRouter::send( + &router, + region.get_id(), + CasualMessage::SplitRegion { + region_epoch: region.get_region_epoch().clone(), + split_keys: vec![split_key], + callback: cb, + }, + ) + .unwrap(); } pub fn must_split(&mut self, region: &metapb::Region, split_key: &[u8]) { diff --git a/components/test_raftstore/src/pd.rs b/components/test_raftstore/src/pd.rs index 569ce9d073d..93829abf1c9 100644 --- a/components/test_raftstore/src/pd.rs +++ b/components/test_raftstore/src/pd.rs @@ -860,25 +860,28 @@ impl TestPdClient { pub fn must_merge(&self, from: u64, target: u64) { self.merge_region(from, target); - for _ in 1..500 { - sleep_ms(10); - - if self.get_region_by_id(from).wait().unwrap().is_none() { - return; - } - } - - let region = self.get_region_by_id(from).wait().unwrap(); - if region.is_none() { - return; - } - panic!("region {:?} is still not merged.", region.unwrap()); + self.check_merged_timeout(from, Duration::from_secs(5)); } pub fn check_merged(&self, from: u64) -> bool { self.get_region_by_id(from).wait().unwrap().is_none() } + pub fn check_merged_timeout(&self, from: u64, duration: Duration) { + let timer = Instant::now(); + loop { + let region = self.get_region_by_id(from).wait().unwrap(); + if let Some(r) = region { + if timer.elapsed() > duration { + panic!("region {:?} is still not merged.", r); + } + } else { + return; + } + sleep_ms(10); + } + } + pub fn region_leader_must_be(&self, region_id: u64, peer: metapb::Peer) { for _ in 0..500 { sleep_ms(10); diff --git a/components/test_raftstore/src/server.rs b/components/test_raftstore/src/server.rs index 5d26a868aa8..913a9b19007 100644 --- a/components/test_raftstore/src/server.rs +++ b/components/test_raftstore/src/server.rs @@ -22,7 +22,7 @@ use tikv::raftstore::store::fsm::{RaftBatchSystem, RaftRouter}; use tikv::raftstore::store::{Callback, LocalReader, SnapManager}; use tikv::raftstore::Result; use tikv::server::load_statistics::ThreadLoad; -use tikv::server::lock_manager::{Config as PessimisticTxnConfig, LockManager}; +use tikv::server::lock_manager::LockManager; use tikv::server::resolve::{self, Task as ResolveTask}; use tikv::server::service::DebugService; use tikv::server::transport::ServerRaftStoreRouter; @@ -224,7 +224,7 @@ impl Simulator for ServerCluster { ); // Create coprocessor. - let mut coprocessor_host = CoprocessorHost::new(cfg.coprocessor, router.clone()); + let mut coprocessor_host = CoprocessorHost::new(cfg.coprocessor.clone(), router.clone()); let region_info_accessor = RegionInfoAccessor::new(&mut coprocessor_host); region_info_accessor.start(); @@ -256,7 +256,7 @@ impl Simulator for ServerCluster { Arc::clone(&self.pd_client), resolver, Arc::clone(&security_mgr), - &PessimisticTxnConfig::default(), + &cfg.pessimistic_txn, ) .unwrap(); diff --git a/components/test_raftstore/src/transport_simulate.rs b/components/test_raftstore/src/transport_simulate.rs index 508c5b353f0..a745b401e0a 100644 --- a/components/test_raftstore/src/transport_simulate.rs +++ b/components/test_raftstore/src/transport_simulate.rs @@ -311,14 +311,15 @@ impl Direction { /// Drop specified messages for the store with special region. /// -/// If `msg_type` is None, all message will be filtered. +/// If `drop_type` is empty, all message will be dropped. #[derive(Clone)] pub struct RegionPacketFilter { region_id: u64, store_id: u64, direction: Direction, block: Either, Arc>, - msg_type: Option, + drop_type: Vec, + skip_type: Vec, dropped_messages: Option>>>, msg_callback: Option>, } @@ -329,14 +330,13 @@ impl Filter for RegionPacketFilter { let region_id = m.get_region_id(); let from_store_id = m.get_from_peer().get_store_id(); let to_store_id = m.get_to_peer().get_store_id(); + let msg_type = m.get_message().get_msg_type(); if self.region_id == region_id && (self.direction.is_send() && self.store_id == from_store_id || self.direction.is_recv() && self.store_id == to_store_id) - && self - .msg_type - .as_ref() - .map_or(true, |t| t == &m.get_message().get_msg_type()) + && (self.drop_type.is_empty() || self.drop_type.contains(&msg_type)) + && !self.skip_type.contains(&msg_type) { if let Some(f) = self.msg_callback.as_ref() { f(m) @@ -372,7 +372,8 @@ impl RegionPacketFilter { region_id, store_id, direction: Direction::Both, - msg_type: None, + drop_type: vec![], + skip_type: vec![], block: Either::Right(Arc::new(AtomicBool::new(true))), dropped_messages: None, msg_callback: None, @@ -384,8 +385,14 @@ impl RegionPacketFilter { self } + // TODO: rename it to `drop`. pub fn msg_type(mut self, m_type: MessageType) -> RegionPacketFilter { - self.msg_type = Some(m_type); + self.drop_type.push(m_type); + self + } + + pub fn skip(mut self, m_type: MessageType) -> RegionPacketFilter { + self.skip_type.push(m_type); self } diff --git a/components/test_raftstore/src/util.rs b/components/test_raftstore/src/util.rs index f779a21585f..f9e8f037a84 100644 --- a/components/test_raftstore/src/util.rs +++ b/components/test_raftstore/src/util.rs @@ -24,7 +24,7 @@ use tikv::config::*; use tikv::raftstore::store::fsm::RaftRouter; use tikv::raftstore::store::*; use tikv::raftstore::Result; -use tikv::server::Config as ServerConfig; +use tikv::server::{lock_manager::Config as PessimisticTxnConfig, Config as ServerConfig}; use tikv::storage::kv::CompactionListener; use tikv::storage::{Config as StorageConfig, DEFAULT_ROCKSDB_SUB_DIR}; use tikv_util::config::*; @@ -170,6 +170,15 @@ pub fn new_readpool_cfg() -> ReadPoolConfig { } } +pub fn new_pessimistic_txn_cfg() -> PessimisticTxnConfig { + PessimisticTxnConfig { + // Use a large value here since tests run slowly in CI. + wait_for_lock_timeout: 3000, + wake_up_delay_duration: 100, + ..PessimisticTxnConfig::default() + } +} + pub fn new_tikv_config(cluster_id: u64) -> TiKvConfig { TiKvConfig { storage: StorageConfig { @@ -180,6 +189,7 @@ pub fn new_tikv_config(cluster_id: u64) -> TiKvConfig { server: new_server_config(cluster_id), raft_store: new_store_cfg(), readpool: new_readpool_cfg(), + pessimistic_txn: new_pessimistic_txn_cfg(), ..TiKvConfig::default() } } diff --git a/components/tikv_util/src/file.rs b/components/tikv_util/src/file.rs index 3e40302487a..6bb18ac91df 100644 --- a/components/tikv_util/src/file.rs +++ b/components/tikv_util/src/file.rs @@ -3,6 +3,7 @@ use std::fs::{self, OpenOptions}; use std::io::{self, ErrorKind, Read}; use std::path::Path; +use std::sync::{Arc, Mutex}; use openssl::error::ErrorStack; use openssl::hash::{self, Hasher, MessageDigest}; @@ -90,28 +91,27 @@ pub fn sha256(input: &[u8]) -> Result, ErrorStack> { /// Wrapper of a reader which computes its SHA-256 hash while reading. pub struct Sha256Reader { reader: R, - hasher: Hasher, + hasher: Arc>, } impl Sha256Reader { /// Creates a new `Sha256Reader`, wrapping the given reader. - pub fn new(reader: R) -> Result { - Ok(Sha256Reader { - reader, - hasher: Hasher::new(MessageDigest::sha256())?, - }) - } - - /// Computes the final SHA-256 hash. - pub fn hash(mut self) -> Result, ErrorStack> { - Ok(self.hasher.finish()?.to_vec()) + pub fn new(reader: R) -> Result<(Self, Arc>), ErrorStack> { + let hasher = Arc::new(Mutex::new(Hasher::new(MessageDigest::sha256())?)); + Ok(( + Sha256Reader { + reader, + hasher: hasher.clone(), + }, + hasher, + )) } } impl Read for Sha256Reader { fn read(&mut self, buf: &mut [u8]) -> io::Result { let len = self.reader.read(buf)?; - self.hasher.update(&buf[..len])?; + (*self.hasher).lock().unwrap().update(&buf[..len])?; Ok(len) } } @@ -256,9 +256,13 @@ mod tests { let direct_sha256 = sha256(&large_file_bytes).unwrap(); let large_file_reader = fs::File::open(&large_file).unwrap(); - let mut sha256_reader = Sha256Reader::new(large_file_reader).unwrap(); - sha256_reader.read_to_end(&mut Vec::new()).unwrap(); - - assert_eq!(sha256_reader.hash().unwrap(), direct_sha256); + let (mut sha256_reader, sha256_hasher) = Sha256Reader::new(large_file_reader).unwrap(); + let ret = sha256_reader.read_to_end(&mut Vec::new()); + + assert_eq!(ret.unwrap(), DIGEST_BUFFER_SIZE * 4); + assert_eq!( + sha256_hasher.lock().unwrap().finish().unwrap().to_vec(), + direct_sha256 + ); } } diff --git a/components/tikv_util/src/metrics/mod.rs b/components/tikv_util/src/metrics/mod.rs index 946b181bcc3..a0e47adb5c6 100644 --- a/components/tikv_util/src/metrics/mod.rs +++ b/components/tikv_util/src/metrics/mod.rs @@ -8,12 +8,12 @@ use prometheus::*; #[cfg(target_os = "linux")] mod threads_linux; #[cfg(target_os = "linux")] -pub use self::threads_linux::{cpu_total, get_thread_ids, monitor_threads}; +pub use self::threads_linux::{cpu_total, get_thread_ids, monitor_threads, ThreadInfoStatistics}; #[cfg(not(target_os = "linux"))] mod threads_dummy; #[cfg(not(target_os = "linux"))] -pub use self::threads_dummy::monitor_threads; +pub use self::threads_dummy::{monitor_threads, ThreadInfoStatistics}; pub use self::allocator_metrics::monitor_allocator_stats; diff --git a/components/tikv_util/src/metrics/threads_dummy.rs b/components/tikv_util/src/metrics/threads_dummy.rs index 00bac8611a2..23e971037b8 100644 --- a/components/tikv_util/src/metrics/threads_dummy.rs +++ b/components/tikv_util/src/metrics/threads_dummy.rs @@ -7,8 +7,31 @@ other than Linux. PRs are welcome! */ +use crate::collections::HashMap; use std::io; pub fn monitor_threads>(_: S) -> io::Result<()> { Ok(()) } + +pub struct ThreadInfoStatistics {} + +impl ThreadInfoStatistics { + pub fn new() -> Self { + ThreadInfoStatistics {} + } + + pub fn record(&mut self) {} + + pub fn get_cpu_usages(&self) -> HashMap { + HashMap::default() + } + + pub fn get_read_io_rates(&self) -> HashMap { + HashMap::default() + } + + pub fn get_write_io_rates(&self) -> HashMap { + HashMap::default() + } +} diff --git a/components/tikv_util/src/metrics/threads_linux.rs b/components/tikv_util/src/metrics/threads_linux.rs index 65ac067508f..b1ed001133d 100644 --- a/components/tikv_util/src/metrics/threads_linux.rs +++ b/components/tikv_util/src/metrics/threads_linux.rs @@ -3,7 +3,9 @@ use std::fs; use std::io::{Error, ErrorKind, Result}; use std::sync::Mutex; +use std::time::Instant; +use crate::collections::HashMap; use libc::{self, pid_t}; use prometheus::core::{Collector, Desc}; use prometheus::{self, proto, CounterVec, IntCounterVec, IntGaugeVec, Opts}; @@ -287,6 +289,145 @@ lazy_static! { }; } +#[inline] +fn get_name(command: &str) -> String { + if command != "" { + return command.to_owned(); + } + String::from("anony") +} + +fn collect_metrics_by_name( + names: &HashMap, + values: &HashMap, +) -> HashMap { + let mut new_map: HashMap = HashMap::default(); + for (tid, name) in names { + let new_value = new_map.entry(name.to_string()).or_insert(0); + if let Some(value) = values.get(&tid) { + *new_value += *value as u64; + } + } + new_map +} + +#[inline] +fn update_metric( + metrics: &mut HashMap, + rates: &mut HashMap, + tid: i32, + metric_new: f64, + time_delta: f64, +) { + let metric_old = metrics.entry(tid).or_insert(0.0); + let rate = rates.entry(tid).or_insert(0.0); + + let metric_delta = metric_new - *metric_old; + if metric_delta > 0.0 && time_delta > 0.0 { + *metric_old = metric_new; + *rate = metric_delta / time_delta; + } +} + +#[derive(Default)] +struct ThreadMetrics { + cpu_times: HashMap, + read_ios: HashMap, + write_ios: HashMap, +} + +impl ThreadMetrics { + fn clear(&mut self) { + self.cpu_times.clear(); + self.read_ios.clear(); + self.write_ios.clear(); + } +} + +/// Use to collect cpu usages and disk I/O rates +pub struct ThreadInfoStatistics { + pid: pid_t, + last_instant: Instant, + tid_names: HashMap, + metrics_rate: ThreadMetrics, + metrics_total: ThreadMetrics, +} + +impl ThreadInfoStatistics { + pub fn new() -> Self { + let pid = unsafe { libc::getpid() }; + + let mut thread_stats = ThreadInfoStatistics { + pid, + last_instant: Instant::now(), + tid_names: HashMap::default(), + metrics_rate: ThreadMetrics::default(), + metrics_total: ThreadMetrics::default(), + }; + thread_stats.record(); + thread_stats + } + + pub fn record(&mut self) { + let current_instant = Instant::now(); + let time_delta = (current_instant - self.last_instant).as_millis() as f64 / 1000.0; + self.last_instant = current_instant; + + self.metrics_rate.clear(); + + let tids = get_thread_ids(self.pid).unwrap(); + for tid in tids { + if let Ok(stat) = pid::stat_task(self.pid, tid) { + let name = get_name(&stat.command); + self.tid_names.entry(tid).or_insert(name); + + let cpu_time = cpu_total(&stat) * 100.0; + update_metric( + &mut self.metrics_total.cpu_times, + &mut self.metrics_rate.cpu_times, + tid, + cpu_time, + time_delta, + ); + + if let Ok(io) = pid::io_task(self.pid, tid) { + // Threads IO. + let read_bytes = io.read_bytes; + let write_bytes = io.write_bytes; + + update_metric( + &mut self.metrics_total.read_ios, + &mut self.metrics_rate.read_ios, + tid, + read_bytes as f64, + time_delta, + ); + + update_metric( + &mut self.metrics_total.write_ios, + &mut self.metrics_rate.write_ios, + tid, + write_bytes as f64, + time_delta, + ); + } + } + } + } + + pub fn get_cpu_usages(&self) -> HashMap { + collect_metrics_by_name(&self.tid_names, &self.metrics_rate.cpu_times) + } + + pub fn get_read_io_rates(&self) -> HashMap { + collect_metrics_by_name(&self.tid_names, &self.metrics_rate.read_ios) + } + + pub fn get_write_io_rates(&self) -> HashMap { + collect_metrics_by_name(&self.tid_names, &self.metrics_rate.write_ios) + } +} + #[cfg(test)] mod tests { use std::env::temp_dir; @@ -319,6 +460,7 @@ mod tests { .unwrap(); rx1.recv().unwrap(); + let page_size = unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) as usize }; let pid = unsafe { libc::getpid() }; let tids = get_thread_ids(pid).unwrap(); assert!(tids.len() >= 2); @@ -334,7 +476,7 @@ mod tests { tids.iter() .find(|t| { pid::io_task(pid, **t) - .map(|io| io.wchar == name.len()) + .map(|io| io.write_bytes == page_size) .unwrap_or(false) }) .unwrap(); @@ -343,6 +485,137 @@ mod tests { h.join().unwrap(); } + fn write_two_string( + str1: String, + str2: String, + ) -> (sync::mpsc::Sender<()>, sync::mpsc::Receiver<()>) { + let (tx, rx) = sync::mpsc::channel(); + let (tx1, rx1) = sync::mpsc::channel(); + thread::Builder::new() + .name(str1.to_owned()) + .spawn(move || { + // Make `io::write_bytes` > 0 + let mut tmp = temp_dir(); + tmp.push(str1.clone()); + tmp.set_extension("txt"); + let mut f = fs::File::create(tmp.as_path()).unwrap(); + f.write_all(str1.as_bytes()).unwrap(); + f.sync_all().unwrap(); + tx1.send(()).unwrap(); + rx.recv().unwrap(); + + f.write_all(str2.as_bytes()).unwrap(); + f.sync_all().unwrap(); + tx1.send(()).unwrap(); + rx.recv().unwrap(); + + fs::remove_file(tmp).unwrap(); + }) + .unwrap(); + rx1.recv().unwrap(); + + (tx, rx1) + } + + #[test] + fn test_thread_io_statistics() { + let mut thread_info = ThreadInfoStatistics::new(); + + let s1 = "testio123"; + let s2 = "test45678"; + + let (tx, rx1) = write_two_string(s1.to_owned(), s2.to_owned()); + thread_info.record(); + + let page_size = unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) as u64 }; + let pid = unsafe { libc::getpid() }; + let tids = get_thread_ids(pid).unwrap(); + for tid in tids { + if let Ok(stat) = pid::stat_task(pid, tid) { + if stat.command.starts_with(s1) { + { + let write_io = thread_info + .metrics_total + .write_ios + .entry(tid) + .or_insert(0.0); + assert!(*write_io as u64 == page_size); + } + + tx.send(()).unwrap(); + rx1.recv().unwrap(); + thread_info.record(); + + { + let write_io = thread_info + .metrics_total + .write_ios + .entry(tid) + .or_insert(0.0); + assert!(*write_io as u64 == page_size * 2); + } + + tx.send(()).unwrap(); + return; + } + } + } + panic!(); + } + + fn high_cpu_thread( + name: String, + duration_ms: u32, + ) -> (sync::mpsc::Sender<()>, sync::mpsc::Receiver<()>) { + let (tx, rx) = sync::mpsc::channel(); + let (tx1, rx1) = sync::mpsc::channel(); + thread::Builder::new() + .name(name) + .spawn(move || { + let start = Instant::now(); + loop { + if (Instant::now() - start).as_millis() > duration_ms.into() { + break; + } + } + + tx1.send(()).unwrap(); + rx.recv().unwrap(); + }) + .unwrap(); + + (tx, rx1) + } + + #[test] + fn test_thread_cpu_statistics() { + let tn = "testcpu123"; + let mut thread_info = ThreadInfoStatistics::new(); + let (tx, rx) = high_cpu_thread(tn.to_owned(), 200); + + let pid = unsafe { libc::getpid() }; + let tids = get_thread_ids(pid).unwrap(); + for tid in tids { + if let Ok(stat) = pid::stat_task(pid, tid) { + if stat.command.starts_with(tn) { + rx.recv().unwrap(); + thread_info.record(); + + let mut cpu_usages = thread_info.get_cpu_usages(); + let cpu_usage = cpu_usages.entry(stat.command).or_insert(0); + assert!(*cpu_usage < 110); // Consider the error of statistics + if *cpu_usage < 80 { + panic!("the load must be heavy than 0.8, but got {}", *cpu_usage); + } + + tx.send(()).unwrap(); + return; + } + } + } + panic!(); + } + fn get_thread_name(stat: &str) -> Result<(&str, usize)> { let start = stat.find('('); let end = stat.rfind(')'); diff --git a/etc/config-template.toml b/etc/config-template.toml index e169a80f34e..5a515c61e86 100644 --- a/etc/config-template.toml +++ b/etc/config-template.toml @@ -747,13 +747,13 @@ ## The default and maximum delay in milliseconds before responding to TiDB when pessimistic ## transactions encounter locks -# wait-for-lock-timeout = 3000 +# wait-for-lock-timeout = 1000 ## If more than one transaction is waiting for the same lock, only the one with smallest ## start timestamp will be waked up immediately when the lock is released. Others will ## be waked up after `wake_up_delay_duration(ms)` to reduce contention and make the oldest ## one more likely acquires the lock. -# wake-up-delay-duration = 100 +# wake-up-delay-duration = 20 [gc] ## The number of keys to GC in one batch. diff --git a/src/pd/pd.rs b/src/pd/pd.rs index 4575945db85..dda71790159 100644 --- a/src/pd/pd.rs +++ b/src/pd/pd.rs @@ -1,7 +1,11 @@ // Copyright 2016 TiKV Project Authors. Licensed under Apache-2.0. use std::fmt::{self, Display, Formatter}; +use std::io; +use std::sync::mpsc::{self, Sender}; use std::sync::Arc; +use std::thread::{Builder, JoinHandle}; +use std::time::Duration; use futures::Future; use tokio_core::reactor::Handle; @@ -25,12 +29,15 @@ use crate::raftstore::store::util::is_epoch_stale; use crate::raftstore::store::util::KeysInfoFormatter; use crate::raftstore::store::Callback; use crate::raftstore::store::StoreInfo; -use crate::raftstore::store::{CasualMessage, PeerMsg, RaftCommand, RaftRouter}; +use crate::raftstore::store::{CasualMessage, PeerMsg, RaftCommand, RaftRouter, SignificantMsg}; use crate::storage::FlowStatistics; use tikv_util::collections::HashMap; +use tikv_util::metrics::ThreadInfoStatistics; use tikv_util::time::time_now_sec; use tikv_util::worker::{FutureRunnable as Runnable, FutureScheduler as Scheduler, Stopped}; +type RecordPairVec = Vec; + /// Uses an asynchronous thread to tell PD something. pub enum Task { AskSplit { @@ -77,6 +84,11 @@ pub enum Task { DestroyPeer { region_id: u64, }, + StoreInfos { + cpu_usages: RecordPairVec, + read_io_rates: RecordPairVec, + write_io_rates: RecordPairVec, + }, } pub struct StoreStat { @@ -90,6 +102,10 @@ pub struct StoreStat { pub region_keys_read: LocalHistogram, pub region_bytes_written: LocalHistogram, pub region_keys_written: LocalHistogram, + + pub store_cpu_usages: RecordPairVec, + pub store_read_io_rates: RecordPairVec, + pub store_write_io_rates: RecordPairVec, } impl Default for StoreStat { @@ -105,6 +121,10 @@ impl Default for StoreStat { engine_total_keys_read: 0, engine_last_total_bytes_read: 0, engine_last_total_keys_read: 0, + + store_cpu_usages: RecordPairVec::default(), + store_read_io_rates: RecordPairVec::default(), + store_write_io_rates: RecordPairVec::default(), } } } @@ -172,6 +192,92 @@ impl Display for Task { Task::DestroyPeer { ref region_id } => { write!(f, "destroy peer of region {}", region_id) } + Task::StoreInfos { + ref cpu_usages, + ref read_io_rates, + ref write_io_rates, + } => write!( + f, + "get store's informations: cpu_usages {:?}, read_io_rates {:?}, write_io_rates {:?}", + cpu_usages, read_io_rates, write_io_rates, + ), + } + } +} + +#[inline] +fn convert_record_pairs(m: HashMap) -> RecordPairVec { + m.into_iter() + .map(|(k, v)| { + let mut pair = pdpb::RecordPair::new(); + pair.set_key(k); + pair.set_value(v); + pair + }) + .collect() +} + +struct StatsMonitor { + scheduler: Scheduler, + handle: Option>, + sender: Option>, + interval: Duration, +} + +impl StatsMonitor { + pub fn new(interval: Duration, scheduler: Scheduler) -> Self { + StatsMonitor { + scheduler, + handle: None, + sender: None, + interval, + } + } + + pub fn start(&mut self) -> Result<(), io::Error> { + let (tx, rx) = mpsc::channel(); + let interval = self.interval; + let scheduler = self.scheduler.clone(); + self.sender = Some(tx); + let h = Builder::new() + .name(thd_name!("stats-monitor")) + .spawn(move || { + let mut thread_stats = ThreadInfoStatistics::new(); + + while let Err(mpsc::RecvTimeoutError::Timeout) = rx.recv_timeout(interval) { + thread_stats.record(); + + let cpu_usages = convert_record_pairs(thread_stats.get_cpu_usages()); + let read_io_rates = convert_record_pairs(thread_stats.get_read_io_rates()); + let write_io_rates = convert_record_pairs(thread_stats.get_write_io_rates()); + + let task = Task::StoreInfos { + cpu_usages, + read_io_rates, + write_io_rates, + }; + if let Err(e) = scheduler.schedule(task) { + error!( + "failed to send store infos to pd worker"; + "err" => ?e, + ); + } + } + })?; + + self.handle = Some(h); + Ok(()) + } + + pub fn stop(&mut self) { + let h = self.handle.take(); + if h.is_none() { + return; + } + drop(self.sender.take().unwrap()); + if let Err(e) = h.unwrap().join() { + error!("join stats collector failed"; "err" => ?e); + return; } } } @@ -191,16 +297,26 @@ pub struct Runner { // actually it is the sender connected to Runner's Worker which // calls Runner's run() on Task received. scheduler: Scheduler, + stats_monitor: StatsMonitor, } impl Runner { + const INTERVAL_DIVISOR: u32 = 2; + pub fn new( store_id: u64, pd_client: Arc, router: RaftRouter, db: Arc, scheduler: Scheduler, + store_heartbeat_interval: u64, ) -> Runner { + let interval = Duration::from_secs(store_heartbeat_interval) / Self::INTERVAL_DIVISOR; + let mut stats_monitor = StatsMonitor::new(interval, scheduler.clone()); + if let Err(e) = stats_monitor.start() { + error!("failed to start stats collector, error = {:?}", e); + } + Runner { store_id, pd_client, @@ -211,6 +327,7 @@ impl Runner { store_stat: StoreStat::default(), start_ts: time_now_sec(), scheduler, + stats_monitor, } } @@ -416,7 +533,18 @@ impl Runner { stats.set_keys_read( self.store_stat.engine_total_keys_read - self.store_stat.engine_last_total_keys_read, ); - let mut interval = pdpb::TimeInterval::new(); + + stats.set_cpu_usages(protobuf::RepeatedField::from_vec( + self.store_stat.store_cpu_usages.clone(), + )); + stats.set_read_io_rates(protobuf::RepeatedField::from_vec( + self.store_stat.store_read_io_rates.clone(), + )); + stats.set_write_io_rates(protobuf::RepeatedField::from_vec( + self.store_stat.store_write_io_rates.clone(), + )); + + let mut interval = pdpb::TimeInterval::default(); interval.set_start_timestamp(self.store_stat.last_report_ts); stats.set_interval(interval); self.store_stat.engine_last_total_bytes_read = self.store_stat.engine_total_bytes_read; @@ -634,6 +762,17 @@ impl Runner { Some(_) => info!("remove peer statistic record in pd"; "region_id" => region_id), } } + + fn handle_store_infos( + &mut self, + cpu_usages: RecordPairVec, + read_io_rates: RecordPairVec, + write_io_rates: RecordPairVec, + ) { + self.store_stat.store_cpu_usages = cpu_usages; + self.store_stat.store_read_io_rates = read_io_rates; + self.store_stat.store_write_io_rates = write_io_rates; + } } impl Runnable for Runner { @@ -742,8 +881,17 @@ impl Runnable for Runner { } => self.handle_validate_peer(handle, region, peer, merge_source), Task::ReadStats { read_stats } => self.handle_read_stats(read_stats), Task::DestroyPeer { region_id } => self.handle_destroy_peer(region_id), + Task::StoreInfos { + cpu_usages, + read_io_rates, + write_io_rates, + } => self.handle_store_infos(cpu_usages, read_io_rates, write_io_rates), }; } + + fn shutdown(&mut self) { + self.stats_monitor.stop(); + } } fn new_change_peer_request(change_type: ConfChangeType, peer: metapb::Peer) -> AdminRequest { @@ -833,9 +981,9 @@ fn send_admin_request( /// Sends merge fail message to gc merge source. fn send_merge_fail(router: &RaftRouter, source_region_id: u64, target: metapb::Peer) { let target_id = target.get_id(); - if let Err(e) = router.send( + if let Err(e) = router.force_send( source_region_id, - PeerMsg::CasualMessage(CasualMessage::MergeResult { + PeerMsg::SignificantMsg(SignificantMsg::MergeResult { target, stale: true, }), @@ -868,3 +1016,93 @@ fn send_destroy_peer_message( ) } } + +#[cfg(test)] +mod tests { + use std::sync::Mutex; + use std::time::Instant; + use tikv_util::worker::FutureWorker; + + use super::*; + + struct RunnerTest { + store_stat: Arc>, + stats_monitor: StatsMonitor, + } + + impl RunnerTest { + fn new( + interval: u64, + scheduler: Scheduler, + store_stat: Arc>, + ) -> RunnerTest { + let mut stats_monitor = + StatsMonitor::new(Duration::from_secs(interval), scheduler.clone()); + if let Err(e) = stats_monitor.start() { + error!("failed to start stats collector, error = {:?}", e); + } + + RunnerTest { + store_stat, + stats_monitor, + } + } + + fn handle_store_infos( + &mut self, + cpu_usages: RecordPairVec, + read_io_rates: RecordPairVec, + write_io_rates: RecordPairVec, + ) { + let mut store_stat = self.store_stat.lock().unwrap(); + store_stat.store_cpu_usages = cpu_usages; + store_stat.store_read_io_rates = read_io_rates; + store_stat.store_write_io_rates = write_io_rates; + } + } + + impl Runnable for RunnerTest { + fn run(&mut self, task: Task, _handle: &Handle) { + if let Task::StoreInfos { + cpu_usages, + read_io_rates, + write_io_rates, + } = task + { + self.handle_store_infos(cpu_usages, read_io_rates, write_io_rates) + }; + } + + fn shutdown(&mut self) { + self.stats_monitor.stop(); + } + } + + fn sum_record_pairs(pairs: &[pdpb::RecordPair]) -> u64 { + let mut sum = 0; + for record in pairs.iter() { + sum += record.get_value(); + } + sum + } + + #[test] + fn test_collect_stats() { + let mut pd_worker = FutureWorker::new("test-pd-worker"); + let store_stat = Arc::new(Mutex::new(StoreStat::default())); + let runner = RunnerTest::new(1, pd_worker.scheduler(), Arc::clone(&store_stat)); + pd_worker.start(runner).unwrap(); + + let start = Instant::now(); + loop { + if (Instant::now() - start).as_secs() > 2 { + break; + } + } + + let total_cpu_usages = sum_record_pairs(&store_stat.lock().unwrap().store_cpu_usages); + assert!(total_cpu_usages > 90); + + pd_worker.stop(); + } +} diff --git a/src/raftstore/store/fsm/apply.rs b/src/raftstore/store/fsm/apply.rs index ebe26b5a27f..f23ed4505e4 100644 --- a/src/raftstore/store/fsm/apply.rs +++ b/src/raftstore/store/fsm/apply.rs @@ -3,6 +3,7 @@ use std::borrow::Cow; use std::collections::VecDeque; use std::fmt::{self, Debug, Formatter}; +use std::ops::{Deref, DerefMut}; use std::sync::atomic::{AtomicU64, Ordering}; #[cfg(test)] use std::sync::mpsc::Sender; @@ -10,6 +11,7 @@ use std::sync::mpsc::SyncSender; use std::sync::Arc; use std::{cmp, usize}; +use batch_system::{BasicMailbox, BatchRouter, BatchSystem, Fsm, HandlerBuilder, PollHandler}; use crossbeam::channel::{TryRecvError, TrySendError}; use engine::rocks; use engine::rocks::Writable; @@ -34,7 +36,7 @@ use crate::import::SSTImporter; use crate::raftstore::coprocessor::CoprocessorHost; use crate::raftstore::store::fsm::{RaftPollerBuilder, RaftRouter}; use crate::raftstore::store::metrics::*; -use crate::raftstore::store::msg::{Callback, PeerMsg}; +use crate::raftstore::store::msg::{Callback, PeerMsg, SignificantMsg}; use crate::raftstore::store::peer::Peer; use crate::raftstore::store::peer_storage::{self, write_initial_apply_state, write_peer_state}; use crate::raftstore::store::util::check_region_epoch; @@ -49,7 +51,6 @@ use tikv_util::Either; use tikv_util::MustConsumeVec; use super::metrics::*; -use super::{BasicMailbox, BatchRouter, BatchSystem, Fsm, HandlerBuilder, PollHandler}; use super::super::RegionTask; use crate::tiflash_ffi::invoke::{get_tiflash_server_helper, RaftCmdHeader, TiFlashApplyRes}; @@ -176,7 +177,6 @@ pub enum ExecResult { region: Region, state: MergeState, }, - CatchUpLogs(CatchUpLogs), CommitMerge { region: Region, source: Region, @@ -205,6 +205,7 @@ pub enum ExecResult { /// The possible returned value when applying logs. pub enum ApplyResult { None, + Yield, /// Additional result that needs to be sent back to raftstore. Res(ExecResult), /// It is unable to apply the `CommitMerge` until the source peer @@ -307,7 +308,7 @@ impl ApplyContext { importer: Arc, region_scheduler: Scheduler, engines: Engines, - router: BatchRouter, + router: ApplyRouter, notifier: Notifier, cfg: &Config, ) -> ApplyContext { @@ -530,6 +531,13 @@ fn should_write_to_engine(cmd: &RaftCmdRequest, kv_wb_keys: usize) -> bool { /// this struct. /// TODO: check whether generator/coroutine is a good choice in this case. struct WaitSourceMergeState { + /// A flag that indicates whether the source peer has applied to the required + /// index. If the source peer is ready, this flag should be set to the region id + /// of source peer. + logs_up_to_date: Arc, +} + +struct YieldState { /// All of the entries that need to continue to be applied after /// the source peer has applied its logs. pending_entries: Vec, @@ -537,17 +545,20 @@ struct WaitSourceMergeState { /// the source peer has applied its logs and pending entries /// are all handled. pending_msgs: Vec, - /// A flag that indicates whether the source peer has applied to the required - /// index. If the source peer is ready, this flag should be set to the region id - /// of source peer. - logs_up_to_date: Arc, } -impl Debug for WaitSourceMergeState { +impl Debug for YieldState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("WaitSourceMergeState") + f.debug_struct("YieldState") .field("pending_entries", &self.pending_entries.len()) .field("pending_msgs", &self.pending_msgs.len()) + .finish() + } +} + +impl Debug for WaitSourceMergeState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("WaitSourceMergeState") .field("logs_up_to_date", &self.logs_up_to_date) .finish() } @@ -580,6 +591,7 @@ pub struct ApplyDelegate { /// If the delegate should be stopped from polling. /// A delegate can be stopped in conf change, merge or requested by destroy message. stopped: bool, + written: bool, /// Set to true when removing itself because of `ConfChangeType::RemoveNode`, and then /// any following committed logs in same Ready should be applied failed. pending_remove: bool, @@ -591,6 +603,7 @@ pub struct ApplyDelegate { is_merging: bool, /// Records the epoch version after the last merge. last_merge_version: u64, + yield_state: Option, /// A temporary state that keeps track of the progress of the source peer state when /// CommitMerge is unable to be executed. wait_merge_state: Option, @@ -621,7 +634,9 @@ impl ApplyDelegate { applied_index_term: reg.applied_index_term, term: reg.term, stopped: false, + written: false, ready_source_region_id: 0, + yield_state: None, wait_merge_state: None, is_merging: reg.is_merging, pending_cmds: Default::default(), @@ -688,19 +703,21 @@ impl ApplyDelegate { match res { ApplyResult::None => {} ApplyResult::Res(res) => results.push_back(res), - ApplyResult::WaitMergeSource(logs_up_to_date) => { + _ => { + // Both cancel and merge will yield current processing. apply_ctx.committed_count -= drainer.len() + 1; let mut pending_entries = Vec::with_capacity(drainer.len() + 1); - // Note that CommitMerge is skipped when `WaitMergeSource` is returned. - // So we need to enqueue it again and execute it again when resuming. + // Note that current entry is skipped when yield. pending_entries.push(entry); pending_entries.extend(drainer); apply_ctx.finish_for(self, results); - self.wait_merge_state = Some(WaitSourceMergeState { + self.yield_state = Some(YieldState { pending_entries, pending_msgs: Vec::default(), - logs_up_to_date, }); + if let ApplyResult::WaitMergeSource(logs_up_to_date) = res { + self.wait_merge_state = Some(WaitSourceMergeState { logs_up_to_date }); + } return; } } @@ -738,6 +755,10 @@ impl ApplyDelegate { apply_ctx: &mut ApplyContext, entry: &Entry, ) -> ApplyResult { + fail_point!("apply_yield_1000", self.region_id() == 1000, |_| { + ApplyResult::Yield + }); + let index = entry.get_index(); let term = entry.get_term(); let data = entry.get_data(); @@ -798,7 +819,7 @@ impl ApplyDelegate { } ApplyResult::Res(res) } - ApplyResult::WaitMergeSource(_) => unreachable!(), + ApplyResult::Yield | ApplyResult::WaitMergeSource(_) => unreachable!(), } } @@ -962,8 +983,7 @@ impl ApplyDelegate { | ExecResult::VerifyHash { .. } | ExecResult::CompactLog { .. } | ExecResult::DeleteRange { .. } - | ExecResult::IngestSST { .. } - | ExecResult::CatchUpLogs { .. } => {} + | ExecResult::IngestSST { .. } => {} ExecResult::SplitRegion { ref derived, .. } => { self.region = derived.clone(); self.metrics.size_diff_hint = 0; @@ -1752,14 +1772,15 @@ impl ApplyDelegate { // The target peer should send missing log entries to the source peer. // // So, the merge process order would be: - // 1. `exec_commit_merge` in target apply worker - // 2. `catch_up_logs_for_merge` in source apply worker (check whether need to catch up logs) - // 3. `on_ready_catch_up_logs` in source raftstore - // 4. ... (raft append and apply logs) - // 5. `on_ready_prepare_merge` in source raftstore (means source region has finished applying all logs) - // 6. `catch_up_logs_for_merge` in source apply worker (destroy itself and send LogsUpToDate) - // 7. resume `exec_commit_merge` in target apply worker - // 8. `on_ready_commit_merge` in target raftstore + // 1. `exec_commit_merge` in target apply fsm and send `CatchUpLogs` to source peer fsm + // 2. `on_catch_up_logs_for_merge` in source peer fsm + // 3. if the source peer has already executed the corresponding `on_ready_prepare_merge`, set pending_remove and jump to step 6 + // 4. ... (raft append and apply logs) + // 5. `on_ready_prepare_merge` in source peer fsm and set pending_remove (means source region has finished applying all logs) + // 6. `logs_up_to_date_for_merge` in source apply fsm (destroy its apply fsm and send Noop to trigger the target apply fsm) + // 7. resume `exec_commit_merge` in target apply fsm + // 8. `on_ready_commit_merge` in target peer fsm and send `MergeResult` to source peer fsm + // 9. `on_merge_result` in source peer fsm (destroy itself) fn exec_commit_merge( &mut self, ctx: &mut ApplyContext, @@ -1800,15 +1821,16 @@ impl ApplyDelegate { "peer_id" => self.id(), "source_region_id" => source_region_id ); - - // Sends message to the source apply worker and pause `exec_commit_merge` process + fail_point!("before_handle_catch_up_logs_for_merge"); + // Sends message to the source peer fsm and pause `exec_commit_merge` process let logs_up_to_date = Arc::new(AtomicU64::new(0)); - let msg = Msg::CatchUpLogs(CatchUpLogs { + let msg = SignificantMsg::CatchUpLogs(CatchUpLogs { target_region_id: self.region_id(), merge: merge.to_owned(), logs_up_to_date: logs_up_to_date.clone(), }); - ctx.router.schedule_task(source_region_id, msg); + ctx.notifier + .notify(source_region_id, PeerMsg::SignificantMsg(msg)); return Ok(( AdminResponse::default(), ApplyResult::WaitMergeSource(logs_up_to_date), @@ -2252,8 +2274,8 @@ pub enum Msg { }, Registration(Registration), Proposal(RegionProposal), - CatchUpLogs(CatchUpLogs), - LogsUpToDate(u64), + LogsUpToDate(CatchUpLogs), + Noop, Destroy(Destroy), Snapshot(GenSnapTask), #[cfg(test)] @@ -2288,8 +2310,8 @@ impl Debug for Msg { Msg::Registration(ref r) => { write!(f, "[region {}] Reg {:?}", r.region.get_id(), r.apply_state) } - Msg::CatchUpLogs(cul) => write!(f, "{:?}", cul.merge), - Msg::LogsUpToDate(region_id) => write!(f, "[region {}] logs are updated", region_id), + Msg::LogsUpToDate(_) => write!(f, "logs are updated"), + Msg::Noop => write!(f, "noop"), Msg::Destroy(ref d) => write!(f, "[region {}] destroy", d.region_id), Msg::Snapshot(GenSnapTask { region_id, .. }) => { write!(f, "[region {}] requests a snapshot", region_id) @@ -2377,11 +2399,7 @@ impl ApplyFsm { apply_ctx.timer = Some(SlowTimer::new()); } - fail_point!( - "on_handle_apply_1000_1003", - self.delegate.region_id() == 1000 && self.delegate.id() == 1003, - |_| {} - ); + fail_point!("on_handle_apply_1003", self.delegate.id() == 1003, |_| {}); fail_point!("on_handle_apply", |_| {}); if apply.entries.is_empty() || self.delegate.pending_remove || self.delegate.stopped { @@ -2393,7 +2411,7 @@ impl ApplyFsm { self.delegate .handle_raft_committed_entries(apply_ctx, apply.entries); - if self.delegate.wait_merge_state.is_some() { + if self.delegate.yield_state.is_some() { return; } @@ -2440,8 +2458,8 @@ impl ApplyFsm { ctx.flush(); } fail_point!( - "before_peer_destroy_1000_1003", - self.delegate.region_id() == 1000 && self.delegate.id() == 1003, + "before_peer_destroy_1003", + self.delegate.id() == 1003, |_| {} ); info!( @@ -2475,21 +2493,17 @@ impl ApplyFsm { } } - fn resume_pending_merge(&mut self, ctx: &mut ApplyContext) -> bool { - match self.delegate.wait_merge_state { - Some(ref state) => { - let source_region_id = state.logs_up_to_date.load(Ordering::SeqCst); - if source_region_id == 0 { - return false; - } - self.delegate.ready_source_region_id = source_region_id; + fn resume_pending(&mut self, ctx: &mut ApplyContext) -> bool { + if let Some(ref state) = self.delegate.wait_merge_state { + let source_region_id = state.logs_up_to_date.load(Ordering::SeqCst); + if source_region_id == 0 { + return false; } - None => panic!( - "{} is not in waiting state, can't be resume", - self.delegate.tag - ), + self.delegate.ready_source_region_id = source_region_id; } - let mut state = self.delegate.wait_merge_state.take().unwrap(); + self.delegate.wait_merge_state = None; + + let mut state = self.delegate.yield_state.take().unwrap(); if ctx.timer.is_none() { ctx.timer = Some(SlowTimer::new()); @@ -2497,8 +2511,10 @@ impl ApplyFsm { if !state.pending_entries.is_empty() { self.delegate .handle_raft_committed_entries(ctx, state.pending_entries); - if let Some(ref mut s) = self.delegate.wait_merge_state { - // So the delegate is executing another `CommitMerge` in pending_entries. + if let Some(ref mut s) = self.delegate.yield_state { + // So the delegate is expected to yield the CPU. + // It can either be executing another `CommitMerge` in pending_msgs + // or has been written too much data. s.pending_msgs = state.pending_msgs; return false; } @@ -2508,8 +2524,7 @@ impl ApplyFsm { self.handle_tasks(ctx, &mut state.pending_msgs); } - // So the delegate is executing another `CommitMerge` in pending_msgs. - if self.delegate.wait_merge_state.is_some() { + if self.delegate.yield_state.is_some() { return false; } @@ -2521,57 +2536,29 @@ impl ApplyFsm { true } - fn catch_up_logs_for_merge(&mut self, ctx: &mut ApplyContext, catch_up_logs: CatchUpLogs) { - if ctx.timer.is_none() { - ctx.timer = Some(SlowTimer::new()); - } - - // if it is already up to date, no need to catch up anymore - let apply_index = self.delegate.apply_state.get_applied_index(); - debug!( - "check catch up logs for merge"; - "apply_index" => apply_index, - "commit" => catch_up_logs.merge.get_commit(), - "region_id" => self.delegate.region_id(), - "peer_id" => self.delegate.id(), - ); - if apply_index < catch_up_logs.merge.get_commit() { - fail_point!("on_handle_catch_up_logs_for_merge"); - let mut res = VecDeque::new(); - // send logs to raftstore to append - res.push_back(ExecResult::CatchUpLogs(catch_up_logs)); - - // TODO: can we use `ctx.finish_for()` directly? is it safe here? - ctx.apply_res.push(ApplyRes { - region_id: self.delegate.region_id(), - apply_state: self.delegate.apply_state.clone(), - exec_res: res, - metrics: self.delegate.metrics.clone(), - applied_index_term: self.delegate.applied_index_term, - }); - return; - } - + fn logs_up_to_date_for_merge(&mut self, ctx: &mut ApplyContext, catch_up_logs: CatchUpLogs) { fail_point!("after_handle_catch_up_logs_for_merge"); fail_point!( - "after_handle_catch_up_logs_for_merge_1000_1003", - self.delegate.region_id() == 1000 && self.delegate.id() == 1003, + "after_handle_catch_up_logs_for_merge_1003", + self.delegate.id() == 1003, |_| {} ); let region_id = self.delegate.region_id(); - self.destroy(ctx); - catch_up_logs - .logs_up_to_date - .store(region_id, Ordering::SeqCst); info!( "source logs are all applied now"; "region_id" => region_id, "peer_id" => self.delegate.id(), ); - + // The source peer fsm will be destroyed when the target peer executes `on_ready_commit_merge` + // and sends `merge result` to the source peer fsm. + self.destroy(ctx); + catch_up_logs + .logs_up_to_date + .store(region_id, Ordering::SeqCst); + // To trigger the target apply fsm if let Some(mailbox) = ctx.router.mailbox(catch_up_logs.target_region_id) { - let _ = mailbox.force_send(Msg::LogsUpToDate(region_id)); + let _ = mailbox.force_send(Msg::Noop); } else { error!( "failed to get mailbox, are we shutting down?"; @@ -2617,7 +2604,7 @@ impl ApplyFsm { channel_timer = Some(start); } self.handle_apply(apply_ctx, apply); - if let Some(ref mut state) = self.delegate.wait_merge_state { + if let Some(ref mut state) = self.delegate.yield_state { state.pending_msgs = drainer.collect(); break; } @@ -2625,8 +2612,8 @@ impl ApplyFsm { Some(Msg::Proposal(prop)) => self.handle_proposal(prop), Some(Msg::Registration(reg)) => self.handle_registration(reg), Some(Msg::Destroy(d)) => self.handle_destroy(apply_ctx, d), - Some(Msg::CatchUpLogs(cul)) => self.catch_up_logs_for_merge(apply_ctx, cul), - Some(Msg::LogsUpToDate(_)) => {} + Some(Msg::LogsUpToDate(cul)) => self.logs_up_to_date_for_merge(apply_ctx, cul), + Some(Msg::Noop) => {} Some(Msg::Snapshot(snap_task)) => self.handle_snapshot(apply_ctx, snap_task), #[cfg(test)] Some(Msg::Validate(_, f)) => f(&self.delegate), @@ -2700,12 +2687,15 @@ impl PollHandler for ApplyPoller { fn handle_normal(&mut self, normal: &mut ApplyFsm) -> Option { let mut expected_msg_count = None; - if normal.delegate.wait_merge_state.is_some() { - // We need to query the length first, otherwise there is a race - // condition that new messages are queued after resuming and before - // query the length. - expected_msg_count = Some(normal.receiver.len()); - if !normal.resume_pending_merge(&mut self.apply_ctx) { + normal.delegate.written = false; + if normal.delegate.yield_state.is_some() { + if normal.delegate.wait_merge_state.is_some() { + // We need to query the length first, otherwise there is a race + // condition that new messages are queued after resuming and before + // query the length. + expected_msg_count = Some(normal.receiver.len()); + } + if !normal.resume_pending(&mut self.apply_ctx) { return expected_msg_count; } expected_msg_count = None; @@ -2728,6 +2718,9 @@ impl PollHandler for ApplyPoller { if normal.delegate.wait_merge_state.is_some() { // Check it again immediately as catching up logs can be very fast. expected_msg_count = Some(0); + } else if normal.delegate.yield_state.is_some() { + // Let it continue to run next time. + expected_msg_count = None; } expected_msg_count } @@ -2788,7 +2781,24 @@ impl HandlerBuilder for Builder { } } -pub type ApplyRouter = BatchRouter; +#[derive(Clone)] +pub struct ApplyRouter { + pub router: BatchRouter, +} + +impl Deref for ApplyRouter { + type Target = BatchRouter; + + fn deref(&self) -> &BatchRouter { + &self.router + } +} + +impl DerefMut for ApplyRouter { + fn deref_mut(&mut self) -> &mut BatchRouter { + &mut self.router + } +} impl ApplyRouter { pub fn schedule_task(&self, region_id: u64, msg: Msg) { @@ -2807,7 +2817,7 @@ impl ApplyRouter { } return; } - Msg::Apply { .. } | Msg::Destroy(_) | Msg::LogsUpToDate(_) => { + Msg::Apply { .. } | Msg::Destroy(_) | Msg::Noop => { info!( "target region is not found, drop messages"; "region_id" => region_id @@ -2821,7 +2831,7 @@ impl ApplyRouter { ); return; } - Msg::CatchUpLogs(cul) => { + Msg::LogsUpToDate(cul) => { warn!( "region is removed before merged, are we shutting down?"; "region_id" => region_id, @@ -2845,7 +2855,23 @@ impl ApplyRouter { } } -pub type ApplyBatchSystem = BatchSystem; +pub struct ApplyBatchSystem { + system: BatchSystem, +} + +impl Deref for ApplyBatchSystem { + type Target = BatchSystem; + + fn deref(&self) -> &BatchSystem { + &self.system + } +} + +impl DerefMut for ApplyBatchSystem { + fn deref_mut(&mut self) -> &mut BatchSystem { + &mut self.system + } +} impl ApplyBatchSystem { pub fn schedule_all<'a>(&self, peers: impl Iterator) { @@ -2860,12 +2886,13 @@ impl ApplyBatchSystem { pub fn create_apply_batch_system(cfg: &Config) -> (ApplyRouter, ApplyBatchSystem) { let (tx, _) = loose_bounded(usize::MAX); - super::batch::create_system( + let (router, system) = batch_system::create_system( cfg.apply_pool_size, cfg.apply_max_batch_size, tx, Box::new(ControlFsm), - ) + ); + (ApplyRouter { router }, ApplyBatchSystem { system }) } #[cfg(test)] @@ -3538,6 +3565,10 @@ mod tests { assert!(resp.get_header().has_error()); let apply_res = fetch_apply_res(&rx); assert_eq!(apply_res.applied_index_term, 3); + assert_eq!(apply_res.apply_state.get_applied_index(), 10); + // Two continuous writes inside the same region will yield. + let apply_res = fetch_apply_res(&rx); + assert_eq!(apply_res.applied_index_term, 3); assert_eq!(apply_res.apply_state.get_applied_index(), 11); let mut entries = vec![]; diff --git a/src/raftstore/store/fsm/mod.rs b/src/raftstore/store/fsm/mod.rs index 829261bd4cd..1993689b980 100644 --- a/src/raftstore/store/fsm/mod.rs +++ b/src/raftstore/store/fsm/mod.rs @@ -5,10 +5,8 @@ //! stores. They are mixed for now, will be separated in the future. pub mod apply; -mod batch; mod metrics; mod peer; -mod router; pub mod store; pub use self::apply::{ @@ -17,11 +15,7 @@ pub use self::apply::{ Msg as ApplyTask, Notifier as ApplyNotifier, Proposal, RegionProposal, Registration, TaskRes as ApplyTaskRes, }; -pub use self::batch::{ - BatchRouter, BatchSystem, Fsm, HandlerBuilder, NormalScheduler, PollHandler, -}; -pub use self::peer::{DestroyPeerJob, GroupState}; -pub use self::router::{BasicMailbox, Mailbox}; +pub use self::peer::{DestroyPeerJob, GroupState, PeerFsm}; pub use self::store::{ create_raft_batch_system, new_compaction_listener, RaftBatchSystem, RaftPollerBuilder, RaftRouter, StoreInfo, diff --git a/src/raftstore/store/fsm/peer.rs b/src/raftstore/store/fsm/peer.rs index 45ef538f05b..3f2823e5a79 100644 --- a/src/raftstore/store/fsm/peer.rs +++ b/src/raftstore/store/fsm/peer.rs @@ -3,13 +3,12 @@ use std::borrow::Cow; use std::collections::Bound::{Excluded, Included, Unbounded}; use std::collections::VecDeque; -use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant}; use std::{cmp, u64}; use crate::pd::{PdClient, PdTask}; -use crate::raftstore::{Error, Result}; +use batch_system::{BasicMailbox, Fsm}; use engine::Engines; use engine::CF_RAFT; use engine::{Peekable, Snapshot as EngineSnapshot}; @@ -19,8 +18,8 @@ use kvproto::import_sstpb::SSTMeta; use kvproto::metapb::{self, Region, RegionEpoch}; use kvproto::pdpb::CheckPolicy; use kvproto::raft_cmdpb::{ - AdminCmdType, AdminRequest, CmdType, CommitMergeRequest, RaftCmdRequest, RaftCmdResponse, - StatusCmdType, StatusResponse, + AdminCmdType, AdminRequest, CmdType, RaftCmdRequest, RaftCmdResponse, StatusCmdType, + StatusResponse, }; use kvproto::raft_serverpb::{ MergeState, PeerState, RaftMessage, RaftSnapshotData, RaftTruncatedState, RegionLocalState, @@ -38,13 +37,13 @@ use crate::raftstore::coprocessor::RegionChangeEvent; use crate::raftstore::store::cmd_resp::{bind_term, new_error}; use crate::raftstore::store::fsm::store::{PollContext, StoreMeta}; use crate::raftstore::store::fsm::{ - apply, ApplyMetrics, ApplyTask, ApplyTaskRes, BasicMailbox, CatchUpLogs, ChangePeer, - ExecResult, Fsm, RegionProposal, + apply, ApplyMetrics, ApplyTask, ApplyTaskRes, CatchUpLogs, ChangePeer, ExecResult, + RegionProposal, }; use crate::raftstore::store::keys::{self, enc_end_key, enc_start_key}; use crate::raftstore::store::metrics::*; use crate::raftstore::store::msg::Callback; -use crate::raftstore::store::peer::{ConsistencyState, Peer, StaleState, WaitApplyResultState}; +use crate::raftstore::store::peer::{ConsistencyState, Peer, StaleState}; use crate::raftstore::store::peer_storage::{ApplySnapResult, InvokeContext}; use crate::raftstore::store::transport::Transport; use crate::raftstore::store::util::KeysInfoFormatter; @@ -55,6 +54,7 @@ use crate::raftstore::store::{ util, CasualMessage, Config, PeerMsg, PeerTicks, RaftCommand, SignificantMsg, SnapKey, SnapshotDeleter, StoreMsg, }; +use crate::raftstore::{Error, Result}; pub struct DestroyPeerJob { pub initialized: bool, @@ -224,10 +224,6 @@ impl PeerFsm { pub fn schedule_applying_snapshot(&mut self) { self.peer.mut_store().schedule_applying_snapshot(); } - - pub fn have_pending_merge_apply_result(&self) -> bool { - self.peer.pending_merge_apply_result.is_some() - } } impl Fsm for PeerFsm { @@ -291,10 +287,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { } PeerMsg::Tick(tick) => self.on_tick(tick), PeerMsg::ApplyRes { res } => { - if let Some(state) = self.fsm.peer.pending_merge_apply_result.as_mut() { - state.results.push(res); - continue; - } self.on_apply_res(res); } PeerMsg::SignificantMsg(msg) => self.on_significant_msg(msg), @@ -343,9 +335,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { } => { self.on_schedule_half_split_region(®ion_epoch, policy); } - CasualMessage::MergeResult { target, stale } => { - self.on_merge_result(target, stale); - } CasualMessage::GcSnap { snaps } => { self.on_gc_snap(snaps); } @@ -358,10 +347,15 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { self.fsm.group_state = GroupState::Chaos; self.register_raft_base_tick(); - if self.fsm.peer.raft_group.raft.is_learner { - self.fsm.peer.send_load_merge_target(&mut self.ctx.trans); + if self.fsm.peer.peer.get_is_learner() { + self.fsm.peer.bcast_wake_up_message(&mut self.ctx.trans); } } + CasualMessage::SnapshotGenerated => { + // Resume snapshot handling again to avoid waiting another heartbeat. + self.fsm.peer.ping(); + self.fsm.has_ready = true; + } } } @@ -388,9 +382,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { } fn start(&mut self) { - if self.fsm.peer.pending_merge_state.is_some() { - self.notify_prepare_merge(); - } self.register_raft_base_tick(); self.register_raft_gc_log_tick(); self.register_pd_heartbeat_tick(); @@ -399,71 +390,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { self.on_check_merge(); } - fn notify_prepare_merge(&self) { - let region_id = self.region_id(); - let version = self.region().get_region_epoch().get_version(); - // If there is no merge lock for that key, insert one to let target peer know `PrepareMerge` - // is already executed. - let mut meta = self.ctx.store_meta.lock().unwrap(); - let (exist_version, ready_to_merge) = - match meta.merge_locks.insert(region_id, (version, None)) { - None => return, - Some((v, r)) => (v, r), - }; - if exist_version == version { - let ready_to_merge = ready_to_merge.unwrap(); - // Set `ready_to_merge` to true to indicate `PrepareMerge` is finished. - ready_to_merge.store(true, Ordering::SeqCst); - let state = self.fsm.peer.pending_merge_state.as_ref().unwrap(); - let target_region_id = state.get_target().get_id(); - // Send an empty message to target peer to make sure it will check `ready_to_merge` - self.ctx - .router - .force_send(target_region_id, PeerMsg::Noop) - .unwrap(); - } else if exist_version > version { - meta.merge_locks - .insert(region_id, (exist_version, ready_to_merge)); - } else { - panic!( - "{} expects version {} but got {}", - self.fsm.peer.tag, version, exist_version - ); - } - } - - pub fn resume_handling_pending_apply_result(&mut self) -> bool { - match self.fsm.peer.pending_merge_apply_result { - Some(ref state) => { - if !state.ready_to_merge.load(Ordering::SeqCst) { - return false; - } - } - None => panic!( - "{} doesn't have pending apply result, can't be resume.", - self.fsm.peer.tag - ), - } - - let mut pending_apply = self.fsm.peer.pending_merge_apply_result.take().unwrap(); - let mut drainer = pending_apply.results.drain(..); - while let Some(res) = drainer.next() { - debug!( - "resume handling apply result"; - "region_id" => self.region_id(), - "peer_id" => self.fsm.peer_id(), - "res" => ?res, - ); - self.on_apply_res(res); - // So meet another `CommitMerge` apply result needed to wait. - if let Some(state) = self.fsm.peer.pending_merge_apply_result.as_mut() { - state.results.extend(drainer); - return false; - } - } - true - } - fn on_gc_snap(&mut self, snaps: Vec<(SnapKey, bool)>) { let s = self.fsm.peer.get_store(); let compacted_idx = s.truncated_index(); @@ -578,6 +504,12 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { } } } + SignificantMsg::MergeResult { target, stale } => { + self.on_merge_result(target, stale); + } + SignificantMsg::CatchUpLogs(catch_up_logs) => { + self.on_catch_up_logs_for_merge(catch_up_logs); + } } } @@ -819,15 +751,7 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { "peer_id" => self.fsm.peer_id(), "res" => ?res, ); - if let Some(ready_to_merge) = self.on_ready_result(&mut res.exec_res, &res.metrics) - { - // There is a `CommitMerge` needed to wait - self.fsm.peer.pending_merge_apply_result = Some(WaitApplyResultState { - results: vec![ApplyTaskRes::Apply(res)], - ready_to_merge, - }); - return; - } + self.on_ready_result(&mut res.exec_res, &res.metrics); if self.fsm.stopped { return; } @@ -878,8 +802,8 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { return Ok(()); } - if msg.has_merge() { - // noop + if msg.has_extra_msg() { + // now noop return Ok(()); } @@ -907,7 +831,7 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { let from_peer_id = msg.get_from_peer().get_id(); self.fsm.peer.insert_peer_cache(msg.take_from_peer()); - self.fsm.peer.step(msg.take_message())?; + self.fsm.peer.step(self.ctx, msg.take_message())?; if self.fsm.peer.any_new_peer_catch_up(from_peer_id) { self.fsm.peer.heartbeat_pd(self.ctx); @@ -1250,6 +1174,7 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { return Ok(Some(key)); } } + let mut is_overlapped = false; let mut regions_to_destroy = vec![]; // In some extreme cases, it may cause source peer destroyed improperly so that a later @@ -1294,6 +1219,8 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { if snap_region.get_region_epoch().get_version() > exist_region.get_region_epoch().get_version() { + // If snapshot's epoch version is greater than exist region's, the exist region + // may has been merged already. let _ = self.ctx.router.force_send( exist_region.get_id(), PeerMsg::CasualMessage(CasualMessage::RegionOverlapped), @@ -1315,7 +1242,7 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { .router .force_send( region_id, - PeerMsg::CasualMessage(CasualMessage::MergeResult { + PeerMsg::SignificantMsg(SignificantMsg::MergeResult { target: self.fsm.peer.peer.clone(), stale: true, }), @@ -1328,10 +1255,10 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { fn handle_destroy_peer(&mut self, job: DestroyPeerJob) -> bool { if job.initialized { - // When initialized is true and async_remove is false, applyfsm doesn't need to - // send destroy msg to peerfsm because peerfsm has already destroyed. - // In this case, if applyfsm sends destroy msg, peerfsm may be destroyed twice - // because there are some msgs in channel so peerfsm still need to handle them (e.g. callback) + // When initialized is true and async_remove is false, apply fsm doesn't need to + // send destroy msg to peer fsm because peer fsm has already destroyed. + // In this case, if apply fsm sends destroy msg, peer fsm may be destroyed twice + // because there are some msgs in channel so peer fsm still need to handle them (e.g. callback) self.ctx.apply_router.schedule_task( job.region_id, ApplyTask::destroy(job.region_id, job.async_remove), @@ -1380,7 +1307,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { } } } - meta.merge_locks.remove(®ion_id); // Destroy read delegates. if let Some(reader) = meta.readers.remove(®ion_id) { @@ -1420,10 +1346,10 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { .remove(&enc_end_key(self.fsm.peer.region())) .is_none() { - panic!("{} meta corruption detected", self.fsm.peer.tag,); + panic!("{} meta corruption detected", self.fsm.peer.tag); } if meta.regions.remove(®ion_id).is_none() && !merged_by_target { - panic!("{} meta corruption detected", self.fsm.peer.tag,) + panic!("{} meta corruption detected", self.fsm.peer.tag) } } @@ -1452,9 +1378,11 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { let id = peer.get_id(); self.fsm.peer.peer_heartbeats.insert(id, now); if self.fsm.peer.is_leader() { + // Speed up snapshot instead of waiting another heartbeat. + self.fsm.peer.ping(); + self.fsm.has_ready = true; self.fsm.peer.peers_start_pending_time.push((id, now)); } - self.fsm.peer.recent_conf_change_time = now; self.fsm.peer.insert_peer_cache(peer); } ConfChangeType::RemoveNode => { @@ -1467,7 +1395,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { .retain(|&(p, _)| p != peer_id); } self.fsm.peer.remove_peer_from_cache(peer_id); - self.fsm.peer.recent_conf_change_time = now; } } @@ -1842,85 +1769,63 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { fn on_ready_prepare_merge(&mut self, region: metapb::Region, state: MergeState) { { let mut meta = self.ctx.store_meta.lock().unwrap(); - meta.set_region( - &self.ctx.coprocessor_host, - region.clone(), - &mut self.fsm.peer, - ); - } - let target = state.get_target().get_id(); - let commit = state.get_commit(); - self.fsm.peer.pending_merge_state = Some(state); - self.notify_prepare_merge(); - - if let Some(logs_up_to_date) = self.fsm.peer.catch_up_logs.take() { - // Send CatchUpLogs back to destroy source apply delegate, - // then it will send `LogsUpToDate` to target apply delegate. - let mut req = CommitMergeRequest::new(); - req.set_commit(commit); - self.ctx.apply_router.schedule_task( - region.get_id(), - ApplyTask::CatchUpLogs(CatchUpLogs { - target_region_id: target, - merge: req, - logs_up_to_date, - }), - ); - return; + meta.set_region(&self.ctx.coprocessor_host, region, &mut self.fsm.peer); } - self.on_check_merge(); - } - - // The `PrepareMerge` and `CommitMerge` is executed sequentially, but we cannot - // ensure the order to handle the apply results between different peers. So check - // the merge locks to ensure `on_ready_prepare_merge` is called. - fn check_merge_locks( - &self, - source: &metapb::Region, - meta: &mut StoreMeta, - ) -> Option> { - let source_region_id = source.get_id(); - let source_version = source.get_region_epoch().get_version(); - - if let Some((exist_version, ready_to_merge)) = meta.merge_locks.remove(&source_region_id) { - if exist_version == source_version { - assert!(ready_to_merge.is_none()); - // So `on_ready_prepare_merge` is executed. - return None; - } else if exist_version < source_version { - assert!( - ready_to_merge.is_none(), - "{} source region {} meets a commit merge before {} < {}", - self.fsm.peer.tag, - source_region_id, - exist_version, - source_version - ); - } else { - panic!( - "{} source region {} can't finished current merge: {} > {}", - self.fsm.peer.tag, source_region_id, exist_version, source_region_id + self.fsm.peer.pending_merge_state = Some(state); + let state = self.fsm.peer.pending_merge_state.as_ref().unwrap(); + + if let Some(ref catch_up_logs) = self.fsm.peer.catch_up_logs { + if state.get_commit() == catch_up_logs.merge.get_commit() { + assert_eq!(state.get_target().get_id(), catch_up_logs.target_region_id); + // Indicate that `on_catch_up_logs_for_merge` has already executed. + // Mark pending_remove because its apply fsm will be destroyed. + self.fsm.peer.pending_remove = true; + // Send CatchUpLogs back to destroy source apply fsm, + // then it will send `Noop` to trigger target apply fsm. + self.ctx.apply_router.schedule_task( + self.fsm.region_id(), + ApplyTask::LogsUpToDate(self.fsm.peer.catch_up_logs.take().unwrap()), ); + return; } } - // The corresponding `on_ready_prepare_merge` is not executed yet. - // Insert the lock, and `on_ready_prepare_merge` will check and use `ready_to_merge` - // to notify. - let ready_to_merge = Arc::new(AtomicBool::new(false)); - meta.merge_locks.insert( - source_region_id, - (source_version, Some(ready_to_merge.clone())), - ); - Some(ready_to_merge) + self.on_check_merge(); } - fn on_ready_catch_up_logs(&mut self, catch_up_logs: CatchUpLogs) { + fn on_catch_up_logs_for_merge(&mut self, mut catch_up_logs: CatchUpLogs) { let region_id = self.fsm.region_id(); assert_eq!(region_id, catch_up_logs.merge.get_source().get_id()); - // directly append these logs to raft log and then commit + if let Some(ref cul) = self.fsm.peer.catch_up_logs { + panic!( + "{} get catch_up_logs from {} but has already got from {}", + self.fsm.peer.tag, catch_up_logs.target_region_id, cul.target_region_id + ) + } + + if let Some(ref pending_merge_state) = self.fsm.peer.pending_merge_state { + if pending_merge_state.get_commit() == catch_up_logs.merge.get_commit() { + assert_eq!( + pending_merge_state.get_target().get_id(), + catch_up_logs.target_region_id + ); + // Indicate that `on_ready_prepare_merge` has already executed. + // Mark pending_remove because its apply fsm will be destroyed. + self.fsm.peer.pending_remove = true; + // Just for saving memory. + catch_up_logs.merge.clear_entries(); + // Send CatchUpLogs back to destroy source apply fsm, + // then it will send `Noop` to trigger target apply fsm. + self.ctx + .apply_router + .schedule_task(region_id, ApplyTask::LogsUpToDate(catch_up_logs)); + return; + } + } + + // Directly append these logs to raft log and then commit them. match self .fsm .peer @@ -1935,7 +1840,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { ); // Now it has some committed entries, so mark it to take `Ready` in next round. self.fsm.has_ready = true; - self.fsm.peer.catch_up_logs = Some(catch_up_logs.logs_up_to_date); } None => { info!( @@ -1943,28 +1847,17 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { "region_id" => region_id, "peer_id" => self.fsm.peer.peer_id(), ); - // Send CatchUpLogs back to destroy source apply delegate, - // then it will send `LogsUpToDate` to target apply delegate. - self.ctx - .apply_router - .schedule_task(region_id, ApplyTask::CatchUpLogs(catch_up_logs)); } } + // Just for saving memory. + catch_up_logs.merge.clear_entries(); + self.fsm.peer.catch_up_logs = Some(catch_up_logs); } - fn on_ready_commit_merge( - &mut self, - region: metapb::Region, - source: metapb::Region, - ) -> Option> { + fn on_ready_commit_merge(&mut self, region: metapb::Region, source: metapb::Region) { self.register_split_region_check_tick(); let mut meta = self.ctx.store_meta.lock().unwrap(); - let ready_to_merge = self.check_merge_locks(&source, &mut meta); - if ready_to_merge.is_some() { - return ready_to_merge; - } - let prev = meta.region_ranges.remove(&enc_end_key(&source)); assert_eq!(prev, Some(source.get_id())); let prev = if region.get_end_key() == source.get_end_key() { @@ -1984,6 +1877,8 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { meta.set_region(&self.ctx.coprocessor_host, region, &mut self.fsm.peer); let reader = meta.readers.remove(&source.get_id()).unwrap(); reader.mark_invalid(); + + drop(meta); // make approximate size and keys updated in time. // the reason why follower need to update is that there is a issue that after merge // and then transfer leader, the new leader may have stale size and keys. @@ -1998,13 +1893,15 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { ); self.fsm.peer.heartbeat_pd(self.ctx); } - if let Err(e) = self.ctx.router.send( + if let Err(e) = self.ctx.router.force_send( source.get_id(), - PeerMsg::CasualMessage(CasualMessage::MergeResult { + PeerMsg::SignificantMsg(SignificantMsg::MergeResult { target: self.fsm.peer.peer.clone(), stale: false, }), ) { + // TODO: need to remove "are we shutting down", it should panic + // if we are not in shut-down state info!( "failed to send merge result, are we shutting down?"; "region_id" => self.fsm.region_id(), @@ -2012,7 +1909,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { "err" => %e, ); } - None } /// Handle rollbacking Merge result. @@ -2035,33 +1931,9 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { ); } self.fsm.peer.pending_merge_state = None; - { + if let Some(r) = region { let mut meta = self.ctx.store_meta.lock().unwrap(); - if let Some(r) = region { - meta.set_region(&self.ctx.coprocessor_host, r, &mut self.fsm.peer); - } - let region = self.fsm.peer.region(); - let region_id = region.get_id(); - let source_version = region.get_region_epoch().get_version(); - if let Some((exist_version, ready_to_merge)) = meta.merge_locks.remove(®ion_id) { - if exist_version > source_version { - assert!( - ready_to_merge.is_some(), - "{} unexpected empty merge state at {}", - self.fsm.peer.tag, - exist_version - ); - meta.merge_locks - .insert(region_id, (exist_version, ready_to_merge)); - } else { - assert!( - ready_to_merge.is_none(), - "{} rollback a commit merge state at {}", - self.fsm.peer.tag, - exist_version - ); - } - } + meta.set_region(&self.ctx.coprocessor_host, r, &mut self.fsm.peer); } if self.fsm.peer.is_leader() { info!( @@ -2161,11 +2033,7 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { assert_eq!(prev, Some(prev_region)); } - fn on_ready_result( - &mut self, - exec_results: &mut VecDeque, - metrics: &ApplyMetrics, - ) -> Option> { + fn on_ready_result(&mut self, exec_results: &mut VecDeque, metrics: &ApplyMetrics) { // handle executing committed log results while let Some(result) = exec_results.pop_front() { match result { @@ -2177,18 +2045,10 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { self.on_ready_split_region(derived, regions) } ExecResult::PrepareMerge { region, state } => { - self.on_ready_prepare_merge(region, state); - } - ExecResult::CatchUpLogs(catch_up_logs) => { - self.on_ready_catch_up_logs(catch_up_logs); + self.on_ready_prepare_merge(region, state) } ExecResult::CommitMerge { region, source } => { - if let Some(ready_to_merge) = - self.on_ready_commit_merge(region.clone(), source.clone()) - { - exec_results.push_front(ExecResult::CommitMerge { region, source }); - return Some(ready_to_merge); - } + self.on_ready_commit_merge(region.clone(), source.clone()) } ExecResult::RollbackMerge { region, commit } => { self.on_ready_rollback_merge(commit, Some(region)) @@ -2211,8 +2071,6 @@ impl<'a, T: Transport, C: PdClient> PeerFsmDelegate<'a, T, C> { self.ctx.store_stat.lock_cf_bytes_written += metrics.lock_cf_written_bytes; self.ctx.store_stat.engine_total_bytes_written += metrics.written_bytes; self.ctx.store_stat.engine_total_keys_written += metrics.written_keys; - - None } /// Check if a request is valid if it has valid prepare_merge/commit_merge proposal. diff --git a/src/raftstore/store/fsm/router.rs b/src/raftstore/store/fsm/router.rs deleted file mode 100644 index 3f111592701..00000000000 --- a/src/raftstore/store/fsm/router.rs +++ /dev/null @@ -1,610 +0,0 @@ -// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0. - -use super::batch::{Fsm, FsmScheduler}; -use crossbeam::channel::{SendError, TrySendError}; -use std::borrow::Cow; -use std::cell::Cell; -use std::ptr; -use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; -use std::sync::{Arc, Mutex}; -use tikv_util::collections::HashMap; -use tikv_util::mpsc; -use tikv_util::Either; - -// The FSM is notified. -const NOTIFYSTATE_NOTIFIED: usize = 0; -// The FSM is idle. -const NOTIFYSTATE_IDLE: usize = 1; -// The FSM is expected to be dropped. -const NOTIFYSTATE_DROP: usize = 2; - -struct State { - status: AtomicUsize, - data: AtomicPtr, -} - -impl Drop for State { - fn drop(&mut self) { - let ptr = self.data.swap(ptr::null_mut(), Ordering::SeqCst); - if !ptr.is_null() { - unsafe { Box::from_raw(ptr) }; - } - } -} - -/// A basic mailbox. -/// -/// Every mailbox should have one and only one owner, who will receive all -/// messages sent to this mailbox. -/// -/// When a message is sent to a mailbox, its owner will be checked whether it's -/// idle. An idle owner will be scheduled via `FsmScheduler` immediately, which -/// will drive the fsm to poll for messages. -pub struct BasicMailbox { - sender: mpsc::LooseBoundedSender, - state: Arc>, -} - -impl BasicMailbox { - #[inline] - pub fn new( - sender: mpsc::LooseBoundedSender, - fsm: Box, - ) -> BasicMailbox { - BasicMailbox { - sender, - state: Arc::new(State { - status: AtomicUsize::new(NOTIFYSTATE_IDLE), - data: AtomicPtr::new(Box::into_raw(fsm)), - }), - } - } - - /// Take the owner if it's IDLE. - pub(super) fn take_fsm(&self) -> Option> { - let previous_state = self.state.status.compare_and_swap( - NOTIFYSTATE_IDLE, - NOTIFYSTATE_NOTIFIED, - Ordering::AcqRel, - ); - if previous_state != NOTIFYSTATE_IDLE { - return None; - } - - let p = self.state.data.swap(ptr::null_mut(), Ordering::AcqRel); - if !p.is_null() { - Some(unsafe { Box::from_raw(p) }) - } else { - panic!("inconsistent status and data, something should be wrong."); - } - } - - #[inline] - pub fn len(&self) -> usize { - self.sender.len() - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.sender.is_empty() - } - - /// Notify owner via a `FsmScheduler`. - #[inline] - fn notify>(&self, scheduler: &S) { - match self.take_fsm() { - None => {} - Some(mut n) => { - n.set_mailbox(Cow::Borrowed(self)); - scheduler.schedule(n); - } - } - } - - /// Put the owner back to the state. - /// - /// It's not required that all messages should be consumed before - /// releasing a fsm. However, a fsm is guaranteed to be notified only - /// when new messages arrives after it's released. - #[inline] - pub(super) fn release(&self, fsm: Box) { - let previous = self.state.data.swap(Box::into_raw(fsm), Ordering::AcqRel); - let mut previous_status = NOTIFYSTATE_NOTIFIED; - if previous.is_null() { - previous_status = self.state.status.compare_and_swap( - NOTIFYSTATE_NOTIFIED, - NOTIFYSTATE_IDLE, - Ordering::AcqRel, - ); - match previous_status { - NOTIFYSTATE_NOTIFIED => return, - NOTIFYSTATE_DROP => { - let ptr = self.state.data.swap(ptr::null_mut(), Ordering::AcqRel); - unsafe { Box::from_raw(ptr) }; - return; - } - _ => {} - } - } - panic!("invalid release state: {:?} {}", previous, previous_status); - } - - /// Force sending a message despite the capacity limit on channel. - #[inline] - pub fn force_send>( - &self, - msg: Owner::Message, - scheduler: &S, - ) -> Result<(), SendError> { - self.sender.force_send(msg)?; - self.notify(scheduler); - Ok(()) - } - - /// Try to send a message to the mailbox. - /// - /// If there are too many pending messages, function may fail. - #[inline] - pub fn try_send>( - &self, - msg: Owner::Message, - scheduler: &S, - ) -> Result<(), TrySendError> { - self.sender.try_send(msg)?; - self.notify(scheduler); - Ok(()) - } - - /// Close the mailbox explicitly. - #[inline] - fn close(&self) { - self.sender.close_sender(); - match self.state.status.swap(NOTIFYSTATE_DROP, Ordering::AcqRel) { - NOTIFYSTATE_NOTIFIED | NOTIFYSTATE_DROP => return, - _ => {} - } - - let ptr = self.state.data.swap(ptr::null_mut(), Ordering::SeqCst); - if !ptr.is_null() { - unsafe { - Box::from_raw(ptr); - } - } - } -} - -impl Clone for BasicMailbox { - #[inline] - fn clone(&self) -> BasicMailbox { - BasicMailbox { - sender: self.sender.clone(), - state: self.state.clone(), - } - } -} - -/// A more high level mailbox. -pub struct Mailbox> { - mailbox: BasicMailbox, - scheduler: Scheduler, -} - -impl> Mailbox { - /// Force sending a message despite channel capacity limit. - #[inline] - pub fn force_send(&self, msg: Owner::Message) -> Result<(), SendError> { - self.mailbox.force_send(msg, &self.scheduler) - } - - /// Try to send a message. - #[inline] - pub fn try_send(&self, msg: Owner::Message) -> Result<(), TrySendError> { - self.mailbox.try_send(msg, &self.scheduler) - } -} - -enum CheckDoResult { - NotExist, - Invalid, - Valid(T), -} - -/// Router route messages to its target mailbox. -/// -/// Every fsm has a mailbox, hence it's necessary to have an address book -/// that can deliver messages to specified fsm, which is exact router. -/// -/// In our abstract model, every batch system has two different kind of -/// fsms. First is normal fsm, which does the common work like peers in a -/// raftstore model or apply delegate in apply model. Second is control fsm, -/// which does some work that requires a global view of resources or creates -/// missing fsm for specified address. Normal fsm and control fsm can have -/// different scheduler, but this is not required. -pub struct Router { - normals: Arc>>>, - caches: Cell>>, - pub(super) control_box: BasicMailbox, - // TODO: These two schedulers should be unified as single one. However - // it's not possible to write FsmScheduler + FsmScheduler - // for now. - normal_scheduler: Ns, - control_scheduler: Cs, -} - -impl Router -where - N: Fsm, - C: Fsm, - Ns: FsmScheduler + Clone, - Cs: FsmScheduler + Clone, -{ - pub(super) fn new( - control_box: BasicMailbox, - normal_scheduler: Ns, - control_scheduler: Cs, - ) -> Router { - Router { - normals: Arc::default(), - caches: Cell::default(), - control_box, - normal_scheduler, - control_scheduler, - } - } - - /// A helper function that tries to unify a common access pattern to - /// mailbox. - /// - /// Generally, when sending a message to a mailbox, cache should be - /// check first, if not found, lock should be acquired. - /// - /// Returns None means there is no mailbox inside the normal registry. - /// Some(None) means there is expected mailbox inside the normal registry - /// but it returns None after apply the given function. Some(Some) means - /// the given function returns Some and cache is updated if it's invalid. - #[inline] - fn check_do(&self, addr: u64, mut f: F) -> CheckDoResult - where - F: FnMut(&BasicMailbox) -> Option, - { - let caches = unsafe { &mut *self.caches.as_ptr() }; - let mut connected = true; - if let Some(mailbox) = caches.get(&addr) { - match f(mailbox) { - Some(r) => return CheckDoResult::Valid(r), - None => { - connected = false; - } - } - } - - let mailbox = { - let mut boxes = self.normals.lock().unwrap(); - match boxes.get_mut(&addr) { - Some(mailbox) => mailbox.clone(), - None => { - drop(boxes); - if !connected { - caches.remove(&addr); - } - return CheckDoResult::NotExist; - } - } - }; - - let res = f(&mailbox); - match res { - Some(r) => { - caches.insert(addr, mailbox); - CheckDoResult::Valid(r) - } - None => { - if !connected { - caches.remove(&addr); - } - CheckDoResult::Invalid - } - } - } - - /// Register a mailbox with given address. - pub fn register(&self, addr: u64, mailbox: BasicMailbox) { - let mut normals = self.normals.lock().unwrap(); - if let Some(mailbox) = normals.insert(addr, mailbox) { - mailbox.close(); - } - } - - pub fn register_all(&self, mailboxes: Vec<(u64, BasicMailbox)>) { - let mut normals = self.normals.lock().unwrap(); - normals.reserve(mailboxes.len()); - for (addr, mailbox) in mailboxes { - if let Some(m) = normals.insert(addr, mailbox) { - m.close(); - } - } - } - - /// Get the mailbox of specified address. - pub fn mailbox(&self, addr: u64) -> Option> { - let res = self.check_do(addr, |mailbox| { - if mailbox.sender.is_sender_connected() { - Some(Mailbox { - mailbox: mailbox.clone(), - scheduler: self.normal_scheduler.clone(), - }) - } else { - None - } - }); - match res { - CheckDoResult::Valid(r) => Some(r), - _ => None, - } - } - - /// Get the mailbox of control fsm. - pub fn control_mailbox(&self) -> Mailbox { - Mailbox { - mailbox: self.control_box.clone(), - scheduler: self.control_scheduler.clone(), - } - } - - /// Try to send a message to specified address. - /// - /// If Either::Left is returned, then the message is sent. Otherwise, - /// it indicates mailbox is not found. - #[inline] - pub fn try_send( - &self, - addr: u64, - msg: N::Message, - ) -> Either>, N::Message> { - let mut msg = Some(msg); - let res = self.check_do(addr, |mailbox| { - let m = msg.take().unwrap(); - match mailbox.try_send(m, &self.normal_scheduler) { - Ok(()) => Some(Ok(())), - r @ Err(TrySendError::Full(_)) => { - // TODO: report channel full - Some(r) - } - Err(TrySendError::Disconnected(m)) => { - msg = Some(m); - None - } - } - }); - match res { - CheckDoResult::Valid(r) => Either::Left(r), - CheckDoResult::Invalid => Either::Left(Err(TrySendError::Disconnected(msg.unwrap()))), - CheckDoResult::NotExist => Either::Right(msg.unwrap()), - } - } - - /// Send the message to specified address. - #[inline] - pub fn send(&self, addr: u64, msg: N::Message) -> Result<(), TrySendError> { - match self.try_send(addr, msg) { - Either::Left(res) => res, - Either::Right(m) => Err(TrySendError::Disconnected(m)), - } - } - - /// Force sending message to specified address despite the capacity - /// limit of mailbox. - #[inline] - pub fn force_send(&self, addr: u64, msg: N::Message) -> Result<(), SendError> { - match self.send(addr, msg) { - Ok(()) => Ok(()), - Err(TrySendError::Full(m)) => { - let caches = unsafe { &mut *self.caches.as_ptr() }; - caches[&addr].force_send(m, &self.normal_scheduler) - } - Err(TrySendError::Disconnected(m)) => Err(SendError(m)), - } - } - - /// Force sending message to control fsm. - #[inline] - pub fn send_control(&self, msg: C::Message) -> Result<(), TrySendError> { - match self.control_box.try_send(msg, &self.control_scheduler) { - Ok(()) => Ok(()), - r @ Err(TrySendError::Full(_)) => { - // TODO: record metrics. - r - } - r => r, - } - } - - /// Try to notify all normal fsm a message. - pub fn broadcast_normal(&self, mut msg_gen: impl FnMut() -> N::Message) { - let mailboxes = self.normals.lock().unwrap(); - for mailbox in mailboxes.values() { - let _ = mailbox.force_send(msg_gen(), &self.normal_scheduler); - } - } - - /// Try to notify all fsm that the cluster is being shutdown. - pub fn broadcast_shutdown(&self) { - info!("broadcasting shutdown"); - unsafe { &mut *self.caches.as_ptr() }.clear(); - let mut mailboxes = self.normals.lock().unwrap(); - for (addr, mailbox) in mailboxes.drain() { - debug!("[region {}] shutdown mailbox", addr); - mailbox.close(); - } - self.control_box.close(); - self.normal_scheduler.shutdown(); - self.control_scheduler.shutdown(); - } - - /// Close the mailbox of address. - pub fn close(&self, addr: u64) { - info!("[region {}] shutdown mailbox", addr); - unsafe { &mut *self.caches.as_ptr() }.remove(&addr); - let mut mailboxes = self.normals.lock().unwrap(); - if let Some(mb) = mailboxes.remove(&addr) { - mb.close(); - } - } -} - -impl Clone for Router { - fn clone(&self) -> Router { - Router { - normals: self.normals.clone(), - caches: Cell::default(), - control_box: self.control_box.clone(), - // These two schedulers should be unified as single one. However - // it's not possible to write FsmScheduler + FsmScheduler - // for now. - normal_scheduler: self.normal_scheduler.clone(), - control_scheduler: self.control_scheduler.clone(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::raftstore::store::fsm::batch::tests::Message; - use crate::raftstore::store::fsm::batch::{self, tests::*}; - use crossbeam::channel::{RecvTimeoutError, SendError, TryRecvError, TrySendError}; - use std::sync::atomic::AtomicUsize; - use std::sync::Arc; - use std::time::Duration; - use test::Bencher; - - fn counter_closure(counter: &Arc) -> Message { - let c = counter.clone(); - Some(Box::new(move |_: &mut Runner| { - c.fetch_add(1, Ordering::SeqCst); - })) - } - - fn noop() -> Message { - None - } - - fn unreachable() -> Message { - Some(Box::new(|_: &mut Runner| unreachable!())) - } - - #[test] - fn test_basic() { - let (control_tx, mut control_fsm) = new_runner(10); - let (control_drop_tx, control_drop_rx) = mpsc::unbounded(); - control_fsm.sender = Some(control_drop_tx); - let (router, mut system) = batch::create_system(2, 2, control_tx, control_fsm); - let builder = Builder::new(); - system.spawn("test".to_owned(), builder); - - // Missing mailbox should report error. - match router.force_send(1, unreachable()) { - Err(SendError(_)) => (), - Ok(_) => panic!("send should fail"), - } - match router.send(1, unreachable()) { - Err(TrySendError::Disconnected(_)) => (), - Ok(_) => panic!("send should fail"), - Err(TrySendError::Full(_)) => panic!("expect disconnected."), - } - - let (tx, rx) = mpsc::unbounded(); - let router_ = router.clone(); - // Control mailbox should be connected. - router - .send_control(Some(Box::new(move |_: &mut Runner| { - let (sender, mut runner) = new_runner(10); - let (tx1, rx1) = mpsc::unbounded(); - runner.sender = Some(tx1); - let mailbox = BasicMailbox::new(sender, runner); - router_.register(1, mailbox); - tx.send(rx1).unwrap(); - }))) - .unwrap(); - let runner_drop_rx = rx.recv_timeout(Duration::from_secs(3)).unwrap(); - - // Registered mailbox should be connected. - router.force_send(1, noop()).unwrap(); - router.send(1, noop()).unwrap(); - - // Send should respect capacity limit, while force_send not. - let (tx, rx) = mpsc::unbounded(); - router - .send( - 1, - Some(Box::new(move |_: &mut Runner| { - rx.recv_timeout(Duration::from_secs(100)).unwrap(); - })), - ) - .unwrap(); - let counter = Arc::new(AtomicUsize::new(0)); - let sent_cnt = (0..) - .take_while(|_| router.send(1, counter_closure(&counter)).is_ok()) - .count(); - match router.send(1, counter_closure(&counter)) { - Err(TrySendError::Full(_)) => {} - Err(TrySendError::Disconnected(_)) => panic!("mailbox should still be connected."), - Ok(_) => panic!("send should fail"), - } - router.force_send(1, counter_closure(&counter)).unwrap(); - tx.send(1).unwrap(); - // Flush. - let (tx, rx) = mpsc::unbounded(); - router - .force_send( - 1, - Some(Box::new(move |_: &mut Runner| { - tx.send(1).unwrap(); - })), - ) - .unwrap(); - rx.recv_timeout(Duration::from_secs(100)).unwrap(); - - let c = counter.load(Ordering::SeqCst); - assert_eq!(c, sent_cnt + 1); - - // close should release resources. - assert_eq!(runner_drop_rx.try_recv(), Err(TryRecvError::Empty)); - router.close(1); - assert_eq!( - runner_drop_rx.recv_timeout(Duration::from_secs(3)), - Err(RecvTimeoutError::Disconnected) - ); - match router.send(1, unreachable()) { - Err(TrySendError::Disconnected(_)) => (), - Ok(_) => panic!("send should fail."), - Err(TrySendError::Full(_)) => panic!("sender should be closed"), - } - match router.force_send(1, unreachable()) { - Err(SendError(_)) => (), - Ok(_) => panic!("send should fail."), - } - assert_eq!(control_drop_rx.try_recv(), Err(TryRecvError::Empty)); - system.shutdown(); - assert_eq!( - control_drop_rx.recv_timeout(Duration::from_secs(3)), - Err(RecvTimeoutError::Disconnected) - ); - } - - #[bench] - fn bench_send(b: &mut Bencher) { - let (control_tx, control_fsm) = new_runner(100000); - let (router, mut system) = batch::create_system(2, 2, control_tx, control_fsm); - let builder = Builder::new(); - system.spawn("test".to_owned(), builder); - let (normal_tx, normal_fsm) = new_runner(100000); - let normal_box = BasicMailbox::new(normal_tx, normal_fsm); - router.register(1, normal_box); - - b.iter(|| { - router.send(1, noop()).unwrap(); - }); - system.shutdown(); - } -} diff --git a/src/raftstore/store/fsm/store.rs b/src/raftstore/store/fsm/store.rs index f78b21df535..bef710b028c 100644 --- a/src/raftstore/store/fsm/store.rs +++ b/src/raftstore/store/fsm/store.rs @@ -1,5 +1,6 @@ // Copyright 2016 TiKV Project Authors. Licensed under Apache-2.0. +use batch_system::{BasicMailbox, BatchRouter, BatchSystem, Fsm, HandlerBuilder, PollHandler}; use crossbeam::channel::{TryRecvError, TrySendError}; use engine::rocks; use engine::rocks::CompactionJobInfo; @@ -14,7 +15,8 @@ use kvproto::raft_serverpb::{PeerState, RaftMessage, RegionLocalState}; use raft::{Ready, StateRole}; use std::collections::BTreeMap; use std::collections::Bound::{Excluded, Included, Unbounded}; -use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::ops::Deref; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use std::{mem, thread, u64}; @@ -33,10 +35,9 @@ use crate::raftstore::store::fsm::peer::{ #[cfg(not(feature = "no-fail"))] use crate::raftstore::store::fsm::ApplyTaskRes; use crate::raftstore::store::fsm::{ - batch, create_apply_batch_system, ApplyBatchSystem, ApplyPollerBuilder, ApplyRouter, ApplyTask, - BasicMailbox, BatchRouter, BatchSystem, HandlerBuilder, + create_apply_batch_system, ApplyBatchSystem, ApplyPollerBuilder, ApplyRouter, ApplyTask, }; -use crate::raftstore::store::fsm::{ApplyNotifier, Fsm, PollHandler, RegionProposal}; +use crate::raftstore::store::fsm::{ApplyNotifier, RegionProposal}; use crate::raftstore::store::keys::{self, data_end_key, data_key, enc_end_key, enc_start_key}; use crate::raftstore::store::local_metrics::RaftMetrics; use crate::raftstore::store::metrics::*; @@ -95,11 +96,6 @@ pub struct StoreMeta { /// An inverse mapping of `pending_merge_targets` used to let source peer help target peer to clean up related entry. /// source_region_id -> target_region_id pub targets_map: HashMap, - /// In raftstore, the execute order of `PrepareMerge` and `CommitMerge` is not certain because of the messages - /// belongs two regions. To make them in order, `PrepareMerge` will set this structure and `CommitMerge` will retry - /// later if there is no related lock. - /// source_region_id -> (version, BiLock). - pub merge_locks: HashMap>)>, } impl StoreMeta { @@ -113,7 +109,6 @@ impl StoreMeta { pending_snapshot_regions: Vec::default(), pending_merge_targets: HashMap::default(), targets_map: HashMap::default(), - merge_locks: HashMap::default(), } } @@ -134,7 +129,18 @@ impl StoreMeta { } } -pub type RaftRouter = BatchRouter; +#[derive(Clone)] +pub struct RaftRouter { + pub router: BatchRouter, +} + +impl Deref for RaftRouter { + type Target = BatchRouter; + + fn deref(&self) -> &BatchRouter { + &self.router + } +} impl RaftRouter { pub fn send_raft_message( @@ -598,14 +604,6 @@ impl PollHandler for RaftPoller Option { let mut expected_msg_count = None; - if peer.have_pending_merge_apply_result() { - expected_msg_count = Some(peer.receiver.len()); - let mut delegate = PeerFsmDelegate::new(peer, &mut self.poll_ctx); - if !delegate.resume_handling_pending_apply_result() { - return expected_msg_count; - } - expected_msg_count = None; - } fail_point!( "pause_on_peer_collect_message", @@ -1083,8 +1081,9 @@ impl RaftBatchSystem { cfg.snap_apply_batch_size.0 as usize, cfg.use_delete_range, cfg.clean_stale_peer_delay.0, + self.router(), ); - let timer = RegionRunner::new_timer(); + let timer = region_runner.new_timer(); box_try!(workers.region_worker.start_with_timer(region_runner, timer)); let raftlog_gc_runner = RaftlogGcRunner::new(None); @@ -1099,6 +1098,7 @@ impl RaftBatchSystem { self.router.clone(), Arc::clone(&engines.kv), workers.pd_worker.scheduler(), + cfg.pd_store_heartbeat_tick_interval.as_secs(), ); box_try!(workers.pd_worker.start(pd_runner)); @@ -1151,20 +1151,21 @@ impl RaftBatchSystem { pub fn create_raft_batch_system(cfg: &Config) -> (RaftRouter, RaftBatchSystem) { let (store_tx, store_fsm) = StoreFsm::new(cfg); let (apply_router, apply_system) = create_apply_batch_system(&cfg); - let (router, system) = batch::create_system( + let (router, system) = batch_system::create_system( cfg.store_pool_size, cfg.store_max_batch_size, store_tx, store_fsm, ); + let raft_router = RaftRouter { router }; let system = RaftBatchSystem { system, workers: None, apply_router, apply_system, - router: router.clone(), + router: raft_router.clone(), }; - (router, system) + (raft_router, system) } impl<'a, T: Transport, C: PdClient> StoreFsmDelegate<'a, T, C> { @@ -1348,6 +1349,7 @@ impl<'a, T: Transport, C: PdClient> StoreFsmDelegate<'a, T, C> { self.ctx.raft_metrics.message_dropped.stale_msg += 1; return Ok(false); } + let mut is_overlapped = false; let mut regions_to_destroy = vec![]; for (_, id) in meta.region_ranges.range(( @@ -1381,6 +1383,8 @@ impl<'a, T: Transport, C: PdClient> StoreFsmDelegate<'a, T, C> { is_overlapped = true; if msg.get_region_epoch().get_version() > exist_region.get_region_epoch().get_version() { + // If new region's epoch version is greater than exist region's, the exist region + // may has been merged already. let _ = self.ctx.router.force_send( exist_region.get_id(), PeerMsg::CasualMessage(CasualMessage::RegionOverlapped), @@ -1397,7 +1401,7 @@ impl<'a, T: Transport, C: PdClient> StoreFsmDelegate<'a, T, C> { .router .force_send( id, - PeerMsg::CasualMessage(CasualMessage::MergeResult { + PeerMsg::SignificantMsg(SignificantMsg::MergeResult { target: target.clone(), stale: true, }), @@ -2027,35 +2031,12 @@ fn calc_region_declined_bytes( region_declined_bytes } -// check whether the range is covered by existing regions. -fn is_range_covered<'a, F: Fn(u64) -> &'a metapb::Region>( - region_ranges: &BTreeMap, - get_region: F, - mut start: Vec, - end: Vec, -) -> bool { - for (end_key, &id) in region_ranges.range((Excluded(start.clone()), Unbounded::)) { - let region = get_region(id); - // find a missing range - if start < enc_start_key(region) { - return false; - } - if *end_key >= end { - return true; - } - start = end_key.clone(); - } - false -} - #[cfg(test)] mod tests { use std::collections::BTreeMap; - use std::collections::HashMap; use crate::raftstore::coprocessor::properties::{IndexHandle, IndexHandles, SizeProperties}; use crate::storage::kv::CompactedEvent; - use protobuf::RepeatedField; use super::*; @@ -2101,81 +2082,4 @@ mod tests { let expected_declined_bytes = vec![(2, 8192), (3, 4096)]; assert_eq!(declined_bytes, expected_declined_bytes); } - - #[test] - fn test_is_range_covered() { - let meta = vec![(b"b", b"d"), (b"d", b"e"), (b"e", b"f"), (b"f", b"h")]; - let mut region_ranges = BTreeMap::new(); - let mut region_peers = HashMap::new(); - - { - for (i, (start, end)) in meta.into_iter().enumerate() { - let mut region = metapb::Region::new(); - let peer = metapb::Peer::new(); - region.set_peers(RepeatedField::from_vec(vec![peer])); - region.set_start_key(start.to_vec()); - region.set_end_key(end.to_vec()); - - region_ranges.insert(enc_end_key(®ion), i as u64); - region_peers.insert(i as u64, region); - } - - let check_range = |start: &[u8], end: &[u8]| { - is_range_covered( - ®ion_ranges, - |id: u64| ®ion_peers[&id], - data_key(start), - data_end_key(end), - ) - }; - - assert!(!check_range(b"a", b"c")); - assert!(check_range(b"b", b"d")); - assert!(check_range(b"b", b"e")); - assert!(check_range(b"e", b"f")); - assert!(check_range(b"b", b"g")); - assert!(check_range(b"e", b"h")); - assert!(!check_range(b"e", b"n")); - assert!(!check_range(b"g", b"n")); - assert!(!check_range(b"o", b"z")); - assert!(!check_range(b"", b"")); - } - - let meta = vec![(b"b", b"d"), (b"e", b"f"), (b"f", b"h")]; - region_ranges.clear(); - region_peers.clear(); - { - for (i, (start, end)) in meta.into_iter().enumerate() { - let mut region = metapb::Region::new(); - let peer = metapb::Peer::new(); - region.set_peers(RepeatedField::from_vec(vec![peer])); - region.set_start_key(start.to_vec()); - region.set_end_key(end.to_vec()); - - region_ranges.insert(enc_end_key(®ion), i as u64); - region_peers.insert(i as u64, region); - } - - let check_range = |start: &[u8], end: &[u8]| { - is_range_covered( - ®ion_ranges, - |id: u64| ®ion_peers[&id], - data_key(start), - data_end_key(end), - ) - }; - - assert!(!check_range(b"a", b"c")); - assert!(check_range(b"b", b"d")); - assert!(!check_range(b"b", b"e")); - assert!(check_range(b"e", b"f")); - assert!(!check_range(b"b", b"g")); - assert!(check_range(b"e", b"g")); - assert!(check_range(b"e", b"h")); - assert!(!check_range(b"e", b"n")); - assert!(!check_range(b"g", b"n")); - assert!(!check_range(b"o", b"z")); - assert!(!check_range(b"", b"")); - } - } } diff --git a/src/raftstore/store/local_metrics.rs b/src/raftstore/store/local_metrics.rs index 57e7b61251c..6545f77696b 100644 --- a/src/raftstore/store/local_metrics.rs +++ b/src/raftstore/store/local_metrics.rs @@ -75,6 +75,8 @@ pub struct RaftMessageMetrics { pub heartbeat_resp: u64, pub transfer_leader: u64, pub timeout_now: u64, + pub read_index: u64, + pub read_index_resp: u64, } impl RaftMessageMetrics { @@ -147,6 +149,18 @@ impl RaftMessageMetrics { .inc_by(self.timeout_now as i64); self.timeout_now = 0; } + if self.read_index > 0 { + STORE_RAFT_SENT_MESSAGE_COUNTER_VEC + .with_label_values(&["read_index"]) + .inc_by(self.read_index as i64); + self.read_index = 0; + } + if self.read_index_resp > 0 { + STORE_RAFT_SENT_MESSAGE_COUNTER_VEC + .with_label_values(&["read_index_resp"]) + .inc_by(self.read_index_resp as i64); + self.read_index_resp = 0; + } } } diff --git a/src/raftstore/store/msg.rs b/src/raftstore/store/msg.rs index d953e62862e..9d9d8d04b51 100644 --- a/src/raftstore/store/msg.rs +++ b/src/raftstore/store/msg.rs @@ -11,6 +11,7 @@ use kvproto::raft_cmdpb::{RaftCmdRequest, RaftCmdResponse}; use kvproto::raft_serverpb::RaftMessage; use raft::SnapshotStatus; +use crate::raftstore::store::fsm::apply::CatchUpLogs; use crate::raftstore::store::fsm::apply::TaskRes as ApplyTaskRes; use crate::raftstore::store::util::KeysInfoFormatter; use crate::raftstore::store::SnapKey; @@ -142,7 +143,7 @@ impl StoreTick { /// Some significant messages sent to raftstore. Raftstore will dispatch these messages to Raft /// groups to update some important internal status. -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum SignificantMsg { /// Reports whether the snapshot sending is successful or not. SnapshotStatus { @@ -158,6 +159,15 @@ pub enum SignificantMsg { region_id: u64, to_peer_id: u64, }, + /// Source region catch up logs for merging + CatchUpLogs(CatchUpLogs), + /// Result of the fact that the region is merged. + MergeResult { + target: metapb::Peer, + // True means it's a stale merge source. + // False means it came from target region. + stale: bool, + }, } /// Message that will be sent to a peer. @@ -196,11 +206,6 @@ pub enum CasualMessage { region_epoch: RegionEpoch, policy: CheckPolicy, }, - /// Result of querying pd whether a region is merged. - MergeResult { - target: metapb::Peer, - stale: bool, - }, /// Remove snapshot files in `snaps`. GcSnap { snaps: Vec<(SnapKey, bool)>, @@ -209,6 +214,8 @@ pub enum CasualMessage { ClearRegionSize, /// Indicate a target region is overlapped. RegionOverlapped, + /// Notifies that a new snapshot has been generated. + SnapshotGenerated, } impl fmt::Debug for CasualMessage { @@ -235,11 +242,6 @@ impl fmt::Debug for CasualMessage { write!(fmt, "compaction declined bytes {}", bytes) } CasualMessage::HalfSplitRegion { .. } => write!(fmt, "Half Split"), - CasualMessage::MergeResult { target, stale } => write! { - fmt, - "target: {:?}, successful: {}", - target, stale - }, CasualMessage::GcSnap { ref snaps } => write! { fmt, "gc snaps {:?}", @@ -250,6 +252,7 @@ impl fmt::Debug for CasualMessage { "clear region size" }, CasualMessage::RegionOverlapped => write!(fmt, "RegionOverlapped"), + CasualMessage::SnapshotGenerated => write!(fmt, "SnapshotGenerated"), } } } diff --git a/src/raftstore/store/peer.rs b/src/raftstore/store/peer.rs index 79d9ffa22ac..2d1e10a5da9 100644 --- a/src/raftstore/store/peer.rs +++ b/src/raftstore/store/peer.rs @@ -3,7 +3,6 @@ use std::cell::RefCell; use std::collections::Bound::{Excluded, Unbounded}; use std::collections::VecDeque; -use std::sync::atomic::{AtomicBool, AtomicU64}; use std::sync::{atomic, Arc}; use std::time::{Duration, Instant}; use std::{cmp, mem, u64, usize}; @@ -18,7 +17,7 @@ use kvproto::raft_cmdpb::{ TransferLeaderResponse, }; use kvproto::raft_serverpb::{ - MergeMsgType, MergeState, PeerState, RaftApplyState, RaftMessage, RaftSnapshotData, + ExtraMessageType, MergeState, PeerState, RaftApplyState, RaftMessage, RaftSnapshotData, }; use protobuf::{self, Message}; use raft::eraftpb::{self, ConfChangeType, EntryType, MessageType}; @@ -31,9 +30,10 @@ use uuid::Uuid; use crate::pd::{PdTask, INVALID_ID}; use crate::raftstore::coprocessor::{CoprocessorHost, RegionChangeEvent}; +use crate::raftstore::store::fsm::apply::CatchUpLogs; use crate::raftstore::store::fsm::store::PollContext; use crate::raftstore::store::fsm::{ - apply, Apply, ApplyMetrics, ApplyTask, ApplyTaskRes, GroupState, Proposal, RegionProposal, + apply, Apply, ApplyMetrics, ApplyTask, GroupState, Proposal, RegionProposal, }; use crate::raftstore::store::keys::{self, enc_end_key, enc_start_key}; use crate::raftstore::store::worker::{ReadDelegate, ReadProgress, RegionTask}; @@ -106,9 +106,9 @@ bitflags! { // TODO: maybe declare it as protobuf struct is better. /// A bitmap contains some useful flags when dealing with `eraftpb::Entry`. pub struct ProposalContext: u8 { - const SYNC_LOG = 0b00000001; - const SPLIT = 0b00000010; - const PREPARE_MERGE = 0b00000100; + const SYNC_LOG = 0b0000_0001; + const SPLIT = 0b0000_0010; + const PREPARE_MERGE = 0b0000_0100; } } @@ -155,19 +155,6 @@ pub struct CheckTickResult { up_to_date: bool, } -/// A struct that stores the state to wait for `PrepareMerge` apply result. -/// -/// When handling the apply result of a `CommitMerge`, the source peer may have -/// not handle the apply result of the `PrepareMerge`, so the target peer has -/// to abort current handle process and wait for it asynchronously. -pub struct WaitApplyResultState { - /// The following apply results waiting to be handled, including the `CommitMerge`. - /// These will be handled once `ready_to_merge` is true. - pub results: Vec, - /// It is used by target peer to check whether the apply result of `PrepareMerge` is handled. - pub ready_to_merge: Arc, -} - pub struct Peer { /// The ID of the Region which this Peer belongs to. region_id: u64, @@ -194,6 +181,7 @@ pub struct Peer { /// If it fails to send messages to leader. pub leader_unreachable: bool, /// Whether this peer is destroyed asynchronously. + /// If it's true when merging, its data in storeMeta will be removed early by the target peer pub pending_remove: bool, /// If a snapshot is being applied asynchronously, messages should not be sent. pending_messages: Vec, @@ -203,7 +191,6 @@ pub struct Peer { pub peers_start_pending_time: Vec<(u64, Instant)>, /// A inaccurate cache about which peer is marked as down. down_peer_ids: Vec, - pub recent_conf_change_time: Instant, /// An inaccurate difference in region size since last reset. /// It is used to decide whether split check is needed. @@ -237,10 +224,8 @@ pub struct Peer { last_committed_prepare_merge_idx: u64, /// The merge related state. It indicates this Peer is in merging. pub pending_merge_state: Option, - /// The state to wait for `PrepareMerge` apply result. - pub pending_merge_apply_result: Option, /// source region is catching up logs for merge - pub catch_up_logs: Option>, + pub catch_up_logs: Option, /// Write Statistics for PD to schedule hot spot. pub peer_stat: PeerStat, @@ -294,7 +279,6 @@ impl Peer { peer_heartbeats: HashMap::default(), peers_start_pending_time: vec![], down_peer_ids: vec![], - recent_conf_change_time: Instant::now(), size_diff_hint: 0, delete_keys_hint: 0, approximate_size: None, @@ -318,7 +302,6 @@ impl Peer { raft_log_size_hint: 0, leader_lease: Lease::new(cfg.raft_store_max_leader_lease()), pending_messages: vec![], - pending_merge_apply_result: None, peer_stat: PeerStat::default(), catch_up_logs: None, }; @@ -364,13 +347,13 @@ impl Peer { // Though the entries is empty, it is possible that one source peer has caught up the logs // but commit index is not updated. If Other source peers are already destroyed, so the raft // group will not make any progress, namely the source peer can not get the latest commit index anymore. - // Here update the commit index to let source apply rest uncommitted entires. - if merge.get_commit() > self.raft_group.raft.raft_log.committed { + // Here update the commit index to let source apply rest uncommitted entries. + return if merge.get_commit() > self.raft_group.raft.raft_log.committed { self.raft_group.raft.raft_log.commit_to(merge.get_commit()); - return Some(merge.get_commit()); + Some(merge.get_commit()) } else { - return None; - } + None + }; } let first = entries.first().unwrap(); // make sure message should be with index not smaller than committed @@ -409,12 +392,12 @@ impl Peer { ); return None; } - // If initialized is false, it implicitly means applyfsm does not exist now. + // If initialized is false, it implicitly means apply fsm does not exist now. let initialized = self.get_store().is_initialized(); - // If async_remove is true, it means peerfsm needs to be removed after its - // corresponding applyfsm was removed. - // If it is false, it means either applyfsm does not exist or there is no task - // in applyfsm so it's ok to remove peerfsm immediately. + // If async_remove is true, it means peer fsm needs to be removed after its + // corresponding apply fsm was removed. + // If it is false, it means either apply fsm does not exist or there is no task + // in apply fsm so it's ok to remove peer fsm immediately. let async_remove = if self.is_applying_snapshot() { if !self.mut_store().cancel_applying_snap() { info!( @@ -675,6 +658,8 @@ impl Peer { MessageType::MsgHeartbeat => metrics.heartbeat += 1, MessageType::MsgHeartbeatResponse => metrics.heartbeat_resp += 1, MessageType::MsgTransferLeader => metrics.transfer_leader += 1, + MessageType::MsgReadIndex => metrics.read_index += 1, + MessageType::MsgReadIndexResp => metrics.read_index_resp += 1, MessageType::MsgTimeoutNow => { // After a leader transfer procedure is triggered, the lease for // the old leader may be expired earlier than usual, since a new leader @@ -694,15 +679,17 @@ impl Peer { | MessageType::MsgPropose | MessageType::MsgUnreachable | MessageType::MsgSnapStatus - | MessageType::MsgCheckQuorum - | MessageType::MsgReadIndex - | MessageType::MsgReadIndexResp => {} + | MessageType::MsgCheckQuorum => {} } } } /// Steps the raft message. - pub fn step(&mut self, mut m: eraftpb::Message) -> Result<()> { + pub fn step( + &mut self, + ctx: &mut PollContext, + mut m: eraftpb::Message, + ) -> Result<()> { fail_point!( "step_message_3_1", { self.peer.get_store_id() == 3 && self.region_id == 1 }, @@ -736,6 +723,11 @@ impl Peer { } } + if msg_type == MessageType::MsgTransferLeader { + self.execute_transfer_leader(ctx, &m); + return Ok(()); + } + self.raft_group.step(m)?; Ok(()) } @@ -1106,6 +1098,15 @@ impl Peer { "peer_id" => self.peer.get_id(), ); + let before_handle_raft_ready_1003 = || { + fail_point!( + "before_handle_raft_ready_1003", + self.peer.get_id() == 1003 && self.is_leader(), + |_| {} + ); + }; + before_handle_raft_ready_1003(); + let mut ready = self.raft_group.ready_since(self.last_applying_idx); self.on_role_changed(ctx, &ready); @@ -1265,6 +1266,25 @@ impl Peer { merge_to_be_update = false; } } + + fail_point!( + "before_send_rollback_merge_1003", + if self.peer_id() != 1003 { + false + } else { + let index = entry.get_index(); + let data = entry.get_data(); + if data.is_empty() || entry.get_entry_type() != EntryType::EntryNormal { + false + } else { + let cmd: RaftCmdRequest = util::parse_data_at(data, index, &self.tag); + cmd.has_admin_request() + && cmd.get_admin_request().get_cmd_type() + == AdminCmdType::RollbackMerge + } + }, + |_| {} + ); } if !committed_entries.is_empty() { self.last_applying_idx = committed_entries.last().unwrap().get_index(); @@ -1277,6 +1297,7 @@ impl Peer { ctx.apply_router .schedule_task(self.region_id, ApplyTask::apply(apply)); } + fail_point!("after_send_to_apply_1003", self.peer_id() == 1003, |_| {}); } self.apply_reads(ctx, &ready); @@ -1353,7 +1374,8 @@ impl Peer { // `ready`. if !self.is_leader() { // NOTE: there could still be some pending reads proposed by the peer when it was - // leader. They will be cleared in `clear_uncommitted` later in the function. + // leader. They will be cleared in `clear_uncommitted_on_role_change` later in + // the function. self.pending_reads.advance_replica_reads(states); self.post_pending_read_index_on_replica(ctx); } else if self.ready_to_handle_read() { @@ -1371,7 +1393,7 @@ impl Peer { if ready.ss.is_some() { let term = self.term(); // all uncommitted reads will be dropped silently in raft. - self.pending_reads.clear_uncommitted(term); + self.pending_reads.clear_uncommitted_on_role_change(term); } if let Some(propose_time) = propose_time { @@ -1737,43 +1759,71 @@ impl Peer { self.raft_group.transfer_leader(peer.get_id()); } + fn pre_transfer_leader(&mut self, peer: &metapb::Peer) -> bool { + // Checks if safe to transfer leader. + if self.raft_group.raft.has_pending_conf() { + info!( + "reject transfer leader due to pending conf change"; + "region_id" => self.region_id, + "peer_id" => self.peer.get_id(), + "peer" => ?peer, + ); + return false; + } + + // Broadcast heartbeat to make sure followers commit the entries immediately. + // It's only necessary to ping the target peer, but ping all for simplicity. + self.raft_group.ping(); + let mut msg = eraftpb::Message::new(); + msg.set_to(peer.get_id()); + msg.set_msg_type(eraftpb::MessageType::MsgTransferLeader); + msg.set_from(self.peer_id()); + // log term here represents the term of last log. For leader, the term of last + // log is always its current term. Not just set term because raft library forbids + // setting it for MsgTransferLeader messages. + msg.set_log_term(self.term()); + self.raft_group.raft.msgs.push(msg); + true + } + fn ready_to_transfer_leader( &self, ctx: &mut PollContext, + mut index: u64, peer: &metapb::Peer, - ) -> bool { + ) -> Option<&'static str> { let peer_id = peer.get_id(); let status = self.raft_group.status_ref(); let progress = status.progress.unwrap(); if !progress.voters().contains_key(&peer_id) { - return false; + return Some("non voter"); } - for progress in progress.voters().values() { + for (id, progress) in progress.voters() { if progress.state == ProgressState::Snapshot { - return false; + return Some("pending snapshot"); + } + if *id == peer_id && index == 0 { + // index will be zero if it's sent from an instance without + // pre-transfer-leader feature. Set it to matched to make it + // possible to transfer leader to an older version. It may be + // useful during rolling restart. + index = progress.matched; } } - // Checks if safe to transfer leader. - // Check `has_pending_conf` is necessary because `recent_conf_change_time` is updated - // on applied. TODO: fix the transfer leader issue in Raft. if self.raft_group.raft.has_pending_conf() - || duration_to_sec(self.recent_conf_change_time.elapsed()) - < ctx.cfg.raft_reject_transfer_leader_duration.as_secs() as f64 + || self.raft_group.raft.pending_conf_index > index { - debug!( - "reject transfer leader due to the region was config changed recently"; - "region_id" => self.region_id, - "peer_id" => self.peer.get_id(), - "peer" => ?peer, - ); - return false; + return Some("pending conf change"); } let last_index = self.get_store().last_index(); - last_index <= progress.voters()[&peer_id].matched + ctx.cfg.leader_transfer_max_log_lag + if last_index >= index + ctx.cfg.leader_transfer_max_log_lag { + return Some("log gap"); + } + None } fn read_local(&mut self, ctx: &mut PollContext, req: RaftCmdRequest, cb: Callback) { @@ -2089,7 +2139,77 @@ impl Peer { Ok(propose_index) } - // Return true to if the transfer leader request is accepted. + fn execute_transfer_leader( + &mut self, + ctx: &mut PollContext, + msg: &eraftpb::Message, + ) { + // log_term is set by original leader, represents the term last log is written + // in, which should be equal to the original leader's term. + if msg.get_log_term() != self.term() { + return; + } + + if self.is_leader() { + let from = match self.get_peer_from_cache(msg.get_from()) { + Some(p) => p, + None => return, + }; + match self.ready_to_transfer_leader(ctx, msg.get_index(), &from) { + Some(reason) => { + info!( + "reject to transfer leader"; + "region_id" => self.region_id, + "peer_id" => self.peer.get_id(), + "to" => ?from, + "reason" => reason, + "index" => msg.get_index(), + "last_index" => self.get_store().last_index(), + ); + } + None => self.transfer_leader(&from), + } + return; + } + + if self.is_applying_snapshot() + || self.has_pending_snapshot() + || msg.get_from() != self.leader_id() + { + info!( + "reject transferring leader"; + "region_id" =>self.region_id, + "peer_id" => self.peer.get_id(), + "from" => msg.get_from(), + ); + return; + } + + let mut msg = eraftpb::Message::new(); + msg.set_from(self.peer_id()); + msg.set_to(self.leader_id()); + msg.set_msg_type(eraftpb::MessageType::MsgTransferLeader); + msg.set_index(self.get_store().applied_index()); + msg.set_log_term(self.term()); + self.raft_group.raft.msgs.push(msg); + } + + /// Return true to if the transfer leader request is accepted. + /// + /// When transferring leadership begins, leader sends a pre-transfer + /// to target follower first to ensures it's ready to become leader. + /// After that the real transfer leader process begin. + /// + /// 1. pre_transfer_leader on leader: + /// Leader will send a MsgTransferLeader to follower. + /// 2. execute_transfer_leader on follower + /// If follower passes all necessary checks, it will reply an + /// ACK with type MsgTransferLeader and its promised persistent index. + /// 3. execute_transfer_leader on leader: + /// Leader checks if it's appropriate to transfer leadership. If it + /// does, it calls raft transfer_leader API to do the remaining work. + /// + /// See also: tikv/rfcs#37. fn propose_transfer_leader( &mut self, ctx: &mut PollContext, @@ -2101,18 +2221,7 @@ impl Peer { let transfer_leader = get_transfer_leader_cmd(&req).unwrap(); let peer = transfer_leader.get_peer(); - let transferred = if self.ready_to_transfer_leader(ctx, peer) { - self.transfer_leader(peer); - true - } else { - info!( - "transfer leader message ignored directly"; - "region_id" => self.region_id, - "peer_id" => self.peer.get_id(), - "message" => ?req, - ); - false - }; + let transferred = self.pre_transfer_leader(peer); // transfer leader command doesn't need to replicate log and apply, so we // return immediately. Note that this command may fail, we can view it just as an advice @@ -2334,7 +2443,7 @@ impl Peer { } } - pub fn send_load_merge_target(&self, trans: &mut T) { + pub fn bcast_wake_up_message(&self, trans: &mut T) { let region = self.raft_group.get_store().region(); for peer in region.get_peers() { if peer.get_id() == self.peer_id() { @@ -2345,11 +2454,11 @@ impl Peer { send_msg.set_from_peer(self.peer.clone()); send_msg.set_region_epoch(self.region().get_region_epoch().clone()); send_msg.set_to_peer(peer.clone()); - let merge_msg = send_msg.mut_merge(); - merge_msg.set_msg_type(MergeMsgType::MsgLoadMergeTarget); + let extra_msg = send_msg.mut_extra_msg(); + extra_msg.set_field_type(ExtraMessageType::MsgRegionWakeUp); if let Err(e) = trans.send(send_msg) { error!( - "failed to send load merge target message"; + "failed to send wake up message"; "region_id" => self.region_id, "peer_id" => self.peer.get_id(), "target_peer_id" => peer.get_id(), diff --git a/src/raftstore/store/peer_storage.rs b/src/raftstore/store/peer_storage.rs index 29647e9852c..37b8e62cb63 100644 --- a/src/raftstore/store/peer_storage.rs +++ b/src/raftstore/store/peer_storage.rs @@ -1956,7 +1956,15 @@ mod tests { let mut worker = Worker::new("region-worker"); let sched = worker.scheduler(); let mut s = new_storage_from_ents(sched.clone(), &td, &ents); - let runner = RegionRunner::new(s.engines.clone(), mgr, 0, true, Duration::from_secs(0)); + let (router, _) = mpsc::sync_channel(100); + let runner = RegionRunner::new( + s.engines.clone(), + mgr, + 0, + true, + Duration::from_secs(0), + router, + ); worker.start(runner).unwrap(); let snap = s.snapshot(); let unavailable = RaftError::Store(StorageError::SnapshotTemporarilyUnavailable); @@ -2261,12 +2269,14 @@ mod tests { let mut worker = Worker::new("snap-manager"); let sched = worker.scheduler(); let s1 = new_storage_from_ents(sched.clone(), &td1, &ents); + let (router, _) = mpsc::sync_channel(100); let runner = RegionRunner::new( s1.engines.clone(), mgr.clone(), 0, true, Duration::from_secs(0), + router, ); worker.start(runner).unwrap(); assert!(s1.snapshot().is_err()); diff --git a/src/raftstore/store/read_queue.rs b/src/raftstore/store/read_queue.rs index 770a3ce3aa0..8c9060c5343 100644 --- a/src/raftstore/store/read_queue.rs +++ b/src/raftstore/store/read_queue.rs @@ -122,16 +122,17 @@ impl ReadIndexQueue { self.handled_cnt = 0; } - pub fn clear_uncommitted(&mut self, term: u64) { + pub fn clear_uncommitted_on_role_change(&mut self, term: u64) { let mut removed = 0; for mut read in self.reads.drain(self.ready_cnt..) { - self.contexts.remove(&read.id); removed += read.cmds.len(); for (_, cb) in read.cmds.drain(..) { apply::notify_stale_req(term, cb); } } RAFT_READ_INDEX_PENDING_COUNT.sub(removed as i64); + // For a follower changes to leader, and then changes to followr again. + self.contexts.clear(); } pub fn push_back(&mut self, read: ReadIndexRequest, is_leader: bool) { @@ -309,4 +310,44 @@ mod tests { queue.clear_all(None); } + + #[test] + fn test_role_change() { + let mut queue = ReadIndexQueue::default(); + queue.handled_cnt = 100; + + // Push a pending comand when the peer is follower. + let id = Uuid::new_v4(); + let req = ReadIndexRequest::with_command( + id, + RaftCmdRequest::default(), + Callback::None, + Timespec::new(0, 0), + ); + queue.push_back(req, false); + + // After the peer becomes leader, `advance` could be called before + // `clear_uncommitted_on_role_change`. + let mut read = queue.advance_leader_read_and_pop(id, 10); + read.cmds.clear(); + + queue.clear_uncommitted_on_role_change(10); + + let req = ReadIndexRequest::with_command( + Uuid::new_v4(), + RaftCmdRequest::default(), + Callback::None, + Timespec::new(0, 0), + ); + queue.push_back(req, true); + let last_id = queue.reads.back().map(|t| t.id).unwrap(); + queue.advance_leader_reads(vec![(last_id, 10)]); + assert_eq!(queue.ready_cnt, 1); + while let Some(mut read) = queue.pop_front() { + read.cmds.clear(); + } + + // Shouldn't panic when call `advance_replica_reads` with `id` again. + queue.advance_replica_reads(vec![(id, 10)]); + } } diff --git a/src/raftstore/store/transport.rs b/src/raftstore/store/transport.rs index 7dba70cf4dd..b8bb0fd800d 100644 --- a/src/raftstore/store/transport.rs +++ b/src/raftstore/store/transport.rs @@ -35,7 +35,7 @@ pub trait StoreRouter { impl CasualRouter for RaftRouter { #[inline] fn send(&self, region_id: u64, msg: CasualMessage) -> Result<()> { - match RaftRouter::send(self, region_id, PeerMsg::CasualMessage(msg)) { + match self.router.send(region_id, PeerMsg::CasualMessage(msg)) { Ok(()) => Ok(()), Err(TrySendError::Full(_)) => Err(Error::Transport(DiscardReason::Full)), Err(TrySendError::Disconnected(_)) => Err(Error::RegionNotFound(region_id)), diff --git a/src/raftstore/store/worker/region.rs b/src/raftstore/store/worker/region.rs index d3c6306266e..cadfd7f7718 100644 --- a/src/raftstore/store/worker/region.rs +++ b/src/raftstore/store/worker/region.rs @@ -22,8 +22,10 @@ use crate::raftstore::store::peer_storage::{ JOB_STATUS_PENDING, JOB_STATUS_RUNNING, }; use crate::raftstore::store::snap::{plain_file_used, Error, Result, SNAPSHOT_CFS}; +use crate::raftstore::store::transport::CasualRouter; use crate::raftstore::store::{ - self, check_abort, keys, SnapEntry, SnapKey, SnapManager, Snapshot as RaftStoreSnapshot, + self, check_abort, keys, CasualMessage, SnapEntry, SnapKey, SnapManager, + Snapshot as RaftStoreSnapshot, }; use tikv_util::threadpool::{DefaultContext, ThreadPool, ThreadPoolBuilder}; use tikv_util::time; @@ -206,16 +208,17 @@ impl PendingDeleteRanges { } #[derive(Clone)] -struct SnapContext { +struct SnapContext { engines: Engines, batch_size: usize, mgr: SnapManager, use_delete_range: bool, clean_stale_peer_delay: Duration, pending_delete_ranges: PendingDeleteRanges, + router: R, } -impl SnapContext { +impl SnapContext { /// Generates the snapshot of the Region. fn generate_snap( &self, @@ -241,6 +244,10 @@ impl SnapContext { "err" => %e, ); } + // The error can be ignored as snapshot will be sent in next heartbeat in the end. + let _ = self + .router + .send(region_id, CasualMessage::SnapshotGenerated); Ok(()) } @@ -574,23 +581,24 @@ impl SnapContext { } } -pub struct Runner { +pub struct Runner { pool: ThreadPool, - ctx: SnapContext, + ctx: SnapContext, // we may delay some apply tasks if level 0 files to write stall threshold, // pending_applies records all delayed apply task, and will check again later pending_applies: VecDeque, } -impl Runner { +impl Runner { pub fn new( engines: Engines, mgr: SnapManager, batch_size: usize, use_delete_range: bool, clean_stale_peer_delay: Duration, - ) -> Runner { + router: R, + ) -> Runner { Runner { pool: ThreadPoolBuilder::with_default_factory(thd_name!("snap-generator")) .thread_count(GENERATE_POOL_SIZE) @@ -602,12 +610,13 @@ impl Runner { use_delete_range, clean_stale_peer_delay, pending_delete_ranges: PendingDeleteRanges::default(), + router, }, pending_applies: VecDeque::new(), } } - pub fn new_timer() -> Timer { + pub fn new_timer(&self) -> Timer { let mut timer = Timer::new(2); timer.add_task( Duration::from_millis(PENDING_APPLY_CHECK_INTERVAL), @@ -641,7 +650,10 @@ impl Runner { } } -impl Runnable for Runner { +impl Runnable for Runner +where + R: CasualRouter + Send + Clone + 'static, +{ fn run(&mut self, task: Task) { match task { Task::Gen { @@ -699,7 +711,10 @@ pub enum Event { CheckApply, } -impl RunnableWithTimer for Runner { +impl RunnableWithTimer for Runner +where + R: CasualRouter + Send + Clone + 'static, +{ fn on_timeout(&mut self, timer: &mut Timer, event: Event) { match event { Event::CheckApply => { @@ -731,7 +746,7 @@ mod tests { use crate::raftstore::store::peer_storage::JOB_STATUS_PENDING; use crate::raftstore::store::snap::tests::get_test_db_for_regions; use crate::raftstore::store::worker::RegionRunner; - use crate::raftstore::store::{keys, SnapKey, SnapManager}; + use crate::raftstore::store::{keys, CasualMessage, SnapKey, SnapManager}; use engine::rocks; use engine::rocks::{ColumnFamilyOptions, Snapshot, Writable, WriteBatch}; use engine::Engines; @@ -868,7 +883,15 @@ mod tests { let mgr = SnapManager::new(snap_dir.path().to_str().unwrap(), None); let mut worker = Worker::new("snap-manager"); let sched = worker.scheduler(); - let runner = RegionRunner::new(engines.clone(), mgr, 0, true, Duration::from_secs(0)); + let (router, receiver) = mpsc::sync_channel(1); + let runner = RegionRunner::new( + engines.clone(), + mgr, + 0, + true, + Duration::from_secs(0), + router, + ); let mut timer = Timer::new(1); timer.add_task(Duration::from_millis(100), Event::CheckApply); worker.start_with_timer(runner, timer).unwrap(); @@ -885,6 +908,12 @@ mod tests { }) .unwrap(); let s1 = rx.recv().unwrap(); + match receiver.recv() { + Ok((region_id, CasualMessage::SnapshotGenerated)) => { + assert_eq!(region_id, id); + } + msg => panic!("expected SnapshotGenerated, but got {:?}", msg), + } let data = s1.get_data(); let key = SnapKey::from_snap(&s1).unwrap(); let mgr = SnapManager::new(snap_dir.path().to_str().unwrap(), None); diff --git a/src/server/lock_manager/config.rs b/src/server/lock_manager/config.rs index 2bfcc877de5..21438fb9042 100644 --- a/src/server/lock_manager/config.rs +++ b/src/server/lock_manager/config.rs @@ -15,8 +15,8 @@ impl Default for Config { fn default() -> Self { Self { enabled: true, - wait_for_lock_timeout: 3000, - wake_up_delay_duration: 100, + wait_for_lock_timeout: 1000, + wake_up_delay_duration: 20, } } } diff --git a/src/server/lock_manager/deadlock.rs b/src/server/lock_manager/deadlock.rs index 24c0b8c92e6..b7e3bc0db91 100644 --- a/src/server/lock_manager/deadlock.rs +++ b/src/server/lock_manager/deadlock.rs @@ -6,7 +6,10 @@ use super::metrics::*; use super::waiter_manager::Scheduler as WaiterMgrScheduler; use super::{Error, Result}; use crate::pd::{PdClient, INVALID_ID}; -use crate::raftstore::coprocessor::{Coprocessor, ObserverContext, RoleObserver}; +use crate::raftstore::coprocessor::{ + Coprocessor, CoprocessorHost, ObserverContext, RegionChangeEvent, RegionChangeObserver, + RoleObserver, +}; use crate::server::resolve::StoreAddrResolver; use crate::storage::lock_manager::Lock; use futures::{Future, Sink, Stream}; @@ -22,7 +25,7 @@ use raft::StateRole; use std::cell::RefCell; use std::fmt::{self, Display, Formatter}; use std::rc::Rc; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use tikv_util::collections::{HashMap, HashSet}; use tikv_util::future::paired_future_callback; use tikv_util::security::SecurityManager; @@ -99,7 +102,7 @@ impl DetectTable { /// Returns the key hash which causes deadlock. pub fn detect(&mut self, txn_ts: u64, lock_ts: u64, lock_hash: u64) -> Option { - let _timer = DETECTOR_HISTOGRAM_VEC.detect.start_coarse_timer(); + let _timer = DETECT_DURATION_HISTOGRAM.start_coarse_timer(); TASK_COUNTER_VEC.detect.inc(); self.now = Instant::now_coarse(); @@ -215,16 +218,6 @@ impl DetectTable { } } -/// The leader of the region containing the LEADER_KEY is the leader of deadlock detector. -const LEADER_KEY: &[u8] = b""; - -/// Returns true if the region containing the LEADER_KEY. -fn is_leader_region(region: &'_ Region) -> bool { - !region.get_peers().is_empty() - && region.get_start_key() <= LEADER_KEY - && (region.get_end_key().is_empty() || LEADER_KEY < region.get_end_key()) -} - /// The role of the detector. #[derive(Debug, PartialEq, Clone, Copy)] pub enum Role { @@ -273,6 +266,9 @@ pub enum Task { /// /// It's the only way to change the node from leader to follower, and vice versa. ChangeRole(Role), + /// Task only used for test + #[cfg(test)] + GetRole(Box), } impl Display for Task { @@ -285,6 +281,8 @@ impl Display for Task { ), Task::DetectRpc { .. } => write!(f, "Detect Rpc"), Task::ChangeRole(role) => write!(f, "ChangeRole {{ role: {:?} }}", role), + #[cfg(test)] + Task::GetRole(_) => write!(f, "Get role of the deadlock detector"), } } } @@ -334,20 +332,99 @@ impl Scheduler { fn change_role(&self, role: Role) { self.notify_scheduler(Task::ChangeRole(role)); } + + #[cfg(test)] + pub fn get_role(&self, f: Box) { + self.notify_scheduler(Task::GetRole(f)); + } } -impl Coprocessor for Scheduler {} +/// The leader region is the region containing the LEADER_KEY and the leader of the +/// leader region is also the leader of the deadlock detector. +const LEADER_KEY: &[u8] = b""; + +/// `RoleChangeNotifier` observes region or role change events of raftstore. If the +/// region is the leader region and the role of this node is changed, a `ChangeRole` +/// task will be scheduled to the deadlock detector. It's the only way to change the +/// node from the leader of deadlock detector to follower, and vice versa. +#[derive(Clone)] +pub(crate) struct RoleChangeNotifier { + /// The id of the valid leader region. + // raftstore.coprocessor needs it to be Sync + Send. + leader_region_id: Arc>, + scheduler: Scheduler, +} -/// Implements observer traits for `Scheduler`. -/// If the role of the node in the leader region changes, notifys the deadlock detector. -/// -/// If the leader region is merged or splited in the node, the role of the node won't change. -/// If the leader region is removed and the node is the leader, it will change to follower first. -/// So there is no need to observe region change events. -impl RoleObserver for Scheduler { +impl RoleChangeNotifier { + fn is_leader_region(region: &Region) -> bool { + // The key range of a new created region is empty which misleads the leader + // of the deadlock detector stepping down. + // + // If the peers of a region is not empty, the region info is complete. + !region.get_peers().is_empty() + && region.get_start_key() <= LEADER_KEY + && (region.get_end_key().is_empty() || LEADER_KEY < region.get_end_key()) + } + + pub(crate) fn new(scheduler: Scheduler) -> Self { + Self { + leader_region_id: Arc::new(Mutex::new(INVALID_ID)), + scheduler, + } + } + + pub(crate) fn register(self, host: &mut CoprocessorHost) { + host.registry + .register_role_observer(1, Box::new(self.clone())); + host.registry + .register_region_change_observer(1, Box::new(self)); + } +} + +impl Coprocessor for RoleChangeNotifier {} + +impl RoleObserver for RoleChangeNotifier { fn on_role_change(&self, ctx: &mut ObserverContext<'_>, role: StateRole) { - if is_leader_region(ctx.region()) { - self.change_role(role.into()); + let region = ctx.region(); + // A region is created first, so the leader region id must be valid. + if Self::is_leader_region(region) + && *self.leader_region_id.lock().unwrap() == region.get_id() + { + self.scheduler.change_role(role.into()); + } + } +} + +impl RegionChangeObserver for RoleChangeNotifier { + fn on_region_changed( + &self, + ctx: &mut ObserverContext<'_>, + event: RegionChangeEvent, + role: StateRole, + ) { + let region = ctx.region(); + if Self::is_leader_region(region) { + match event { + RegionChangeEvent::Create | RegionChangeEvent::Update => { + *self.leader_region_id.lock().unwrap() = region.get_id(); + self.scheduler.change_role(role.into()); + } + RegionChangeEvent::Destroy => { + // When one region is merged to target region, it will be destroyed. + // If the leader region is merged to the target region and the node + // is also the leader of the target region, the RoleChangeNotifier will + // receive one RegionChangeEvent::Update of the target region and one + // RegionChangeEvent::Destroy of the leader region. To prevent the + // destroy event misleading the leader stepping down, it saves the + // valid leader region id and only when the id equals to the destroyed + // region id, it sends a ChangeRole(Follower) task to the deadlock detector. + let mut leader_region_id = self.leader_region_id.lock().unwrap(); + if *leader_region_id == region.get_id() { + *leader_region_id = INVALID_ID; + self.scheduler.change_role(Role::Follower); + } + } + } } } } @@ -509,10 +586,12 @@ where if self.inner.borrow().role != role { match role { Role::Leader => { - info!("became the leader of deadlock detector!"; "self_id" => self.store_id) + info!("became the leader of deadlock detector!"; "self_id" => self.store_id); + DETECTOR_LEADER_GAUGE.set(1); } Role::Follower => { - info!("changed from the leader of deadlock detector to follower!"; "self_id" => self.store_id) + info!("changed from the leader of deadlock detector to follower!"; "self_id" => self.store_id); + DETECTOR_LEADER_GAUGE.set(0); } } } @@ -730,6 +809,8 @@ where self.handle_detect_rpc(handle, stream, sink); } Task::ChangeRole(role) => self.handle_change_role(role), + #[cfg(test)] + Task::GetRole(f) => f(self.inner.borrow().role), } } } @@ -793,8 +874,11 @@ impl deadlock_grpc::Deadlock for Service { } #[cfg(test)] -mod tests { +pub mod tests { use super::*; + use crate::server::resolve::Callback; + use tikv_util::security::SecurityConfig; + use tikv_util::worker::FutureWorker; #[test] fn test_detect_table() { @@ -936,4 +1020,129 @@ mod tests { assert!(detect_table.detect(3, 1, 3).is_none()); assert_eq!(detect_table.wait_for_map.len(), 1); } + + pub(crate) struct MockPdClient; + + impl PdClient for MockPdClient {} + + #[derive(Clone)] + pub(crate) struct MockResolver; + + impl StoreAddrResolver for MockResolver { + fn resolve(&self, _store_id: u64, _cb: Callback) -> Result<()> { + Err(Error::Other(box_err!("unimplemented"))) + } + } + + fn start_deadlock_detector(host: &mut CoprocessorHost) -> (FutureWorker, Scheduler) { + let waiter_mgr_worker = FutureWorker::new("dummy-waiter-mgr"); + let waiter_mgr_scheduler = WaiterMgrScheduler::new(waiter_mgr_worker.scheduler()); + let mut detector_worker = FutureWorker::new("test-deadlock-detector"); + let detector_runner = Detector::new( + 1, + Arc::new(MockPdClient {}), + MockResolver {}, + Arc::new(SecurityManager::new(&SecurityConfig::default()).unwrap()), + waiter_mgr_scheduler, + &Config::default(), + ); + let detector_scheduler = Scheduler::new(detector_worker.scheduler()); + let role_change_notifier = RoleChangeNotifier::new(detector_scheduler.clone()); + role_change_notifier.register(host); + detector_worker.start(detector_runner).unwrap(); + (detector_worker, detector_scheduler) + } + + // Region with non-empty peers is valid. + fn new_region(id: u64, start_key: &[u8], end_key: &[u8], valid: bool) -> Region { + let mut region = Region::default(); + region.set_id(id); + region.set_start_key(start_key.to_vec()); + region.set_end_key(end_key.to_vec()); + if valid { + region.set_peers(vec![kvproto::metapb::Peer::default()].into()); + } + region + } + + #[test] + fn test_role_change_notifier() { + let mut host = CoprocessorHost::default(); + let (mut worker, scheduler) = start_deadlock_detector(&mut host); + + let mut region = new_region(1, b"", b"", true); + let invalid = new_region(2, b"", b"", false); + let other = new_region(3, b"0", b"", true); + let follower_roles = [ + StateRole::Follower, + StateRole::PreCandidate, + StateRole::Candidate, + ]; + let events = [ + RegionChangeEvent::Create, + RegionChangeEvent::Update, + RegionChangeEvent::Destroy, + ]; + let check_role = |role| { + let (tx, f) = paired_future_callback(); + scheduler.get_role(tx); + assert_eq!(f.wait().unwrap(), role); + }; + + // Region changed + for &event in &events[..2] { + for &follower_role in &follower_roles { + host.on_region_changed(®ion, event, follower_role); + check_role(Role::Follower); + host.on_region_changed(&invalid, event, StateRole::Leader); + check_role(Role::Follower); + host.on_region_changed(&other, event, StateRole::Leader); + check_role(Role::Follower); + host.on_region_changed(®ion, event, StateRole::Leader); + check_role(Role::Leader); + host.on_region_changed(&invalid, event, follower_role); + check_role(Role::Leader); + host.on_region_changed(&other, event, follower_role); + check_role(Role::Leader); + host.on_region_changed(®ion, event, follower_role); + check_role(Role::Follower); + } + } + host.on_region_changed(®ion, RegionChangeEvent::Create, StateRole::Leader); + host.on_region_changed(&invalid, RegionChangeEvent::Destroy, StateRole::Leader); + host.on_region_changed(&other, RegionChangeEvent::Destroy, StateRole::Leader); + check_role(Role::Leader); + host.on_region_changed(®ion, RegionChangeEvent::Destroy, StateRole::Leader); + check_role(Role::Follower); + // Leader region id is changed. + region.set_id(2); + host.on_region_changed(®ion, RegionChangeEvent::Update, StateRole::Leader); + // Destroy the previous leader region. + region.set_id(1); + host.on_region_changed(®ion, RegionChangeEvent::Destroy, StateRole::Leader); + check_role(Role::Leader); + + // Role changed + let region = new_region(1, b"", b"", true); + host.on_region_changed(®ion, RegionChangeEvent::Create, StateRole::Follower); + check_role(Role::Follower); + for &follower_role in &follower_roles { + host.on_role_change(®ion, follower_role); + check_role(Role::Follower); + host.on_role_change(&invalid, StateRole::Leader); + check_role(Role::Follower); + host.on_role_change(&other, StateRole::Leader); + check_role(Role::Follower); + host.on_role_change(®ion, StateRole::Leader); + check_role(Role::Leader); + host.on_role_change(&invalid, follower_role); + check_role(Role::Leader); + host.on_role_change(&other, follower_role); + check_role(Role::Leader); + host.on_role_change(®ion, follower_role); + check_role(Role::Follower); + } + + worker.stop(); + } } diff --git a/src/server/lock_manager/metrics.rs b/src/server/lock_manager/metrics.rs index 7af235945f0..34df503aab8 100644 --- a/src/server/lock_manager/metrics.rs +++ b/src/server/lock_manager/metrics.rs @@ -25,10 +25,10 @@ make_static_metric! { }, } - pub struct DetectorHistogramVec: Histogram { + pub struct WaitTableStatusGauge: IntGauge { "type" => { - monitor_membership_change, - detect, + locks, + txns, }, } } @@ -51,15 +51,25 @@ lazy_static! { pub static ref WAITER_LIFETIME_HISTOGRAM: Histogram = register_histogram!( "tikv_lock_manager_waiter_lifetime_duration", "Duration of waiters' lifetime in seconds", - exponential_buckets(0.0005, 2.0, 20).unwrap() + exponential_buckets(0.0005, 2.0, 20).unwrap() // 0.5ms ~ 524s + ) + .unwrap(); + pub static ref DETECT_DURATION_HISTOGRAM: Histogram = register_histogram!( + "tikv_lock_manager_detect_duration", + "Duration of handling detect requests", + exponential_buckets(0.0001, 2.0, 20).unwrap() // 0.1ms ~ 104s + ) + .unwrap(); + pub static ref WAIT_TABLE_STATUS_GAUGE: WaitTableStatusGauge = register_static_int_gauge_vec!( + WaitTableStatusGauge, + "tikv_lock_manager_wait_table_status", + "Status of the wait table", + &["type"] ) .unwrap(); - pub static ref DETECTOR_HISTOGRAM_VEC: DetectorHistogramVec = register_static_histogram_vec!( - DetectorHistogramVec, - "tikv_lock_manager_detector_histogram", - "Bucketed histogram of deadlock detector", - &["type"], - exponential_buckets(0.0005, 2.0, 20).unwrap() + pub static ref DETECTOR_LEADER_GAUGE: IntGauge = register_int_gauge!( + "tikv_lock_manager_detector_leader_heartbeat", + "Heartbeat of the leader of the deadlock detector" ) .unwrap(); } diff --git a/src/server/lock_manager/mod.rs b/src/server/lock_manager/mod.rs index b1e8c792aea..c0f4acec14d 100644 --- a/src/server/lock_manager/mod.rs +++ b/src/server/lock_manager/mod.rs @@ -9,21 +9,22 @@ pub mod waiter_manager; pub use self::config::Config; pub use self::deadlock::Service as DeadlockService; -use self::deadlock::{Detector, Scheduler as DetectorScheduler}; +use self::deadlock::{Detector, RoleChangeNotifier, Scheduler as DetectorScheduler}; use self::waiter_manager::{Scheduler as WaiterMgrScheduler, WaiterManager}; +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::{Arc, Mutex}; +use std::thread::JoinHandle; + use crate::pd::PdClient; use crate::raftstore::coprocessor::CoprocessorHost; use crate::server::resolve::StoreAddrResolver; use crate::server::{Error, Result}; use crate::storage::txn::{execute_callback, ProcessResult}; use crate::storage::{lock_manager::Lock, LockMgr, StorageCb}; -use std::collections::hash_map::DefaultHasher; -use std::hash::{Hash, Hasher}; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; -use std::sync::Mutex; -use std::thread::JoinHandle; + use tikv_util::collections::HashSet; use tikv_util::security::SecurityManager; use tikv_util::worker::FutureWorker; @@ -175,11 +176,11 @@ impl LockManager { } } - /// Creates a `Scheduler` of the deadlock detector worker and registers it to + /// Creates a `RoleChangeNotifier` of the deadlock detector worker and registers it to /// the `CoprocessorHost` to observe the role change events of the leader region. pub fn register_detector_role_change_observer(&self, host: &mut CoprocessorHost) { - host.registry - .register_role_observer(1, Box::new(self.detector_scheduler.clone())); + let role_change_notifier = RoleChangeNotifier::new(self.detector_scheduler.clone()); + role_change_notifier.register(host); } /// Creates a `DeadlockService` to handle deadlock detect requests from other nodes. @@ -258,15 +259,13 @@ impl LockMgr for LockManager { #[cfg(test)] mod tests { + use self::deadlock::tests::*; use self::metrics::*; use self::waiter_manager::tests::*; use super::*; - use crate::pd::{RegionInfo, Result as PdResult}; - use crate::raftstore::coprocessor::Config as CopConfig; - use crate::server::resolve::Callback; + use crate::raftstore::coprocessor::RegionChangeEvent; use tikv_util::security::SecurityConfig; - use std::sync::mpsc; use std::thread; use std::time::Duration; @@ -274,30 +273,12 @@ mod tests { use kvproto::metapb::{Peer, Region}; use raft::StateRole; - struct MockPdClient; - - impl PdClient for MockPdClient { - fn get_region_info(&self, _key: &[u8]) -> PdResult { - unimplemented!(); - } - } - - #[derive(Clone)] - struct MockResolver; - - impl StoreAddrResolver for MockResolver { - fn resolve(&self, _store_id: u64, _cb: Callback) -> Result<()> { - Err(Error::Other(box_err!("unimplemented"))) - } - } - fn start_lock_manager() -> LockManager { - use protobuf::RepeatedField; - - let (tx, _rx) = mpsc::sync_channel(100); - let mut coprocessor_host = CoprocessorHost::new(CopConfig::default(), tx); - + let mut coprocessor_host = CoprocessorHost::default(); let mut lock_mgr = LockManager::new(); + let mut cfg = Config::default(); + cfg.wait_for_lock_timeout = 3000; + cfg.wake_up_delay_duration = 100; lock_mgr.register_detector_role_change_observer(&mut coprocessor_host); lock_mgr .start( @@ -305,7 +286,7 @@ mod tests { Arc::new(MockPdClient {}), MockResolver {}, Arc::new(SecurityManager::new(&SecurityConfig::default()).unwrap()), - &Config::default(), + &cfg, ) .unwrap(); @@ -313,8 +294,12 @@ mod tests { let mut leader_region = Region::new(); leader_region.set_start_key(b"".to_vec()); leader_region.set_end_key(b"foo".to_vec()); - leader_region.set_peers(RepeatedField::from_vec(vec![Peer::new()])); - coprocessor_host.on_role_change(&leader_region, StateRole::Leader); + leader_region.set_peers(vec![Peer::default()].into()); + coprocessor_host.on_region_changed( + &leader_region, + RegionChangeEvent::Create, + StateRole::Leader, + ); thread::sleep(Duration::from_millis(100)); lock_mgr @@ -331,7 +316,7 @@ mod tests { assert!(lock_mgr.has_waiter()); assert_elapsed( || expect_key_is_locked(f.wait().unwrap().unwrap().pop().unwrap(), lock_info), - 3000, + 2900, 3200, ); assert!(!lock_mgr.has_waiter()); diff --git a/src/server/lock_manager/waiter_manager.rs b/src/server/lock_manager/waiter_manager.rs index e4c44a3552e..0a25aca9854 100644 --- a/src/server/lock_manager/waiter_manager.rs +++ b/src/server/lock_manager/waiter_manager.rs @@ -282,18 +282,27 @@ impl WaitTable { /// Returns the duplicated `Waiter` if there is. fn add_waiter(&mut self, waiter: Waiter) -> Option { - let waiters = self.wait_table.entry(waiter.lock.hash).or_default(); + let waiters = self.wait_table.entry(waiter.lock.hash).or_insert_with(|| { + WAIT_TABLE_STATUS_GAUGE.locks.inc(); + Waiters::default() + }); let old_idx = waiters.iter().position(|w| w.start_ts == waiter.start_ts); waiters.push(waiter); - let old = waiters.swap_remove(old_idx?); - self.waiter_count.fetch_sub(1, Ordering::SeqCst); - Some(old) + if let Some(old_idx) = old_idx { + let old = waiters.swap_remove(old_idx); + self.waiter_count.fetch_sub(1, Ordering::SeqCst); + Some(old) + } else { + WAIT_TABLE_STATUS_GAUGE.txns.inc(); + None + } // Here we don't increase waiter_count because it's already updated in LockManager::wait_for() } /// Removes all waiters waiting for the lock. fn remove(&mut self, lock: Lock) { self.wait_table.remove(&lock.hash); + WAIT_TABLE_STATUS_GAUGE.locks.dec(); } fn remove_waiter(&mut self, lock: Lock, waiter_ts: u64) -> Option { @@ -303,8 +312,9 @@ impl WaitTable { .position(|waiter| waiter.start_ts == waiter_ts)?; let waiter = waiters.swap_remove(idx); self.waiter_count.fetch_sub(1, Ordering::SeqCst); + WAIT_TABLE_STATUS_GAUGE.txns.dec(); if waiters.is_empty() { - self.wait_table.remove(&lock.hash); + self.remove(lock); } Some(waiter) } @@ -323,6 +333,7 @@ impl WaitTable { .0; let oldest = waiters.swap_remove(oldest_idx); self.waiter_count.fetch_sub(1, Ordering::SeqCst); + WAIT_TABLE_STATUS_GAUGE.txns.dec(); Some((oldest, waiters)) } @@ -590,7 +601,7 @@ pub mod tests { core.run(delay.map(|not_cancelled| assert!(not_cancelled))) .unwrap() }, - 100, + 50, 200, ); @@ -603,7 +614,7 @@ pub mod tests { core.run(delay.map(|not_cancelled| assert!(not_cancelled))) .unwrap() }, - 30, + 20, 100, ); @@ -616,7 +627,7 @@ pub mod tests { core.run(delay.map(|not_cancelled| assert!(not_cancelled))) .unwrap() }, - 100, + 50, 200, ); @@ -791,7 +802,7 @@ pub mod tests { waiter.reset_timeout(Instant::now() + Duration::from_millis(100)); let (tx, rx) = mpsc::sync_channel(1); let f = waiter.on_timeout(move || tx.send(1).unwrap()); - assert_elapsed(|| core.run(f).unwrap(), 100, 200); + assert_elapsed(|| core.run(f).unwrap(), 50, 200); rx.try_recv().unwrap(); // The timeout handler shouldn't be invoked after waiter has been notified. @@ -889,6 +900,7 @@ pub mod tests { waiter_count.fetch_add(1, Ordering::SeqCst); wait_table.add_waiter(dummy_waiter(1, lock.ts, lock.hash)); assert_eq!(waiter_count.load(Ordering::SeqCst), 1); + // Remove the waiter. wait_table.remove_waiter(lock, 1).unwrap(); assert_eq!(waiter_count.load(Ordering::SeqCst), 0); // Removing a non-existed waiter shouldn't decrease waiter count. @@ -960,7 +972,7 @@ pub mod tests { scheduler.wait_for(waiter.start_ts, waiter.cb, waiter.pr, waiter.lock, 1000); assert_elapsed( || expect_key_is_locked(f.wait().unwrap().unwrap().pop().unwrap(), lock_info), - 1000, + 900, 1200, ); @@ -969,7 +981,7 @@ pub mod tests { scheduler.wait_for(waiter.start_ts, waiter.cb, waiter.pr, waiter.lock, 100); assert_elapsed( || expect_key_is_locked(f.wait().unwrap().unwrap().pop().unwrap(), lock_info), - 100, + 50, 300, ); @@ -978,7 +990,7 @@ pub mod tests { scheduler.wait_for(waiter.start_ts, waiter.cb, waiter.pr, waiter.lock, 3000); assert_elapsed( || expect_key_is_locked(f.wait().unwrap().unwrap().pop().unwrap(), lock_info), - 1000, + 900, 1200, ); @@ -1056,7 +1068,7 @@ pub mod tests { lock_info.set_lock_version(lock.ts - 1); assert_elapsed( || expect_write_conflict(f.wait().unwrap(), waiter_ts, lock_info, commit_ts - 1), - wake_up_delay_duration, + wake_up_delay_duration - 50, wake_up_delay_duration + 200, ); @@ -1128,7 +1140,7 @@ pub mod tests { // The new waiter will be wake up after timeout. assert_elapsed( || expect_key_is_locked(f2.wait().unwrap().unwrap().pop().unwrap(), lock_info2), - 1000, + 900, 1200, ); diff --git a/src/server/resolve.rs b/src/server/resolve.rs index 9cde485c854..18c933c2b63 100644 --- a/src/server/resolve.rs +++ b/src/server/resolve.rs @@ -211,7 +211,7 @@ mod tests { fn test_resolve_store_peer_addr() { let mut store = new_store("127.0.0.1:12345", metapb::StoreState::Up); store.set_peer_address("127.0.0.1:22345".to_string()); - let runner = new_runner(store); + let mut runner = new_runner(store); assert_eq!( runner.get_address(0).unwrap(), "127.0.0.1:22345".to_string() diff --git a/src/server/server.rs b/src/server/server.rs index c08fbb379ea..96a21979866 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -309,9 +309,14 @@ mod tests { } fn is_unreachable_to(msg: &SignificantMsg, region_id: u64, to_peer_id: u64) -> bool { - *msg == SignificantMsg::Unreachable { - region_id, - to_peer_id, + if let SignificantMsg::Unreachable { + region_id: r_id, + to_peer_id: p_id, + } = *msg + { + region_id == r_id && to_peer_id == p_id + } else { + false } } diff --git a/tests/failpoints/cases/mod.rs b/tests/failpoints/cases/mod.rs index 35786d4c408..53e1a7c1064 100644 --- a/tests/failpoints/cases/mod.rs +++ b/tests/failpoints/cases/mod.rs @@ -11,5 +11,6 @@ mod test_split_region; mod test_stale_peer; mod test_stale_read; mod test_storage; +mod test_transfer_leader; // TODO: enable these tests. // mod test_upgrade; diff --git a/tests/failpoints/cases/test_merge.rs b/tests/failpoints/cases/test_merge.rs index 4936378525b..3f7f94829bc 100644 --- a/tests/failpoints/cases/test_merge.rs +++ b/tests/failpoints/cases/test_merge.rs @@ -6,7 +6,6 @@ use std::thread; use std::time::*; use fail; -use futures::Future; use kvproto::raft_serverpb::{PeerState, RegionLocalState}; use raft::eraftpb::MessageType; @@ -14,7 +13,7 @@ use raft::eraftpb::MessageType; use engine::*; use test_raftstore::*; use tikv::pd::PdClient; -use tikv::raftstore::store::keys; +use tikv::raftstore::store::{keys, Callback}; use tikv_util::config::*; use tikv_util::HandyRwLock; @@ -140,22 +139,7 @@ fn test_node_merge_restart() { cluster.start().unwrap(); // Wait till merge is finished. - let timer = Instant::now(); - loop { - if pd_client - .get_region_by_id(left.get_id()) - .wait() - .unwrap() - .is_none() - { - break; - } - - if timer.elapsed() > Duration::from_secs(5) { - panic!("region still not merged after 5 secs"); - } - sleep_ms(10); - } + pd_client.check_merged_timeout(left.get_id(), Duration::from_secs(5)); cluster.must_put(b"k4", b"v4"); @@ -237,12 +221,12 @@ fn test_node_merge_catch_up_logs_restart() { must_get_none(&cluster.get_engine(3), b"k11"); // after source peer is applied but before set it to tombstone - fail::cfg("after_handle_catch_up_logs_for_merge_1000_1003", "return()").unwrap(); + fail::cfg("after_handle_catch_up_logs_for_merge_1003", "return()").unwrap(); pd_client.must_merge(left.get_id(), right.get_id()); thread::sleep(Duration::from_millis(100)); cluster.shutdown(); - fail::remove("after_handle_catch_up_logs_for_merge_1000_1003"); + fail::remove("after_handle_catch_up_logs_for_merge_1003"); cluster.start().unwrap(); must_get_equal(&cluster.get_engine(3), b"k11", b"v11"); } @@ -273,7 +257,7 @@ fn test_node_merge_catch_up_logs_leader_election() { let state1 = cluster.truncated_state(1000, 1); // let the entries committed but not applied - fail::cfg("on_handle_apply_1000_1003", "pause").unwrap(); + fail::cfg("on_handle_apply_1003", "pause").unwrap(); for i in 2..20 { cluster.must_put(format!("k1{}", i).as_bytes(), b"v"); } @@ -296,13 +280,13 @@ fn test_node_merge_catch_up_logs_leader_election() { must_get_none(&cluster.get_engine(3), b"k11"); // let peer not destroyed before election timeout - fail::cfg("before_peer_destroy_1000_1003", "pause").unwrap(); - fail::remove("on_handle_apply_1000_1003"); + fail::cfg("before_peer_destroy_1003", "pause").unwrap(); + fail::remove("on_handle_apply_1003"); pd_client.must_merge(left.get_id(), right.get_id()); // wait election timeout thread::sleep(Duration::from_millis(500)); - fail::remove("before_peer_destroy_1000_1003"); + fail::remove("before_peer_destroy_1003"); must_get_equal(&cluster.get_engine(3), b"k11", b"v11"); } @@ -357,9 +341,9 @@ fn test_node_merge_catch_up_logs_no_need() { thread::sleep(Duration::from_millis(100)); // let source region not merged - fail::cfg("on_handle_catch_up_logs_for_merge", "pause").unwrap(); + fail::cfg("before_handle_catch_up_logs_for_merge", "pause").unwrap(); fail::cfg("after_handle_catch_up_logs_for_merge", "pause").unwrap(); - // due to `on_handle_catch_up_logs_for_merge` failpoint, we already pass `apply_index < catch_up_logs.merge.get_commit()` + // due to `before_handle_catch_up_logs_for_merge` failpoint, we already pass `apply_index < catch_up_logs.merge.get_commit()` // so now can let apply index make progress. fail::remove("apply_after_prepare_merge"); @@ -368,7 +352,7 @@ fn test_node_merge_catch_up_logs_no_need() { thread::sleep(Duration::from_millis(50)); // let merge process continue - fail::remove("on_handle_catch_up_logs_for_merge"); + fail::remove("before_handle_catch_up_logs_for_merge"); fail::remove("after_handle_catch_up_logs_for_merge"); thread::sleep(Duration::from_millis(50)); @@ -549,19 +533,21 @@ fn test_node_merge_restart_after_apply_premerge_before_apply_compact_log() { configure_for_merge(&mut cluster); cluster.cfg.raft_store.merge_max_log_gap = 10; cluster.cfg.raft_store.raft_log_gc_count_limit = 11; - // rely on this config to trigger a compact log + // Rely on this config to trigger a compact log cluster.cfg.raft_store.raft_log_gc_size_limit = ReadableSize(1); cluster.cfg.raft_store.raft_log_gc_tick_interval = ReadableDuration::millis(10); + + let pd_client = Arc::clone(&cluster.pd_client); + pd_client.disable_default_operator(); + cluster.run(); - // prevent gc_log_tick to propose a compact log + // Prevent gc_log_tick to propose a compact log let raft_gc_log_tick_fp = "on_raft_gc_log_tick"; fail::cfg(raft_gc_log_tick_fp, "return()").unwrap(); cluster.must_put(b"k1", b"v1"); cluster.must_put(b"k3", b"v3"); - let pd_client = Arc::clone(&cluster.pd_client); let region = pd_client.get_region(b"k1").unwrap(); - cluster.must_split(®ion, b"k2"); let left = pd_client.get_region(b"k1").unwrap(); @@ -569,46 +555,40 @@ fn test_node_merge_restart_after_apply_premerge_before_apply_compact_log() { let left_peer_1 = find_peer(&left, 1).cloned().unwrap(); cluster.must_transfer_leader(left.get_id(), left_peer_1); - // make log gap between store 1 and store 3, for min_index in preMerge + // Make log gap between store 1 and store 3, for min_index in preMerge cluster.add_send_filter(IsolationFilterFactory::new(3)); for i in 0..6 { cluster.must_put(format!("k1{}", i).as_bytes(), b"v1"); } - // prevent on_apply_res to update merge_state in Peer - // if not, almost everything cannot propose including compact log + // Prevent on_apply_res to update merge_state in Peer + // If not, almost everything cannot propose including compact log let on_apply_res_fp = "on_apply_res"; fail::cfg(on_apply_res_fp, "return()").unwrap(); - let merge = new_prepare_merge(right.clone()); - let req = new_admin_request(left.get_id(), left.get_region_epoch(), merge); - let resp = cluster - .call_command_on_leader(req, Duration::from_secs(3)) - .unwrap(); - if resp.get_header().has_error() { - panic!("response {:?} has error", resp); - } + cluster.try_merge(left.get_id(), right.get_id()); + cluster.clear_send_filters(); - // prevent apply fsm to apply compact log + // Prevent apply fsm to apply compact log let handle_apply_fp = "on_handle_apply"; fail::cfg(handle_apply_fp, "return()").unwrap(); let state1 = cluster.truncated_state(left.get_id(), 1); fail::remove(raft_gc_log_tick_fp); - // wait for compact log to be proposed and committed maybe + // Wait for compact log to be proposed and committed maybe sleep_ms(30); cluster.shutdown(); fail::remove(handle_apply_fp); fail::remove(on_apply_res_fp); - // prevent sched_merge_tick to propose CommitMerge + // Prevent sched_merge_tick to propose CommitMerge let schedule_merge_fp = "on_schedule_merge"; fail::cfg(schedule_merge_fp, "return()").unwrap(); cluster.start().unwrap(); - // wait for compact log to apply + // Wait for compact log to apply for _ in 0..50 { let state2 = cluster.truncated_state(left.get_id(), 1); if state1.get_index() != state2.get_index() { @@ -616,10 +596,193 @@ fn test_node_merge_restart_after_apply_premerge_before_apply_compact_log() { } sleep_ms(10); } - // can schedule merge now + // Now schedule merge fail::remove(schedule_merge_fp); - // propose to left region and wait for merge to succeed conveniently + pd_client.check_merged_timeout(left.get_id(), Duration::from_secs(5)); + cluster.must_put(b"k123", b"v2"); must_get_equal(&cluster.get_engine(3), b"k123", b"v2"); } + +/// Tests whether stale merge is rollback properly if it merge to the same target region again later. +#[test] +fn test_node_failed_merge_before_succeed_merge() { + let _guard = crate::setup(); + let mut cluster = new_node_cluster(0, 3); + configure_for_merge(&mut cluster); + cluster.cfg.raft_store.merge_max_log_gap = 30; + cluster.cfg.raft_store.store_max_batch_size = 1; + cluster.cfg.raft_store.store_pool_size = 2; + let pd_client = Arc::clone(&cluster.pd_client); + pd_client.disable_default_operator(); + + cluster.run(); + + for i in 0..10 { + cluster.must_put(format!("k{}", i).as_bytes(), b"v1"); + } + let region = pd_client.get_region(b"k1").unwrap(); + cluster.must_split(®ion, b"k5"); + + let left = pd_client.get_region(b"k1").unwrap(); + let mut right = pd_client.get_region(b"k5").unwrap(); + let left_peer_1 = find_peer(&left, 1).cloned().unwrap(); + cluster.must_transfer_leader(left.get_id(), left_peer_1.clone()); + + let left_peer_3 = find_peer(&left, 3).cloned().unwrap(); + assert_eq!(left_peer_3.get_id(), 1003); + + // Prevent sched_merge_tick to propose CommitMerge + let schedule_merge_fp = "on_schedule_merge"; + fail::cfg(schedule_merge_fp, "return()").unwrap(); + + // To minimize peers log gap for merging + cluster.must_put(b"k11", b"v2"); + must_get_equal(&cluster.get_engine(2), b"k11", b"v2"); + must_get_equal(&cluster.get_engine(3), b"k11", b"v2"); + // Make peer 1003 can't receive PrepareMerge and RollbackMerge log + cluster.add_send_filter(IsolationFilterFactory::new(3)); + + cluster.try_merge(left.get_id(), right.get_id()); + + // Change right region's epoch to make this merge failed + cluster.must_split(&right, b"k8"); + fail::remove(schedule_merge_fp); + // Wait for left region to rollback merge + cluster.must_put(b"k12", b"v2"); + // Prevent the `PrepareMerge` and `RollbackMerge` log sending to apply fsm after + // cleaning send filter. Since this method is just to check `RollbackMerge`, + // the `PrepareMerge` may escape, but it makes the best effort. + let before_send_rollback_merge_1003_fp = "before_send_rollback_merge_1003"; + fail::cfg(before_send_rollback_merge_1003_fp, "pause").unwrap(); + cluster.clear_send_filters(); + + right = pd_client.get_region(b"k5").unwrap(); + let right_peer_1 = find_peer(&right, 1).cloned().unwrap(); + cluster.must_transfer_leader(right.get_id(), right_peer_1); + // Add some data for checking data integrity check at a later time + for i in 0..5 { + cluster.must_put(format!("k2{}", i).as_bytes(), b"v3"); + } + // Do a really succeed merge + pd_client.must_merge(left.get_id(), right.get_id()); + // Wait right region to send CatchUpLogs to left region. + sleep_ms(100); + // After executing CatchUpLogs in source peer fsm, the committed log will send + // to apply fsm in the end of this batch. So even the first `on_ready_prepare_merge` + // is executed after CatchUplogs, the latter committed logs is still sent to apply fsm + // if CatchUpLogs and `on_ready_prepare_merge` is in different batch. + // + // In this case, the data is complete because the wrong up-to-date msg from the + // first `on_ready_prepare_merge` is sent after all committed log. + // Sleep a while to wait apply fsm to send `on_ready_prepare_merge` to peer fsm. + let after_send_to_apply_1003_fp = "after_send_to_apply_1003"; + fail::cfg(after_send_to_apply_1003_fp, "sleep(300)").unwrap(); + + fail::remove(before_send_rollback_merge_1003_fp); + // Wait `after_send_to_apply_1003` timeout + sleep_ms(300); + fail::remove(after_send_to_apply_1003_fp); + // Check the data integrity + for i in 0..5 { + must_get_equal(&cluster.get_engine(3), format!("k2{}", i).as_bytes(), b"v3"); + } +} + +/// Tests whether the source peer is destroyed correctly when transferring leader during committing merge. +/// +/// In the previous merge flow, target peer deletes meta of source peer without marking it as pending remove. +/// If source peer becomes leader at the same time, it will panic due to corrupted meta. +#[test] +fn test_node_merge_transfer_leader() { + let _guard = crate::setup(); + let mut cluster = new_node_cluster(0, 3); + configure_for_merge(&mut cluster); + cluster.cfg.raft_store.store_max_batch_size = 1; + cluster.cfg.raft_store.store_pool_size = 2; + let pd_client = Arc::clone(&cluster.pd_client); + pd_client.disable_default_operator(); + + cluster.run(); + + let region = pd_client.get_region(b"k1").unwrap(); + cluster.must_split(®ion, b"k2"); + + cluster.must_put(b"k1", b"v1"); + cluster.must_put(b"k3", b"v3"); + + let left = pd_client.get_region(b"k1").unwrap(); + let right = pd_client.get_region(b"k2").unwrap(); + + let left_peer_1 = find_peer(&left, 1).unwrap().to_owned(); + cluster.must_transfer_leader(left.get_id(), left_peer_1.clone()); + + let schedule_merge_fp = "on_schedule_merge"; + fail::cfg(schedule_merge_fp, "return()").unwrap(); + + cluster.try_merge(left.get_id(), right.get_id()); + + let left_peer_3 = find_peer(&left, 3).unwrap().to_owned(); + assert_eq!(left_peer_3.get_id(), 1003); + // Prevent peer 1003 to handle ready when it's leader + let before_handle_raft_ready_1003 = "before_handle_raft_ready_1003"; + fail::cfg(before_handle_raft_ready_1003, "pause").unwrap(); + + let epoch = cluster.get_region_epoch(left.get_id()); + let mut transfer_leader_req = + new_admin_request(left.get_id(), &epoch, new_transfer_leader_cmd(left_peer_3)); + transfer_leader_req.mut_header().set_peer(left_peer_1); + cluster + .sim + .rl() + .async_command_on_node(1, transfer_leader_req, Callback::None) + .unwrap(); + fail::remove(schedule_merge_fp); + + pd_client.check_merged_timeout(left.get_id(), Duration::from_secs(5)); + + fail::remove(before_handle_raft_ready_1003); + sleep_ms(100); + cluster.must_put(b"k4", b"v4"); + must_get_equal(&cluster.get_engine(3), b"k4", b"v4"); +} + +#[test] +fn test_merge_cascade_merge_with_apply_yield() { + let _guard = crate::setup(); + let mut cluster = new_node_cluster(0, 3); + configure_for_merge(&mut cluster); + let pd_client = Arc::clone(&cluster.pd_client); + pd_client.disable_default_operator(); + + cluster.run(); + + let region = pd_client.get_region(b"k1").unwrap(); + cluster.must_split(®ion, b"k5"); + let region = pd_client.get_region(b"k5").unwrap(); + cluster.must_split(®ion, b"k9"); + + for i in 0..10 { + cluster.must_put(format!("k{}", i).as_bytes(), b"v1"); + } + + let r1 = pd_client.get_region(b"k1").unwrap(); + let r2 = pd_client.get_region(b"k5").unwrap(); + let r3 = pd_client.get_region(b"k9").unwrap(); + + pd_client.must_merge(r2.get_id(), r1.get_id()); + assert_eq!(r1.get_id(), 1000); + let apply_yield_1000_fp = "apply_yield_1000"; + fail::cfg(apply_yield_1000_fp, "80%3*return()").unwrap(); + + for i in 0..10 { + cluster.must_put(format!("k{}", i).as_bytes(), b"v2"); + } + + pd_client.must_merge(r3.get_id(), r1.get_id()); + + for i in 0..10 { + cluster.must_put(format!("k{}", i).as_bytes(), b"v3"); + } +} diff --git a/tests/failpoints/cases/test_replica_read.rs b/tests/failpoints/cases/test_replica_read.rs index d48ddda228e..c1c019463ad 100644 --- a/tests/failpoints/cases/test_replica_read.rs +++ b/tests/failpoints/cases/test_replica_read.rs @@ -1,12 +1,12 @@ // Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0. +use crossbeam::channel; use engine::{Peekable, CF_RAFT, DB}; use fail; use kvproto::raft_serverpb::{PeerState, RaftApplyState, RaftMessage, RegionLocalState}; use raft::eraftpb::MessageType; use std::mem; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc; +use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; @@ -97,7 +97,7 @@ fn test_duplicate_read_index_ctx() { // Delay all raft messages to peer 1. let dropped_msgs = Arc::new(Mutex::new(Vec::new())); - let (sx, rx) = mpsc::sync_channel::<()>(2); + let (sx, rx) = channel::unbounded(); let recv_filter = Box::new( RegionPacketFilter::new(region.get_id(), 1) .direction(Direction::Recv) @@ -292,19 +292,19 @@ fn test_read_after_cleanup_range_for_snap() { assert_eq!(cluster.leader_of_region(region.get_id()).unwrap(), p1); cluster.stop_node(3); (0..10).for_each(|_| cluster.must_put(b"k1", b"v1")); - // Ensure logs are compacted. - must_truncated_to(cluster.get_engine(3), r1, 8); + // Ensure logs are compacted, then node 1 will send a snapshot to node 3 later + must_truncated_to(cluster.get_engine(1), r1, 8); fail::cfg("send_snapshot", "pause").unwrap(); cluster.run_node(3).unwrap(); // Sleep for a while to ensure peer 3 receives a HeartBeat thread::sleep(Duration::from_millis(500)); + // Add filter for delaying ReadIndexResp and MsgSnapshot let dropped_msgs = Arc::new(Mutex::new(Vec::new())); - let (read_index_sx, read_index_rx) = mpsc::sync_channel::(1); - let (snap_sx, snap_rx) = mpsc::sync_channel::(1); - let (heartbeat_sx, heartbeat_rx) = mpsc::sync_channel::(1); - let is_recv_heartbeat = AtomicBool::new(false); + let (read_index_sx, read_index_rx) = channel::unbounded::(); + let (snap_sx, snap_rx) = channel::unbounded::(); + let (heartbeat_sx, heartbeat_rx) = channel::unbounded::(); let recv_filter = Box::new( RegionPacketFilter::new(region.get_id(), 3) .direction(Direction::Recv) @@ -316,9 +316,7 @@ fn test_read_after_cleanup_range_for_snap() { } else if msg.get_message().get_msg_type() == MessageType::MsgSnapshot { snap_sx.send(msg.clone()).unwrap(); } else if msg.get_message().get_msg_type() == MessageType::MsgHeartbeat { - if is_recv_heartbeat.compare_and_swap(false, true, Ordering::SeqCst) { - heartbeat_sx.send(msg.clone()).unwrap(); - } + heartbeat_sx.send(msg.clone()).unwrap(); } })), ); @@ -334,7 +332,7 @@ fn test_read_after_cleanup_range_for_snap() { ); request.mut_header().set_peer(p3.clone()); request.mut_header().set_replica_read(true); - // send request to peer 3 + // Send follower read request to peer 3 let (cb1, rx1) = make_cb(&request); cluster .sim @@ -355,6 +353,7 @@ fn test_read_after_cleanup_range_for_snap() { router.send_raft_message(read_index_msg.clone()).unwrap(); fail::cfg("pause_on_peer_collect_message", "off").unwrap(); must_get_none(&cluster.get_engine(3), b"k0"); + // Should not receive resp rx1.recv_timeout(Duration::from_millis(500)).unwrap_err(); fail::cfg("apply_snap_cleanup_range", "off").unwrap(); rx1.recv_timeout(Duration::from_secs(5)).unwrap(); diff --git a/tests/failpoints/cases/test_stale_read.rs b/tests/failpoints/cases/test_stale_read.rs index 8fc3c98d660..eb722a7d75b 100644 --- a/tests/failpoints/cases/test_stale_read.rs +++ b/tests/failpoints/cases/test_stale_read.rs @@ -374,6 +374,7 @@ fn test_read_index_when_transfer_leader_2() { let filter = Box::new( RegionPacketFilter::new(r1.get_id(), old_leader.get_store_id()) .direction(Direction::Recv) + .skip(MessageType::MsgTransferLeader) .when(Arc::new(AtomicBool::new(true))) .reserve_dropped(Arc::clone(&dropped_msgs)), ); diff --git a/tests/failpoints/cases/test_transfer_leader.rs b/tests/failpoints/cases/test_transfer_leader.rs new file mode 100644 index 00000000000..cf236328ca6 --- /dev/null +++ b/tests/failpoints/cases/test_transfer_leader.rs @@ -0,0 +1,41 @@ +// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0. + +use fail; +use test_raftstore::*; + +/// When a follower applies log slowly, leader should not transfer leader +/// to it. Otherwise, new leader may wait a long time to serve read/write +/// requests. +#[test] +fn test_transfer_leader_slow_apply() { + let _guard = crate::setup(); + + // 3 nodes cluster. + let mut cluster = new_node_cluster(0, 3); + + let pd_client = cluster.pd_client.clone(); + pd_client.disable_default_operator(); + + let r1 = cluster.run_conf_change(); + pd_client.must_add_peer(r1, new_peer(2, 1002)); + pd_client.must_add_peer(r1, new_peer(3, 1003)); + + cluster.must_put(b"k1", b"v1"); + must_get_equal(&cluster.get_engine(2), b"k1", b"v1"); + must_get_equal(&cluster.get_engine(3), b"k1", b"v1"); + + let fp = "on_handle_apply_1003"; + fail::cfg(fp, "pause").unwrap(); + for i in 0..=cluster.cfg.raft_store.leader_transfer_max_log_lag { + let bytes = format!("k{:03}", i).into_bytes(); + cluster.must_put(&bytes, &bytes); + } + cluster.transfer_leader(r1, new_peer(3, 1003)); + cluster.must_put(b"k2", b"v2"); + must_get_equal(&cluster.get_engine(1), b"k2", b"v2"); + assert_ne!(cluster.leader_of_region(r1).unwrap(), new_peer(3, 1003)); + fail::remove(fp); + cluster.must_transfer_leader(r1, new_peer(3, 1003)); + cluster.must_put(b"k3", b"v3"); + must_get_equal(&cluster.get_engine(3), b"k3", b"v3"); +} diff --git a/tests/integrations/raftstore/test_conf_change.rs b/tests/integrations/raftstore/test_conf_change.rs index 94ef1d7afb9..8b0769d4823 100644 --- a/tests/integrations/raftstore/test_conf_change.rs +++ b/tests/integrations/raftstore/test_conf_change.rs @@ -3,7 +3,7 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::Arc; use std::thread; -use std::time::Duration; +use std::time::*; use futures::Future; @@ -897,3 +897,22 @@ where let admin_req = new_admin_request(region_id, &epoch, conf_change); cluster.call_command_on_leader(admin_req, Duration::from_secs(3)) } + +/// Tests if conf change relies on heartbeat. +#[test] +fn test_conf_change_fast() { + let mut cluster = new_server_cluster(0, 3); + // Sets heartbeat timeout to more than 5 seconds. It also changes the election timeout, + // but it's OK as the cluster starts with only one peer, it will campaigns immediately. + configure_for_lease_read(&mut cluster, Some(5000), None); + let pd_client = Arc::clone(&cluster.pd_client); + pd_client.disable_default_operator(); + let r1 = cluster.run_conf_change(); + cluster.must_put(b"k1", b"v1"); + let timer = Instant::now(); + // If conf change relies on heartbeat, it will take more than 5 seconds to finish, + // hence it must timeout. + pd_client.must_add_peer(r1, new_peer(2, 2)); + must_get_equal(&cluster.get_engine(2), b"k1", b"v1"); + assert!(timer.elapsed() < Duration::from_secs(5)); +} diff --git a/tests/integrations/raftstore/test_lease_read.rs b/tests/integrations/raftstore/test_lease_read.rs index d53bbc6e071..13d19b98684 100644 --- a/tests/integrations/raftstore/test_lease_read.rs +++ b/tests/integrations/raftstore/test_lease_read.rs @@ -383,6 +383,7 @@ fn test_read_index_when_transfer_leader_1() { let filter = Box::new( RegionPacketFilter::new(r1.get_id(), old_leader.get_store_id()) .direction(Direction::Recv) + .skip(MessageType::MsgTransferLeader) .when(Arc::new(AtomicBool::new(true))) .reserve_dropped(Arc::clone(&dropped_msgs)), ); diff --git a/tests/integrations/raftstore/test_merge.rs b/tests/integrations/raftstore/test_merge.rs index f19bb12edab..1df72de4720 100644 --- a/tests/integrations/raftstore/test_merge.rs +++ b/tests/integrations/raftstore/test_merge.rs @@ -3,7 +3,7 @@ use std::iter::*; use std::sync::Arc; use std::thread; -use std::time::Duration; +use std::time::*; use kvproto::raft_cmdpb::CmdType; use kvproto::raft_serverpb::{PeerState, RegionLocalState}; @@ -106,6 +106,10 @@ fn test_node_base_merge() { fn test_node_merge_with_slow_learner() { let mut cluster = new_node_cluster(0, 2); configure_for_merge(&mut cluster); + cluster.cfg.raft_store.raft_log_gc_threshold = 40; + cluster.cfg.raft_store.raft_log_gc_count_limit = 40; + cluster.cfg.raft_store.merge_max_log_gap = 15; + cluster.pd_client.disable_default_operator(); // Create a cluster with peer 1 as leader and peer 2 as learner. let r1 = cluster.run_conf_change(); @@ -129,7 +133,7 @@ fn test_node_merge_with_slow_learner() { must_get_equal(&cluster.get_engine(2), b"k3", b"v3"); cluster.add_send_filter(IsolationFilterFactory::new(2)); - (0..100).for_each(|i| cluster.must_put(b"k1", format!("v{}", i).as_bytes())); + (0..20).for_each(|i| cluster.must_put(b"k1", format!("v{}", i).as_bytes())); // Merge 2 regions under isolation should fail. let merge = new_prepare_merge(right.clone()); @@ -147,7 +151,38 @@ fn test_node_merge_with_slow_learner() { cluster.must_put(b"k11", b"v100"); must_get_equal(&cluster.get_engine(1), b"k11", b"v100"); must_get_equal(&cluster.get_engine(2), b"k11", b"v100"); + + pd_client.must_merge(left.get_id(), right.get_id()); + + // Test slow learner will be cleaned up when merge can't be continued. + let region = pd_client.get_region(b"k1").unwrap(); + cluster.must_split(®ion, b"k5"); + cluster.must_put(b"k4", b"v4"); + cluster.must_put(b"k5", b"v5"); + must_get_equal(&cluster.get_engine(2), b"k4", b"v4"); + must_get_equal(&cluster.get_engine(2), b"k5", b"v5"); + let left = pd_client.get_region(b"k1").unwrap(); + let right = pd_client.get_region(b"k5").unwrap(); + cluster.add_send_filter(IsolationFilterFactory::new(2)); pd_client.must_merge(left.get_id(), right.get_id()); + let state1 = cluster.truncated_state(right.get_id(), 1); + (0..50).for_each(|i| cluster.must_put(b"k2", format!("v{}", i).as_bytes())); + + // wait to trigger compact raft log + let timer = Instant::now(); + loop { + let state2 = cluster.truncated_state(right.get_id(), 1); + if state1.get_index() != state2.get_index() { + break; + } + if timer.elapsed() > Duration::from_secs(3) { + panic!("log compaction not finish after 3 seconds."); + } + sleep_ms(10); + } + cluster.clear_send_filters(); + cluster.must_put(b"k6", b"v6"); + must_get_equal(&cluster.get_engine(2), b"k6", b"v6"); } /// Test whether merge will be aborted if prerequisites is not met. @@ -786,3 +821,63 @@ fn test_merge_with_slow_promote() { cluster.sim.wl().clear_send_filters(3); cluster.must_transfer_leader(left.get_id(), new_peer(3, left.get_id() + 3)); } + +/// Test whether a isolated store recover properly if there is no target peer +/// on this store before isolated. +/// A (-∞, k2), B [k2, +∞) on store 1,2,4 +/// store 4 is isolated +/// B merge to A (target peer A is not created on store 4. It‘s just exist logically) +/// A split => C (-∞, k3), A [k3, +∞) +/// Then network recovery +#[test] +fn test_merge_isolated_store_with_no_target_peer() { + let mut cluster = new_node_cluster(0, 4); + configure_for_merge(&mut cluster); + cluster.cfg.raft_store.right_derive_when_split = true; + let pd_client = Arc::clone(&cluster.pd_client); + pd_client.disable_default_operator(); + + let r1 = cluster.run_conf_change(); + pd_client.must_add_peer(r1, new_peer(2, 2)); + pd_client.must_add_peer(r1, new_peer(3, 3)); + + for i in 0..10 { + cluster.must_put(format!("k{}", i).as_bytes(), b"v1"); + } + + let region = pd_client.get_region(b"k1").unwrap(); + // (-∞, k2), [k2, +∞) + cluster.must_split(®ion, b"k2"); + + let left = pd_client.get_region(b"k1").unwrap(); + let right = pd_client.get_region(b"k2").unwrap(); + + let left_on_store1 = find_peer(&left, 1).unwrap().to_owned(); + cluster.must_transfer_leader(left.get_id(), left_on_store1); + let right_on_store1 = find_peer(&right, 1).unwrap().to_owned(); + cluster.must_transfer_leader(right.get_id(), right_on_store1); + + pd_client.must_add_peer(right.get_id(), new_peer(4, 4)); + let right_on_store3 = find_peer(&right, 3).unwrap().to_owned(); + pd_client.must_remove_peer(right.get_id(), right_on_store3); + + cluster.must_put(b"k22", b"v22"); + must_get_equal(&cluster.get_engine(4), b"k22", b"v22"); + + cluster.add_send_filter(IsolationFilterFactory::new(4)); + + pd_client.must_add_peer(left.get_id(), new_peer(4, 5)); + let left_on_store3 = find_peer(&left, 3).unwrap().to_owned(); + pd_client.must_remove_peer(left.get_id(), left_on_store3); + + pd_client.must_merge(right.get_id(), left.get_id()); + + let new_left = pd_client.get_region(b"k1").unwrap(); + // (-∞, k3), [k3, +∞) + cluster.must_split(&new_left, b"k3"); + // Now new_left region range is [k3, +∞) + cluster.must_put(b"k345", b"v345"); + cluster.clear_send_filters(); + + must_get_equal(&cluster.get_engine(4), b"k345", b"v345"); +} diff --git a/tests/integrations/raftstore/test_transfer_leader.rs b/tests/integrations/raftstore/test_transfer_leader.rs index c4687cc8057..69a106a88ce 100644 --- a/tests/integrations/raftstore/test_transfer_leader.rs +++ b/tests/integrations/raftstore/test_transfer_leader.rs @@ -59,12 +59,6 @@ fn test_server_basic_transfer_leader() { test_basic_transfer_leader(&mut cluster); } -#[test] -fn test_node_basic_transfer_leader() { - let mut cluster = new_node_cluster(0, 3); - test_basic_transfer_leader(&mut cluster); -} - fn test_pd_transfer_leader(cluster: &mut Cluster) { let pd_client = Arc::clone(&cluster.pd_client); pd_client.disable_default_operator(); @@ -116,12 +110,6 @@ fn test_server_pd_transfer_leader() { test_pd_transfer_leader(&mut cluster); } -#[test] -fn test_node_pd_transfer_leader() { - let mut cluster = new_node_cluster(0, 3); - test_pd_transfer_leader(&mut cluster); -} - fn test_transfer_leader_during_snapshot(cluster: &mut Cluster) { let pd_client = Arc::clone(&cluster.pd_client); // Disable default max peer count check. @@ -162,6 +150,7 @@ fn test_transfer_leader_during_snapshot(cluster: &mut Cluster) let resp = cluster.call_command_on_leader(put, Duration::from_secs(5)); // if it's transferring leader, resp will timeout. assert!(resp.is_ok(), "{:?}", resp); + must_get_equal(&cluster.get_engine(1), b"k1", b"v1"); } #[test] @@ -169,9 +158,3 @@ fn test_server_transfer_leader_during_snapshot() { let mut cluster = new_server_cluster(0, 3); test_transfer_leader_during_snapshot(&mut cluster); } - -#[test] -fn test_node_transfer_leader_during_snapshot() { - let mut cluster = new_node_cluster(0, 3); - test_transfer_leader_during_snapshot(&mut cluster); -} diff --git a/tests/integrations/server/lock_manager.rs b/tests/integrations/server/lock_manager.rs index c77cd81b6ad..ef493acf0da 100644 --- a/tests/integrations/server/lock_manager.rs +++ b/tests/integrations/server/lock_manager.rs @@ -39,26 +39,49 @@ fn must_acquire_pessimistic_lock(client: &TikvClient, ctx: Context, key: Vec assert!(resp.errors.is_empty(), "{:?}", resp.get_errors()); } +fn delete_pessimistic_lock( + client: &TikvClient, + ctx: Context, + key: Vec, + ts: u64, +) -> PessimisticRollbackResponse { + let mut req = PessimisticRollbackRequest::default(); + req.set_context(ctx); + req.set_keys(vec![key].into_iter().collect()); + req.start_version = ts; + req.for_update_ts = ts; + client.kv_pessimistic_rollback(&req).unwrap() +} + +fn must_delete_pessimistic_lock(client: &TikvClient, ctx: Context, key: Vec, ts: u64) { + let resp = delete_pessimistic_lock(client, ctx, key, ts); + assert!(!resp.has_region_error(), "{:?}", resp.get_region_error()); + assert!(resp.errors.is_empty(), "{:?}", resp.get_errors()); +} + fn must_deadlock(client: &TikvClient, ctx: Context, key1: &[u8], ts: u64) { let key1 = key1.to_vec(); let mut key2 = key1.clone(); - key2.push(1); + key2.push(0); must_acquire_pessimistic_lock(client, ctx.clone(), key1.clone(), ts); must_acquire_pessimistic_lock(client, ctx.clone(), key2.clone(), ts + 1); - let client1 = client.clone(); - let ctx1 = ctx.clone(); + let (client_clone, ctx_clone, key1_clone) = (client.clone(), ctx.clone(), key1.clone()); let (tx, rx) = mpsc::sync_channel(1); thread::spawn(move || { - let _ = acquire_pessimistic_lock(&client1, ctx1, key1, ts + 1); + let _ = acquire_pessimistic_lock(&client_clone, ctx_clone, key1_clone, ts + 1); tx.send(1).unwrap(); }); // Sleep to make sure txn(ts+1) is waiting for txn(ts) thread::sleep(Duration::from_millis(500)); - let resp = acquire_pessimistic_lock(client, ctx, key2, ts); + let resp = acquire_pessimistic_lock(client, ctx.clone(), key2.clone(), ts); assert_eq!(resp.errors.len(), 1); - assert!(resp.errors[0].has_deadlock()); + assert!(resp.errors[0].has_deadlock(), "{:?}", resp.get_errors()); rx.recv().unwrap(); + + // Clean up + must_delete_pessimistic_lock(client, ctx.clone(), key1, ts); + must_delete_pessimistic_lock(client, ctx, key2, ts); } fn build_leader_client(cluster: &mut Cluster, key: &[u8]) -> (TikvClient, Context) { @@ -79,6 +102,12 @@ fn build_leader_client(cluster: &mut Cluster, key: &[u8]) -> (Tik (client, ctx) } +/// Creates a deadlock on the store containing key. +fn must_detect_deadlock(cluster: &mut Cluster, key: &[u8], ts: u64) { + let (client, ctx) = build_leader_client(cluster, key); + must_deadlock(&client, ctx, key, ts); +} + fn deadlock_detector_leader_must_be(cluster: &mut Cluster, store_id: u64) { let leader_region = cluster.get_region(b""); assert_eq!( @@ -104,6 +133,41 @@ fn must_transfer_leader(cluster: &mut Cluster, region_key: &[u8], cluster.must_get(region_key); } +/// Transfers the region containing region_key from source store to target peer. +/// +/// REQUIRE: The source store must be the leader the region and the target store must not have +/// this region. +fn must_transfer_region( + cluster: &mut Cluster, + region_key: &[u8], + source_store_id: u64, + target_store_id: u64, + target_peer_id: u64, +) { + let target_peer = new_peer(target_store_id, target_peer_id); + let region = cluster.get_region(region_key); + cluster + .pd_client + .must_add_peer(region.get_id(), target_peer.clone()); + must_transfer_leader(cluster, region_key, target_store_id); + let source_peer = find_peer_of_store(®ion, source_store_id); + cluster + .pd_client + .must_remove_peer(region.get_id(), source_peer); +} + +fn must_merge_region( + cluster: &mut Cluster, + source_region_key: &[u8], + target_region_key: &[u8], +) { + let (source_id, target_id) = ( + cluster.get_region(source_region_key).get_id(), + cluster.get_region(target_region_key).get_id(), + ); + cluster.pd_client.must_merge(source_id, target_id); +} + fn find_peer_of_store(region: &Region, store_id: u64) -> Peer { region .get_peers() @@ -113,56 +177,100 @@ fn find_peer_of_store(region: &Region, store_id: u64) -> Peer { .clone() } -#[test] -fn test_detect_deadlock_when_shuffle_region() { - let mut cluster = new_server_cluster(0, 4); +/// Creates a cluster with only one region and store(1) is the leader of the region. +fn new_cluster_for_deadlock_test(count: usize) -> Cluster { + let mut cluster = new_server_cluster(0, count); let pd_client = Arc::clone(&cluster.pd_client); // Disable default max peer count check. pd_client.disable_default_operator(); - // Region 1 has 3 peers. And peer(1, 1) is the leader of region 1. let region_id = cluster.run_conf_change(); pd_client.must_add_peer(region_id, new_peer(2, 2)); pd_client.must_add_peer(region_id, new_peer(3, 3)); - - // The leader of deadlock detector is the leader of region 1. deadlock_detector_leader_must_be(&mut cluster, 1); - let (client, ctx) = build_leader_client(&mut cluster, b"k1"); - must_deadlock(&client, ctx, b"k1", 10); + must_detect_deadlock(&mut cluster, b"k", 10); + cluster +} - // The leader of region 1 has transfered. The leader of deadlock detector should also transfer. +#[test] +fn test_detect_deadlock_when_transfer_leader() { + let mut cluster = new_cluster_for_deadlock_test(3); + // Transfer the leader of region 1 to store(2). + // The leader of deadlock detector should also be transfered to store(2). must_transfer_leader(&mut cluster, b"", 2); deadlock_detector_leader_must_be(&mut cluster, 2); - let (client, ctx) = build_leader_client(&mut cluster, b"k2"); - must_deadlock(&client, ctx, b"k2", 20); + must_detect_deadlock(&mut cluster, b"k", 10); +} - // Split region and transfer the leader of new region to store(3). +#[test] +fn test_detect_deadlock_when_split_region() { + let mut cluster = new_cluster_for_deadlock_test(3); let region = cluster.get_region(b""); - cluster.must_split(®ion, b"k10"); - must_transfer_leader(&mut cluster, b"k10", 3); - // Deadlock occurs on store(3) and the leader of deadlock detector is store(2). - deadlock_detector_leader_must_be(&mut cluster, 2); - let (client, ctx) = build_leader_client(&mut cluster, b"k10"); - must_deadlock(&client, ctx, b"k10", 30); - - // Transfer the new region from store(1, 2, 3) to store(2, 3, 4). - let new_region = cluster.get_region(b"k10"); - pd_client.must_add_peer(new_region.get_id(), new_peer(4, 4)); - must_transfer_leader(&mut cluster, b"k10", 4); - let peer = find_peer_of_store(&new_region, 1); - pd_client.must_remove_peer(region_id, peer); - - // Transfer the leader of deadlock detector to store(1) and - // deadlock occours on store(4) again. - must_transfer_leader(&mut cluster, b"", 1); + cluster.must_split(®ion, b"k1"); + // After split, the leader is still store(1). deadlock_detector_leader_must_be(&mut cluster, 1); - let (client, ctx) = build_leader_client(&mut cluster, b"k11"); - must_deadlock(&client, ctx, b"k11", 30); - - // Add store(1) back again which will send a role change message with empty region key range to - // the deadlock detector. It misleads the leader of deadlock detector stepping down. - pd_client.must_add_peer(new_region.get_id(), new_peer(1, 5)); + must_detect_deadlock(&mut cluster, b"k", 10); + // Transfer the new region's leader to store(2) and deadlock occours on it. + must_transfer_leader(&mut cluster, b"k1", 2); deadlock_detector_leader_must_be(&mut cluster, 1); - let (client, ctx) = build_leader_client(&mut cluster, b"k3"); - must_deadlock(&client, ctx, b"k3", 10); + must_detect_deadlock(&mut cluster, b"k1", 10); +} + +#[test] +fn test_detect_deadlock_when_transfer_region() { + let mut cluster = new_cluster_for_deadlock_test(4); + // Transfer the leader region to store(4) and the leader of deadlock detector should be + // also transfered. + must_transfer_region(&mut cluster, b"k", 1, 4, 4); + deadlock_detector_leader_must_be(&mut cluster, 4); + must_detect_deadlock(&mut cluster, b"k", 10); + + let region = cluster.get_region(b""); + cluster.must_split(®ion, b"k1"); + // Transfer the new region to store(1). It shouldn't affect deadlock detector. + must_transfer_region(&mut cluster, b"k1", 4, 1, 5); + deadlock_detector_leader_must_be(&mut cluster, 4); + must_detect_deadlock(&mut cluster, b"k", 10); + must_detect_deadlock(&mut cluster, b"k1", 10); + + // Transfer the new region back to store(4) which will send a role change message with empty + // key range. It shouldn't affect deadlock detector. + must_transfer_region(&mut cluster, b"k1", 1, 4, 6); + deadlock_detector_leader_must_be(&mut cluster, 4); + must_detect_deadlock(&mut cluster, b"k", 10); + must_detect_deadlock(&mut cluster, b"k1", 10); +} + +#[test] +fn test_detect_deadlock_when_merge_region() { + let mut cluster = new_cluster_for_deadlock_test(3); + + // Source region will be destroyed. + for as_target in &[false, true] { + let region = cluster.get_region(b""); + cluster.must_split(®ion, b"k1"); + if *as_target { + must_merge_region(&mut cluster, b"k1", b""); + } else { + must_merge_region(&mut cluster, b"", b"k1"); + } + deadlock_detector_leader_must_be(&mut cluster, 1); + must_detect_deadlock(&mut cluster, b"k", 10); + } + + // Leaders of two regions are on different store. + for as_target in &[false, true] { + let region = cluster.get_region(b""); + cluster.must_split(®ion, b"k1"); + must_transfer_leader(&mut cluster, b"k1", 2); + if *as_target { + must_merge_region(&mut cluster, b"k1", b""); + deadlock_detector_leader_must_be(&mut cluster, 1); + } else { + must_merge_region(&mut cluster, b"", b"k1"); + deadlock_detector_leader_must_be(&mut cluster, 2); + } + must_detect_deadlock(&mut cluster, b"k", 10); + must_transfer_leader(&mut cluster, b"", 1); + } } diff --git a/tests/integrations/storage/test_raft_storage.rs b/tests/integrations/storage/test_raft_storage.rs index 02dfdeb4dd1..3dac8ea3ea5 100644 --- a/tests/integrations/storage/test_raft_storage.rs +++ b/tests/integrations/storage/test_raft_storage.rs @@ -4,7 +4,6 @@ use std::thread; use std::time::Duration; use kvproto::kvrpcpb::Context; -use std::collections::HashMap; use std::sync::mpsc::channel; use std::sync::Arc; use test_raftstore::*; @@ -12,6 +11,7 @@ use test_storage::*; use tikv::storage::config::Config; use tikv::storage::{self, AutoGCConfig, Engine, Key, Mutation}; use tikv::storage::{kv, mvcc, txn}; +use tikv_util::collections::HashMap; use tikv_util::HandyRwLock; fn new_raft_storage() -> ( diff --git a/tiflash-proxy/src/lib.rs b/tiflash-proxy/src/lib.rs index 648881a5f45..66f2e59adb4 100644 --- a/tiflash-proxy/src/lib.rs +++ b/tiflash-proxy/src/lib.rs @@ -27,7 +27,7 @@ pub use tiflash_raft_proxy::run_tiflash_proxy_ffi; fn proxy_version_info() -> String { let fallback = "Unknown (env var does not exist when building)"; format!( - "\nRelease Version: {}\ + "Release Version: {}\ \nGit Commit Hash: {}\ \nGit Commit Branch: {}\ \nUTC Build Time: {}\