diff --git a/Cargo.lock b/Cargo.lock index 9752e54f..1e3d5a3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.26.2", + "gimli", ] [[package]] @@ -17,7 +17,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "gimli 0.27.3", + "gimli", ] [[package]] @@ -26,17 +26,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "ahash" version = "0.8.3" @@ -50,9 +39,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -72,11 +61,23 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "allocator-api2" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" + [[package]] name = "ambient-authority" -version = "0.0.1" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + +[[package]] +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8ad6edb4840b78c5c3d88de606b22252d552b55f3a4699fbb10fc070ec3049" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] name = "android_system_properties" @@ -98,21 +99,21 @@ dependencies = [ "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal 0.4.7", + "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -158,10 +159,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] -name = "arrayvec" -version = "0.7.2" +name = "async-bincode" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "0688a53af69da2208017b6d68ea675f073fbbc2488e71cc9b40af48ad9404fc2" +dependencies = [ + "bincode", + "byteorder", + "bytes 1.4.0", + "futures-core", + "futures-sink", + "serde", + "tokio", +] [[package]] name = "async-compression" @@ -191,7 +201,7 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.19", + "rustix 0.37.23", "slab", "socket2", "waker-fn", @@ -225,18 +235,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -245,17 +255,6 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -285,7 +284,7 @@ dependencies = [ "http", "hyper", "ring", - "time 0.3.21", + "time 0.3.23", "tokio", "tower", "tracing", @@ -455,7 +454,7 @@ dependencies = [ "percent-encoding", "regex", "sha2", - "time 0.3.21", + "time 0.3.23", "tracing", ] @@ -595,7 +594,7 @@ dependencies = [ "itoa", "num-integer", "ryu", - "time 0.3.21", + "time 0.3.23", ] [[package]] @@ -730,13 +729,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.6", + "prettyplease 0.2.10", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -762,9 +761,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "block-buffer" @@ -862,7 +861,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -913,39 +912,38 @@ dependencies = [ [[package]] name = "cap-fs-ext" -version = "0.26.1" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0e103ce36d217d568903ad27b14ec2238ecb5d65bad2e756a8f3c0d651506e" +checksum = "58bc48200a1a0fa6fba138b1802ad7def18ec1cdd92f7b2a04e21f1bd887f7b9" dependencies = [ "cap-primitives", "cap-std", - "io-lifetimes 0.7.5", - "windows-sys 0.36.1", + "io-lifetimes 1.0.11", + "windows-sys 0.48.0", ] [[package]] name = "cap-primitives" -version = "0.26.1" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3f336aa91cce16033ed3c94ac91d98956c49b420e6d6cd0dd7d0e386a57085" +checksum = "a4b6df5b295dca8d56f35560be8c391d59f0420f72e546997154e24e765e6451" dependencies = [ "ambient-authority", "fs-set-times", "io-extras", - "io-lifetimes 0.7.5", + "io-lifetimes 1.0.11", "ipnet", "maybe-owned", - "rustix 0.35.13", - "winapi-util", - "windows-sys 0.36.1", - "winx", + "rustix 0.37.23", + "windows-sys 0.48.0", + "winx 0.35.1", ] [[package]] name = "cap-rand" -version = "0.26.1" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14b9606aa9550d34651bc481443203bc014237bdb992d201d2afa62d2ec6dea" +checksum = "4d25555efacb0b5244cf1d35833d55d21abc916fff0eaad254b8e2453ea9b8ab" dependencies = [ "ambient-authority", "rand", @@ -953,27 +951,26 @@ dependencies = [ [[package]] name = "cap-std" -version = "0.26.1" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d6e70b626eceac9d6fc790fe2d72cc3f2f7bc3c35f467690c54a526b0f56db" +checksum = "3373a62accd150b4fcba056d4c5f3b552127f0ec86d3c8c102d60b978174a012" dependencies = [ "cap-primitives", "io-extras", - "io-lifetimes 0.7.5", - "ipnet", - "rustix 0.35.13", + "io-lifetimes 1.0.11", + "rustix 0.37.23", ] [[package]] name = "cap-time-ext" -version = "0.26.1" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a0524f7c4cff2ea547ae2b652bf7a348fd3e48f76556dc928d8b45ab2f1d50" +checksum = "e95002993b7baee6b66c8950470e59e5226a23b3af39fc59c47fe416dd39821a" dependencies = [ "cap-primitives", "once_cell", - "rustix 0.35.13", - "winx", + "rustix 0.37.23", + "winx 0.35.1", ] [[package]] @@ -1024,13 +1021,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", "time 0.1.45", @@ -1081,7 +1078,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -1158,9 +1155,9 @@ dependencies = [ [[package]] name = "console-subscriber" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ab2224a0311582eb03adba4caaf18644f7b1f10a760803a803b9b605187fc7" +checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" dependencies = [ "console-api", "crossbeam-channel", @@ -1195,7 +1192,7 @@ dependencies = [ "log", "mime", "paste", - "pin-project 1.1.0", + "pin-project 1.1.2", "serde", "serde_json", "tar", @@ -1231,37 +1228,37 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62c772976416112fa4484cbd688cb6fb35fd430005c1c586224fc014018abad" +checksum = "182b82f78049f54d3aee5a19870d356ef754226665a695ce2fcdd5d55379718e" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b40ed2dd13c2ac7e24f88a3090c68ad3414eb1d066a95f8f1f7b3b819cb4e46" +checksum = "e7c027bf04ecae5b048d3554deb888061bc26f426afff47bf06d6ac933dce0a6" dependencies = [ - "arrayvec", "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", - "cranelift-egraph", + "cranelift-control", "cranelift-entity", "cranelift-isle", - "gimli 0.26.2", + "gimli", + "hashbrown 0.13.2", "log", "regalloc2", "smallvec", @@ -1270,47 +1267,42 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb927a8f1c27c34ee3759b6b0ffa528d2330405d5cc4511f0cab33fe2279f4b5" +checksum = "649f70038235e4c81dba5680d7e5ae83e1081f567232425ab98b55b03afd9904" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43dfa417b884a9ab488d95fd6b93b25e959321fe7bfd7a0a960ba5d7fb7ab927" +checksum = "7a1d1c5ee2611c6a0bdc8d42d5d3dc5ce8bf53a8040561e26e88b9b21f966417" [[package]] -name = "cranelift-egraph" -version = "0.90.1" +name = "cranelift-control" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a66b39785efd8513d2cca967ede56d6cc57c8d7986a595c7c47d0c78de8dce" +checksum = "da66a68b1f48da863d1d53209b8ddb1a6236411d2d72a280ffa8c2f734f7219e" dependencies = [ - "cranelift-entity", - "fxhash", - "hashbrown 0.12.3", - "indexmap 1.9.3", - "log", - "smallvec", + "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0637ffde963cb5d759bc4d454cfa364b6509e6c74cdaa21298add0ed9276f346" +checksum = "9bd897422dbb66621fa558f4d9209875530c53e3c8f4b13b2849fbb667c431a6" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb72b8342685e850cb037350418f62cc4fc55d6c2eb9c7ca01b82f9f1a6f3d56" +checksum = "05db883114c98cfcd6959f72278d2fec42e01ea6a6982cfe4f20e88eebe86653" dependencies = [ "cranelift-codegen", "log", @@ -1320,15 +1312,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850579cb9e4b448f7c301f1e6e6cbad99abe3f1f1d878a4994cb66e33c6db8cd" +checksum = "84559de86e2564152c87e299c8b2559f9107e9c6d274b24ebeb04fb0a5f4abf8" [[package]] name = "cranelift-native" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a279e5bcba3e0466c734d8d8eb6bfc1ad29e95c37f3e4955b492b5616335e" +checksum = "3f40b57f187f0fe1ffaf281df4adba2b4bc623a0f6651954da9f3c184be72761" dependencies = [ "cranelift-codegen", "libc", @@ -1337,9 +1329,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.90.1" +version = "0.96.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b8c5e7ffb754093fb89ec4bd4f9dbb9f1c955427299e334917d284745835c2" +checksum = "f3eab6084cc789b9dd0b1316241efeb2968199fee709f4bb4fe0fb0923bb468b" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -1421,14 +1413,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] @@ -1444,9 +1436,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -1467,15 +1459,24 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + [[package]] name = "derive_arbitrary" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" +checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.25", ] [[package]] @@ -1580,7 +1581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", - "is-terminal 0.4.7", + "is-terminal", "log", "regex", "termcolor", @@ -1592,17 +1593,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - [[package]] name = "errno" version = "0.3.1" @@ -1676,6 +1666,17 @@ dependencies = [ "instant", ] +[[package]] +name = "fd-lock" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0377f1edc77dbd1118507bc7a66e4ab64d2b90c66f90726dc801e73a8c68f9" +dependencies = [ + "cfg-if", + "rustix 0.38.3", + "windows-sys 0.48.0", +] + [[package]] name = "file-per-thread-logger" version = "0.1.6" @@ -1722,7 +1723,7 @@ checksum = "2cd66269887534af4b0c3e3337404591daa8dc8b9b2b3db71f9523beb4bafb41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -1748,22 +1749,22 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "fs-set-times" -version = "0.17.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a267b6a9304912e018610d53fe07115d8b530b160e85db4d2d3a59f3ddde1aec" +checksum = "6d167b646a876ba8fda6b50ac645cfd96242553cbaf0ca4fccaa39afcbf0801f" dependencies = [ - "io-lifetimes 0.7.5", - "rustix 0.35.13", - "windows-sys 0.36.1", + "io-lifetimes 1.0.11", + "rustix 0.38.3", + "windows-sys 0.48.0", ] [[package]] @@ -1847,7 +1848,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -1901,6 +1902,19 @@ dependencies = [ "byteorder", ] +[[package]] +name = "fxprof-processed-profile" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27d12c0aed7f1e24276a241aadc4cb8ea9f83000f34bc062b7cc2d51e3b0fabd" +dependencies = [ + "bitflags 2.3.3", + "debugid", + "fxhash", + "serde", + "serde_json", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1913,43 +1927,26 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "ghost" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.23", -] - [[package]] name = "gimli" -version = "0.26.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" dependencies = [ "fallible-iterator 0.2.0", "indexmap 1.9.3", "stable_deref_trait", ] -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - [[package]] name = "glob" version = "0.3.1" @@ -1958,9 +1955,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes 1.4.0", "fnv", @@ -1980,9 +1977,6 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.6", -] [[package]] name = "hashbrown" @@ -1990,7 +1984,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash", ] [[package]] @@ -1998,14 +1992,18 @@ name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashlink" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0761a1b9491c4f2e3d66aa0f62d0fba0af9a0e2852e4d48ea506632a4b56e6aa" +checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.14.0", ] [[package]] @@ -2029,27 +2027,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -2153,15 +2133,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.21.1", + "rustls 0.21.3", "tokio", - "tokio-rustls 0.24.0", + "tokio-rustls 0.24.1", ] [[package]] @@ -2196,7 +2177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "226df6fd0aece319a325419d770aa9d947defa60463f142cd82b329121f906a3" dependencies = [ "hyper", - "pin-project 1.1.0", + "pin-project 1.1.2", "tokio", "tokio-tungstenite", "tungstenite", @@ -2211,15 +2192,15 @@ dependencies = [ "futures-util", "hex", "hyper", - "pin-project 1.1.0", + "pin-project 1.1.2", "tokio", ] [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2238,11 +2219,17 @@ dependencies = [ "cc", ] +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2277,9 +2264,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.29.0" +version = "1.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a28d25139df397cbca21408bb742cf6837e04cdbebf1b07b760caf971d6a972" +checksum = "28491f7753051e5704d4d0ae7860d45fae3238d7d235bc4289dcd45c48d3cec3" dependencies = [ "console", "lazy_static", @@ -2300,31 +2287,18 @@ dependencies = [ [[package]] name = "inventory" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0539b5de9241582ce6bd6b0ba7399313560151e58c9aaf8b74b711b1bdce644" -dependencies = [ - "ghost", -] +checksum = "c38a87a1e0e2752433cd4b26019a469112a25fb43b30f5ee9b3b898925c5a0f9" [[package]] name = "io-extras" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5d8c2ab5becd8720e30fd25f8fa5500d8dc3fceadd8378f05859bd7b46fc49" -dependencies = [ - "io-lifetimes 0.7.5", - "windows-sys 0.36.1", -] - -[[package]] -name = "io-lifetimes" -version = "0.7.5" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074" +checksum = "fde93d48f0d9277f977a333eca8313695ddd5301dc96f7e02aeddcb0dd99096f" dependencies = [ - "libc", - "windows-sys 0.42.0", + "io-lifetimes 1.0.11", + "windows-sys 0.48.0", ] [[package]] @@ -2333,38 +2307,31 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] [[package]] -name = "ipnet" -version = "2.7.2" +name = "io-lifetimes" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "bffb4def18c48926ccac55c1223e02865ce1a821751a95920448662696e7472c" [[package]] -name = "is-terminal" -version = "0.3.0" +name = "ipnet" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d508111813f9af3afd2f92758f77e4ed2cc9371b642112c6a48d22eb73105c5" -dependencies = [ - "hermit-abi 0.2.6", - "io-lifetimes 0.7.5", - "rustix 0.35.13", - "windows-sys 0.36.1", -] +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes 1.0.11", - "rustix 0.37.19", + "hermit-abi", + "rustix 0.38.3", "windows-sys 0.48.0", ] @@ -2388,9 +2355,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "ittapi" @@ -2423,9 +2390,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -2511,9 +2478,9 @@ dependencies = [ [[package]] name = "libsql-wasmtime-bindings" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcb56f5849df5085e99b7e1bea2e87ff3f93c4143d0922ab43682f904d9cbf59" +checksum = "5c4794ff21e37f83839dad45f8c7977b071315f18705cf73badc9850b9fb6b6f" dependencies = [ "wasmtime", "wasmtime-wasi", @@ -2567,6 +2534,7 @@ dependencies = [ name = "libsqlx-server" version = "0.1.0" dependencies = [ + "async-bincode", "axum", "base64 0.21.2", "bincode", @@ -2576,6 +2544,7 @@ dependencies = [ "futures", "hmac", "hyper", + "itertools 0.11.0", "libsqlx", "moka", "parking_lot 0.12.1", @@ -2588,8 +2557,11 @@ dependencies = [ "sled", "thiserror", "tokio", + "tokio-stream", + "tokio-util", "tracing", "tracing-subscriber", + "turmoil", "uuid", ] @@ -2601,21 +2573,21 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.0.46" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -2623,12 +2595,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "mach" @@ -2696,7 +2665,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" dependencies = [ - "rustix 0.37.19", + "rustix 0.37.23", ] [[package]] @@ -2711,27 +2680,27 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -2768,14 +2737,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -2894,11 +2862,20 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ - "hermit-abi 0.2.6", "libc", ] @@ -2910,12 +2887,12 @@ checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" [[package]] name = "object" -version = "0.29.0" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "crc32fast", - "hashbrown 0.12.3", + "hashbrown 0.13.2", "indexmap 1.9.3", "memchr", ] @@ -2966,9 +2943,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -2987,7 +2964,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -2998,9 +2975,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ "cc", "libc", @@ -3050,7 +3027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.7", + "parking_lot_core 0.9.8", ] [[package]] @@ -3069,22 +3046,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "smallvec", - "windows-sys 0.45.0", + "windows-targets 0.48.1", ] [[package]] name = "paste" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" [[package]] name = "peeking_take_while" @@ -3103,9 +3080,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "petgraph" @@ -3119,18 +3096,18 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ "phf_shared", ] [[package]] name = "phf_codegen" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ "phf_generator", "phf_shared", @@ -3138,9 +3115,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", "rand", @@ -3148,9 +3125,9 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", "uncased", @@ -3167,11 +3144,11 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ - "pin-project-internal 1.1.0", + "pin-project-internal 1.1.2", ] [[package]] @@ -3187,20 +3164,20 @@ dependencies = [ [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -3284,12 +3261,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b69d39aab54d069e7f2fe8cb970493e7834601ca2d8c65fd7bbd183578080d1" +checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387" dependencies = [ "proc-macro2", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -3304,9 +3281,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] @@ -3394,6 +3371,17 @@ dependencies = [ "cc", ] +[[package]] +name = "pulldown-cmark" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + [[package]] name = "pulldown-cmark" version = "0.9.3" @@ -3466,6 +3454,16 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "rand_xorshift" version = "0.3.0" @@ -3546,12 +3544,13 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.4.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b2eab54204ea0117fe9a060537e0b07a4e72f7c7d182361ecc346cab2240e5" +checksum = "d4a52e724646c6c0800fc456ec43b4165d2f91fba88ceaca06d9e0b400023478" dependencies = [ - "fxhash", + "hashbrown 0.13.2", "log", + "rustc-hash", "slice-group-by", "smallvec", ] @@ -3615,7 +3614,7 @@ dependencies = [ "http", "http-body", "hyper", - "hyper-rustls 0.24.0", + "hyper-rustls 0.24.1", "hyper-tls", "ipnet", "js-sys", @@ -3625,14 +3624,14 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.1", + "rustls 0.21.3", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.0", + "tokio-rustls 0.24.1", "tower-service", "url", "wasm-bindgen", @@ -3662,7 +3661,7 @@ name = "rusqlite" version = "0.29.0" source = "git+https://github.com/psarna/rusqlite?rev=d9a97c0f25#d9a97c0f25d48272c91d3f8d93d46cb405c39037" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "fallible-iterator 0.2.0", "fallible-streaming-iterator", "hashlink", @@ -3693,31 +3692,30 @@ dependencies = [ [[package]] name = "rustix" -version = "0.35.13" +version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ "bitflags 1.3.2", - "errno 0.2.8", - "io-lifetimes 0.7.5", + "errno", + "io-lifetimes 1.0.11", "itoa", "libc", - "linux-raw-sys 0.0.46", + "linux-raw-sys 0.3.8", "once_cell", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "rustix" -version = "0.37.19" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" dependencies = [ - "bitflags 1.3.2", - "errno 0.3.1", - "io-lifetimes 1.0.11", + "bitflags 2.3.3", + "errno", "libc", - "linux-raw-sys 0.3.8", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] @@ -3735,9 +3733,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.1" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" dependencies = [ "log", "ring", @@ -3747,9 +3745,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -3759,18 +3757,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ "base64 0.21.2", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" dependencies = [ "ring", "untrusted", @@ -3778,9 +3776,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "rusty-fork" @@ -3796,9 +3794,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "same-file" @@ -3811,11 +3809,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -3827,6 +3825,12 @@ dependencies = [ "parking_lot 0.12.1", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.1.0" @@ -3888,22 +3892,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.166" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.166" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -3920,10 +3924,11 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" dependencies = [ + "itoa", "serde", ] @@ -3963,9 +3968,9 @@ dependencies = [ [[package]] name = "sha256" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f8b5de2bac3a4ae28e9b611072a8e326d9b26c8189c0972d4c321fa684f1f" +checksum = "08a975c1bc0941703000eaf232c4d8ce188d8d5408d6344b6b2c8c6262772828" dependencies = [ "hex", "sha2", @@ -4019,7 +4024,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror", - "time 0.3.21", + "time 0.3.23", ] [[package]] @@ -4038,7 +4043,7 @@ dependencies = [ "cargo_metadata", "error-chain", "glob", - "pulldown-cmark", + "pulldown-cmark 0.9.3", "tempfile", "walkdir", ] @@ -4076,9 +4081,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" @@ -4119,6 +4124,7 @@ version = "0.15.0" dependencies = [ "anyhow", "arbitrary", + "async-bincode", "async-lock", "async-trait", "aws-config", @@ -4169,12 +4175,14 @@ dependencies = [ "tokio", "tokio-stream", "tokio-tungstenite", + "tokio-util", "tonic 0.8.3", "tonic-build", "tower", "tower-http", "tracing", "tracing-subscriber", + "turmoil", "url", "uuid", "vergen", @@ -4196,7 +4204,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3995a6daa13c113217b6ad22154865fb06f9cb939bef398fd04f4a7aaaf5bd7" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "cc", "fallible-iterator 0.2.0", "indexmap 1.9.3", @@ -4215,7 +4223,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db68d3f0682b50197a408d65a3246b7d6173399d1325cf0208fb3fdb66e3229f" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "cc", "fallible-iterator 0.3.0", "indexmap 1.9.3", @@ -4265,9 +4273,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ "proc-macro2", "quote", @@ -4282,18 +4290,18 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-interface" -version = "0.23.0" +version = "0.25.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92adbaf536f5aff6986e1e62ba36cee72b1718c5153eee08b9e728ddde3f6029" +checksum = "10081a99cbecbc363d381b9503563785f0b02735fccbb0d4c1a2cb3d39f7e7fe" dependencies = [ - "atty", - "bitflags 1.3.2", + "bitflags 2.3.3", "cap-fs-ext", "cap-std", - "io-lifetimes 0.7.5", - "rustix 0.35.13", - "windows-sys 0.36.1", - "winx", + "fd-lock", + "io-lifetimes 2.0.2", + "rustix 0.38.3", + "windows-sys 0.48.0", + "winx 0.36.1", ] [[package]] @@ -4315,9 +4323,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.7" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" +checksum = "1b1c7f239eb94671427157bd93b3694320f3668d4e1eff08c7285366fd777fac" [[package]] name = "tempfile" @@ -4329,7 +4337,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.19", + "rustix 0.37.23", "windows-sys 0.48.0", ] @@ -4371,7 +4379,7 @@ checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -4397,11 +4405,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", + "libc", + "num_threads", "serde", "time-core", "time-macros", @@ -4415,9 +4425,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -4476,7 +4486,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -4502,11 +4512,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.1", + "rustls 0.21.3", "tokio", ] @@ -4521,6 +4531,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-test" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3" +dependencies = [ + "async-stream", + "bytes 1.4.0", + "futures-core", + "tokio", + "tokio-stream", +] + [[package]] name = "tokio-tungstenite" version = "0.19.0" @@ -4575,7 +4598,7 @@ dependencies = [ "hyper", "hyper-timeout", "percent-encoding", - "pin-project 1.1.0", + "pin-project 1.1.2", "prost", "prost-derive", "rustls-pemfile", @@ -4608,7 +4631,7 @@ dependencies = [ "hyper", "hyper-timeout", "percent-encoding", - "pin-project 1.1.0", + "pin-project 1.1.2", "prost", "tokio", "tokio-stream", @@ -4640,7 +4663,7 @@ dependencies = [ "futures-core", "futures-util", "indexmap 1.9.3", - "pin-project 1.1.0", + "pin-project 1.1.2", "pin-project-lite", "rand", "slab", @@ -4700,13 +4723,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -4735,7 +4758,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.1.0", + "pin-project 1.1.2", "tracing", ] @@ -4799,6 +4822,26 @@ dependencies = [ "utf-8", ] +[[package]] +name = "turmoil" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e72ab712288bd737d0abc60712e031fb48488bbce7810ac2135da067e916469" +dependencies = [ + "bytes 1.4.0", + "futures", + "indexmap 1.9.3", + "rand", + "rand_distr", + "scoped-tls", + "tokio", + "tokio-stream", + "tokio-test", + "tokio-util", + "tracing", + "tracing-subscriber", +] + [[package]] name = "typenum" version = "1.16.0" @@ -4837,9 +4880,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" @@ -4856,6 +4899,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "untrusted" version = "0.7.1" @@ -4870,9 +4919,9 @@ checksum = "2fbfe96089af082b3c856f83bdd0b6866241377d9dbea803fb39481151e5742d" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", @@ -4922,13 +4971,13 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "8.2.1" +version = "8.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b3c89c2c7e50f33e4d35527e5bf9c11d6d132226dbbd1753f0fbe9f19ef88c6" +checksum = "bbc5ad0d9d26b2c49a5ab7da76c3e79d3ee37e7821799f8223fcb8f2f391a2e7" dependencies = [ "anyhow", "rustversion", - "time 0.3.21", + "time 0.3.23", ] [[package]] @@ -4970,11 +5019,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -4992,9 +5040,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi-cap-std-sync" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecbeebb8985a5423f36f976b2f4a0b3c6ce38d7d9a7247e1ce07aa2880e4f29b" +checksum = "5d29c5da3b5cfc9212a7fa824224875cb67fb89d2a8392db655e4c59b8ab2ae7" dependencies = [ "anyhow", "async-trait", @@ -5004,40 +5052,41 @@ dependencies = [ "cap-time-ext", "fs-set-times", "io-extras", - "io-lifetimes 0.7.5", - "is-terminal 0.3.0", + "io-lifetimes 1.0.11", + "is-terminal", "once_cell", - "rustix 0.35.13", + "rustix 0.37.23", "system-interface", "tracing", "wasi-common", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasi-common" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e2171f3783fe6600ee24ff6c58ca1b329c55e458cc1622ecc1fd0427648607" +checksum = "f8bd905dcec1448664bf63d42d291cbae0feeea3ad41631817b8819e096d76bd" dependencies = [ "anyhow", "bitflags 1.3.2", "cap-rand", "cap-std", "io-extras", - "rustix 0.35.13", + "log", + "rustix 0.37.23", "thiserror", "tracing", "wasmtime", "wiggle", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5045,24 +5094,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -5072,9 +5121,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5082,134 +5131,178 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c94f464d50e31da425794a02da1a82d4b96a657dcb152a6664e8aa915be517" +checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" dependencies = [ "leb128", ] [[package]] name = "wasmparser" -version = "0.93.0" +version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a4460aa3e271fa180b6a5d003e728f3963fb30e3ba0fa7c9634caa06049328" +checksum = "2c437373cac5ea84f1113d648d51f71751ffbe3d90c00ae67618cf20d0b5ee7b" dependencies = [ "indexmap 1.9.3", + "url", ] [[package]] name = "wasmtime" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18265705b1c49218776577d9f301d79ab06888c7f4a32e2ed24e68a55738ce7" +checksum = "634357e8668774b24c80b210552f3f194e2342a065d6d83845ba22c5817d0770" dependencies = [ "anyhow", "async-trait", "bincode", + "bumpalo", "cfg-if", + "fxprof-processed-profile", "indexmap 1.9.3", "libc", "log", - "object 0.29.0", + "object 0.30.4", "once_cell", "paste", "psm", "rayon", "serde", + "serde_json", "target-lexicon", "wasmparser", "wasmtime-cache", + "wasmtime-component-macro", "wasmtime-cranelift", "wasmtime-environ", "wasmtime-fiber", "wasmtime-jit", "wasmtime-runtime", "wat", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-asm-macros" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a201583f6c79b96e74dcce748fa44fb2958f474ef13c93f880ea4d3bed31ae4f" +checksum = "d33c73c24ce79b0483a3b091a9acf88871f4490b88998e8974b22236264d304c" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f37efc6945b08fcb634cffafc438dd299bac55a27c836954656c634d3e63c31" +checksum = "6107809b2d9f5b2fd3ddbaddb3bb92ff8048b62f4030debf1408119ffd38c6cb" dependencies = [ "anyhow", - "base64 0.13.1", + "base64 0.21.2", "bincode", "directories-next", "file-per-thread-logger", "log", - "rustix 0.35.13", + "rustix 0.37.23", "serde", "sha2", "toml", - "windows-sys 0.36.1", + "windows-sys 0.48.0", "zstd", ] +[[package]] +name = "wasmtime-component-macro" +version = "9.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ba489850d9c91c6c5b9e1696ee89e7a69d9796236a005f7e9131b6746e13b6" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasmtime-component-util", + "wasmtime-wit-bindgen", + "wit-parser", +] + +[[package]] +name = "wasmtime-component-util" +version = "9.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fa88f9e77d80f828c9d684741a9da649366c6d1cceb814755dd9cab7112d1d1" + [[package]] name = "wasmtime-cranelift" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe208297e045ea0ee6702be88772ea40f918d55fbd4163981a4699aff034b634" +checksum = "5800616a28ed6bd5e8b99ea45646c956d798ae030494ac0689bc3e45d3b689c1" dependencies = [ "anyhow", "cranelift-codegen", + "cranelift-control", "cranelift-entity", "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli 0.26.2", + "gimli", "log", - "object 0.29.0", + "object 0.30.4", "target-lexicon", "thiserror", "wasmparser", + "wasmtime-cranelift-shared", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-cranelift-shared" +version = "9.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27e4030b959ac5c5d6ee500078977e813f8768fa2b92fc12be01856cd0c76c55" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-native", + "gimli", + "object 0.30.4", + "target-lexicon", "wasmtime-environ", ] [[package]] name = "wasmtime-environ" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754b97f7441ac780a7fa738db5b9c23c1b70ef4abccd8ad205ada5669d196ba2" +checksum = "9ec815d01a8d38aceb7ed4678f9ba551ae6b8a568a63810ac3ad9293b0fd01c8" dependencies = [ "anyhow", "cranelift-entity", - "gimli 0.26.2", + "gimli", "indexmap 1.9.3", "log", - "object 0.29.0", + "object 0.30.4", "serde", "target-lexicon", "thiserror", @@ -5219,70 +5312,69 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f54abc960b4a055ba16b942cbbd1da641e0ad44cc97a7608f3d43c069b120e" +checksum = "23c5127908fdf720614891ec741c13dd70c844e102caa393e2faca1ee68e9bfb" dependencies = [ "cc", "cfg-if", - "rustix 0.35.13", + "rustix 0.37.23", "wasmtime-asm-macros", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-jit" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32800cb6e29faabab7056593f70a4c00c65c75c365aaf05406933f2169d0c22f" +checksum = "2712eafe829778b426cad0e1769fef944898923dd29f0039e34e0d53ba72b234" dependencies = [ - "addr2line 0.17.0", + "addr2line 0.19.0", "anyhow", "bincode", "cfg-if", "cpp_demangle", - "gimli 0.26.2", + "gimli", "ittapi", "log", - "object 0.29.0", + "object 0.30.4", "rustc-demangle", "serde", "target-lexicon", - "thiserror", "wasmtime-environ", "wasmtime-jit-debug", "wasmtime-jit-icache-coherence", "wasmtime-runtime", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-jit-debug" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe057012a0ba6cee3685af1e923d6e0a6cb9baf15fb3ffa4be3d7f712c7dec42" +checksum = "65fb78eacf4a6e47260d8ef8cc81ea8ddb91397b2e848b3fb01567adebfe89b5" dependencies = [ - "object 0.29.0", + "object 0.30.4", "once_cell", - "rustix 0.35.13", + "rustix 0.37.23", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "2.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6bbabb309c06cc238ee91b1455b748c45f0bdcab0dda2c2db85b0a1e69fcb66" +checksum = "d1364900b05f7d6008516121e8e62767ddb3e176bdf4c84dfa85da1734aeab79" dependencies = [ "cfg-if", "libc", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-runtime" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a23b6e138e89594c0189162e524a29e217aec8f9a4e1959a34f74c64e8d17d" +checksum = "4a16ffe4de9ac9669175c0ea5c6c51ffc596dfb49320aaa6f6c57eff58cef069" dependencies = [ "anyhow", "cc", @@ -5292,23 +5384,22 @@ dependencies = [ "log", "mach", "memfd", - "memoffset 0.6.5", + "memoffset 0.8.0", "paste", "rand", - "rustix 0.35.13", - "thiserror", + "rustix 0.37.23", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-fiber", "wasmtime-jit-debug", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-types" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ec7615fde8c79737f1345d81f0b18da83b3db929a87b4604f27c932246d1e2" +checksum = "19961c9a3b04d5e766875a5c467f6f5d693f508b3e81f8dc4a1444aa94f041c9" dependencies = [ "cranelift-entity", "serde", @@ -5318,17 +5409,29 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca539adf155dca1407aa3656e5661bf2364b1f3ebabc7f0a8bd62629d876acfa" +checksum = "21080ff62878f1d7c53d9571053dbe96552c0f982f9f29eac65ea89974fabfd7" dependencies = [ "anyhow", + "libc", "wasi-cap-std-sync", "wasi-common", "wasmtime", "wiggle", ] +[[package]] +name = "wasmtime-wit-bindgen" +version = "9.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421f0d16cc5c612b35ae53a0be3d3124c72296f18e5be3468263c745d56d37ab" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + [[package]] name = "wast" version = "35.0.2" @@ -5340,9 +5443,9 @@ dependencies = [ [[package]] name = "wast" -version = "59.0.0" +version = "60.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38462178c91e3f990df95f12bf48abe36018e03550a58a65c53975f4e704fc35" +checksum = "bd06cc744b536e30387e72a48fdd492105b9c938bb4f415c39c616a7a0a697ad" dependencies = [ "leb128", "memchr", @@ -5352,18 +5455,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936a025be0417a94d6e9bf92bfdf9e06dbf63debf187b650d9c73a5add701f1" +checksum = "5abe520f0ab205366e9ac7d3e6b2fc71de44e32a2b58f2ec871b6b575bdcea3b" dependencies = [ - "wast 59.0.0", + "wast 60.0.0", ] [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -5401,9 +5504,9 @@ dependencies = [ [[package]] name = "wiggle" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da09ca5b8bb9278a2123e8c36342166b9aaa55a0dbab18b231f46d6f6ab85bc" +checksum = "5b34e40b7b17a920d03449ca78b0319984379eed01a9a11c1def9c3d3832d85a" dependencies = [ "anyhow", "async-trait", @@ -5416,9 +5519,9 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5796f53b429df7d44cfdaae8f6d9cd981d82aec3516561352ca9c5e73ee185" +checksum = "9eefda132eaa84fe5f15d23a55a912f8417385aee65d0141d78a3b65e46201ed" dependencies = [ "anyhow", "heck", @@ -5431,9 +5534,9 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "3.0.1" +version = "9.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b830eb7203d48942fb8bc8bb105f76e7d09c33a082d638e990e02143bb2facd" +checksum = "6ca1a344a0ba781e2a94b27be5bb78f23e43d52336bd663b810d49d7189ad334" dependencies = [ "proc-macro2", "quote", @@ -5478,35 +5581,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.48.1", ] [[package]] @@ -5524,7 +5599,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -5544,9 +5619,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", @@ -5569,12 +5644,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -5587,12 +5656,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -5605,12 +5668,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -5623,12 +5680,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -5653,12 +5704,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -5682,13 +5727,38 @@ dependencies = [ [[package]] name = "winx" -version = "0.33.0" +version = "0.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b01e010390eb263a4518c8cebf86cb67469d1511c00b749a47b64c39e8054d" +checksum = "1c52a121f0fbf9320d5f2a9a5d82f6cb7557eda5e8b47fc3e7f359ec866ae960" dependencies = [ "bitflags 1.3.2", - "io-lifetimes 0.7.5", - "windows-sys 0.36.1", + "io-lifetimes 1.0.11", + "windows-sys 0.48.0", +] + +[[package]] +name = "winx" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4857cedf8371f690bb6782a3e2b065c54d1b6661be068aaf3eac8b45e813fdf8" +dependencies = [ + "bitflags 2.3.3", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-parser" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca2581061573ef6d1754983d7a9b3ed5871ef859d52708ea9a0f5af32919172" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 1.9.3", + "log", + "pulldown-cmark 0.8.0", + "unicode-xid", + "url", ] [[package]] diff --git a/docs/LINC.md b/docs/LINC.md new file mode 100644 index 00000000..9a915c65 --- /dev/null +++ b/docs/LINC.md @@ -0,0 +1,282 @@ +# Libsql Inter-Node Communication protocol: LINC protocol + +## Overview + +This document describes the version 1 of Libsql Inter-Node Communication (LINC) +protocol. + +The first version of the protocol aims to merge the existing two +protocol (proxy and replication) into a single one, and adds support for multi-tenancy. + +LINC v1 is designed to handle 3 tasks: +- inter-node communication +- database replication +- proxying of request from replicas to primaries + +LINC makes use of streams to multiplex messages between databases on different nodes. + +LINC v1 is implemented on top of TCP. + +LINC uses bincode for message serialization and deserialization. + +## Connection protocol + +Each node is identified by a `node_id`, and an address. +At startup, a sqld node is configured with list of peers (`(node_id, node_addr)`). A connection between two peers is initiated by the peer with the greatest node_id. + +```mermaid +graph TD +node4 --> node3 +node4 --> node2 +node4 --> node1 +node3 --> node2 +node3 --> node1 +node2 --> node1 +node1 +``` + +A new node node can be added to the cluster with no reconfiguration as long as its `node_id` is greater than all other `node_id` in the cluster and it has the address of all the other nodes. In this case, the new node will initiate a connection with all other nodes. + +On disconnection, the initiator of the connection attempts to reconnect. + +## Messages + +```rust +enum Message { + /// Messages destined to a node + Node(NodeMessage), + /// message destined to a stream + Stream { + stream_id: StreamId, + payload: StreamMessage, + }, +} + +enum NodeMessage { + /// Initial message exchanged between nodes when connecting + Handshake { + protocol_version: String, + node_id: String, + }, + /// Request to open a bi-directional stream between the client and the server + OpenStream { + /// Id to give to the newly opened stream + stream_id: StreamId, + /// Id of the database to open the stream to. + database_id: Uuid, + }, + /// Close a previously opened stream + CloseStream { + id: StreamId, + }, + /// Error type returned while handling a node message + Error(NodeError), +} + +enum NodeError { + UnknownStream(StreamId), + HandshakeVersionMismatch { expected: u32 }, + StreamAlreadyExist(StreamId), + UnknownDatabase(DatabaseId, StreamId), +} + +enum StreamMessage { + /// Replication message between a replica and a primary + Replication(ReplicationMessage), + /// Proxy message between a replica and a primary + Proxy(ProxyMessage), + Error(StreamError), +} + +enum ReplicationMessage { + HandshakeResponse { + /// id of the replication log + log_id: Uuid, + /// current frame_no of the primary + current_frame_no: u64, + }, + /// Replication request + Replicate { + /// next frame no to send + next_frame_no: u64, + }, + /// a batch of frames that are part of the same transaction + Transaction { + /// if not None, then the last frame is a commit frame, and this is the new size of the database. + size_after: Option, + /// frame_no of the last frame in frames + end_frame_no: u64 + /// a batch of frames part of the transaction. + frames: Vec + }, + /// Error occurred handling a replication message + Error(StreamError) +} + +struct Frame { + /// Page id of that frame + page_id: u32, + /// Data + data: Bytes, +} + +enum ProxyMessage { + /// Proxy a query to a primary + ProxyRequest { + /// id of the connection to perform the query against + /// If the connection doesn't already exist it is created + /// Id of the request. + /// Responses to this request must have the same id. + connection_id: u32, + req_id: u32, + query: Query, + }, + /// Response to a proxied query + ProxyResponse { + /// id of the request this message is a response to. + req_id: u32, + /// Collection of steps to drive the query builder transducer. + row_step: [RowStep] + }, + /// Stop processing request `id`. + CancelRequest { + req_id: u32, + }, + /// Close Connection with passed id. + CloseConnection { + connection_id: u32, + }, +} + +/// Steps applied to the query builder transducer to build a response to a proxied query. +/// Those types closely mirror those of the `QueryBuilderTrait`. +enum BuilderStep { + BeginStep, + FinishStep(u64, Option), + StepError(StepError), + ColsDesc([Column]), + BeginRows, + BeginRow, + AddRowValue(Value), + FinishRow, + FinishRos, + Finish(ConnectionState) +} + +// State of the connection after a query was executed +enum ConnectionState { + /// The connection is still in a open transaction state + OpenTxn, + /// The connection is idle. + Idle, +} + +struct Column { + /// name of the column + name: string, + /// Declared type of the column, if any. + decl_ty: Option, +} + +/// for now, the stringified version of a sqld::error::Error. +struct StepError(String); + +enum StreamError { + NotAPrimary, + AlreadyReplicating, +} +``` + +## Node Handshake + +When a node connects to another node, it first need to perform a handshake. The +handshake is initialized by the initializer of the connection. It sends the +following message: + +```typescipt +type NodeHandshake = { + version: string, // protocol version + node_id: string, +} +``` + +If a peer receives a connection from a peer with a id smaller than his, it must reject the handshake with a `IllegalConnection` error + +## Streams + +Messages destined to a particular database are sent as part of a stream. A +stream is created by sending a `NodeMessage::OpenStream`, specifying the id of +the stream to open, along with the id of the database for which to open this +stream. If the requested database is not on the destination node, the +destination node respond with a `NodeError::UnknownDatabase` error, and the stream in not +opened. + +If a node receives a message for a stream that was not opened before, it responds a `NodeError::UnknownStream` + +A stream is closed by sending a `CloseStream` with the id of the stream. If the +stream does not exist an `NodeError::UnknownStream` error is returned. + +Streams can be opened by either peer. Each stream is identified with by `i32` +stream id. The peer that initiated the original connection allocates positive +stream ids, while the acceptor peer allocates negative ids. 0 is not a legal +value for a stream_id. The receiver of a request for a stream with id 0 must +close the connection immediately. + +The peer opening a stream is responsible for sending the close message. The +other peer can close the stream at any point, but must not send close message +for that stream. On subsequent message to that stream, it will respond with an +`UnknownStream` message, forcing the initiator to deal with recreating a +stream if necessary. + +## Sub-protocols + +### Replication + +The replica is responsible for initiating the replication protocol. This is +done by opening a stream to a primary. If the destination of the stream is not a +primary database, it responds with a `StreamError::NotAPrimary` error and immediately close +the stream. If the destination database is a primary, it responds to the stream +open request with a `ReplicationMessage::HandshakeResponse` message. This message informs the +replica of the current log version, and of the primary current replication +index (frame_no). + +The replica compares the log version it received from the primary with the one it has, if any. If the +versions don't match, the replica deletes its state and start replicating again from the start. + +After a successful handshake, the replica sends a `ReplicationMessage::Replicate` message with the +next frame_no it's expecting. For example if the replica has not replicated any +frame yet, it sends `ReplicationMessage::Replicate { next_frame_no: 0 }` to +signify to the primary that it's expecting to be sent frame 0. The primary +sends the smallest frame with a `frame_no` satisfying `frame_no >= +next_frame_no`. Because logs can be compacted, the next frame_no the primary +sends to the replica isn't necessarily the one the replica is expecting. It's correct to send +the smallest frame >= next_frame_no because frame_nos only move forward in the event of a compaction: a +frame can only be missing if it was written too more recently, hence _moving +forward_ in the log. The primary ensure consistency by moving commit points +accordingly. It is an error for the primary to send a frame_no strictly less +than the requested frame_no, frame_nos can be received in any order. + +In the event of a disconnection, it is the replica's duty to re-initiate the replication protocol. + +Sending a replicate request twice on the same stream is an error. If a primary +receives more than a single `Replicate` request, it closes the stream and sends +a `StreamError::AlreadyReplicating` request. The replica can re-open a stream and start +replicating again if necessary. + +### Proxy + +Replicas can proxy queries to their primary. Replica can start sending proxy request after they have sent a replication request. + +To proxy a query, a replica sends a `ProxyRequest`. Proxied query on a same connection are serialized. The replica sets the connection id +and the request id for the proxied query. If no connection exists for the +passed id on the primary, one is created. The query is executed on the primary, +and the result rows are returned in `ProxyResponse`. The result rows can be split +into multiple `ProxyResponse`, enabling row streaming. A replica can send a `CancelRequest` to interrupt a request. Any +`ProxyResponse` for that `request_id` can be dropped by the replica, and the +primary should stop sending any more `ProxyResponse` message upon receiving the +cancel request. The primary must rollback a cancelled request. + +The primary can reduce the amount of concurrent open transaction by closing the +underlying SQLite connection for proxied connections that are not in a open +transaction state (`is_autocommit` is true). Subsequent requests on that +connection id will re-open a connection, if necessary. diff --git a/libsqlx-server/Cargo.toml b/libsqlx-server/Cargo.toml index 5e6d5c15..b4f9d366 100644 --- a/libsqlx-server/Cargo.toml +++ b/libsqlx-server/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-bincode = { version = "0.7.1", features = ["tokio"] } axum = "0.6.18" base64 = "0.21.2" bincode = "1.3.3" @@ -15,6 +16,7 @@ color-eyre = "0.6.2" futures = "0.3.28" hmac = "0.12.1" hyper = { version = "0.14.27", features = ["h2", "server"] } +itertools = "0.11.0" libsqlx = { version = "0.1.0", path = "../libsqlx" } moka = { version = "0.11.2", features = ["future"] } parking_lot = "0.12.1" @@ -27,6 +29,11 @@ sha2 = "0.10.7" sled = "0.34.7" thiserror = "1.0.43" tokio = { version = "1.29.1", features = ["full"] } +tokio-stream = "0.1.14" +tokio-util = "0.7.8" tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } uuid = { version = "1.4.0", features = ["v4"] } + +[dev-dependencies] +turmoil = "0.5.5" diff --git a/libsqlx-server/src/database.rs b/libsqlx-server/src/database.rs index d0c979cc..e4971b74 100644 --- a/libsqlx-server/src/database.rs +++ b/libsqlx-server/src/database.rs @@ -1,7 +1,7 @@ use tokio::sync::{mpsc, oneshot}; use crate::hrana::http::proto::{PipelineRequestBody, PipelineResponseBody}; -use crate::allocation::{AllocationMessage, ConnectionHandle}; +use crate::allocation::AllocationMessage; pub struct Database { pub sender: mpsc::Sender, @@ -9,11 +9,8 @@ pub struct Database { impl Database { pub async fn hrana_pipeline(&self, req: PipelineRequestBody) -> crate::Result { - dbg!(); let (sender, ret) = oneshot::channel(); - dbg!(); self.sender.send(AllocationMessage::HranaPipelineReq { req, ret: sender }).await.unwrap(); - dbg!(); ret.await.unwrap() } } diff --git a/libsqlx-server/src/linc/bus.rs b/libsqlx-server/src/linc/bus.rs new file mode 100644 index 00000000..6fcc3238 --- /dev/null +++ b/libsqlx-server/src/linc/bus.rs @@ -0,0 +1,186 @@ +use std::collections::{hash_map::Entry, HashMap}; +use std::sync::Arc; + +use color_eyre::eyre::{bail, anyhow}; +use parking_lot::Mutex; +use tokio::sync::{mpsc, Notify}; +use uuid::Uuid; + +use super::connection::{ConnectionHandle, Stream}; + +type NodeId = Uuid; +type DatabaseId = Uuid; + +#[must_use] +pub struct Subscription { + receiver: mpsc::Receiver, + bus: Bus, + database_id: DatabaseId, +} + +impl Drop for Subscription { + fn drop(&mut self) { + self.bus + .inner + .lock() + .subscriptions + .remove(&self.database_id); + } +} + +impl futures::Stream for Subscription { + type Item = Stream; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.receiver.poll_recv(cx) + } +} + +#[derive(Clone)] +pub struct Bus { + inner: Arc>, + pub node_id: NodeId, +} + +enum ConnectionSlot { + Handle(ConnectionHandle), + // Interest in the connection when it becomes available + Interest(Arc), +} + +struct BusInner { + connections: HashMap, + subscriptions: HashMap>, +} + +impl Bus { + pub fn new(node_id: NodeId) -> Self { + Self { + node_id, + inner: Arc::new(Mutex::new(BusInner { + connections: HashMap::new(), + subscriptions: HashMap::new(), + })), + } + } + + /// open a new stream to the database at `database_id` on the node `node_id` + pub async fn new_stream( + &self, + node_id: NodeId, + database_id: DatabaseId, + ) -> color_eyre::Result { + let get_conn = || { + let mut lock = self.inner.lock(); + match lock.connections.entry(node_id) { + Entry::Occupied(mut e) => match e.get_mut() { + ConnectionSlot::Handle(h) => Ok(h.clone()), + ConnectionSlot::Interest(notify) => Err(notify.clone()), + }, + Entry::Vacant(e) => { + let notify = Arc::new(Notify::new()); + e.insert(ConnectionSlot::Interest(notify.clone())); + Err(notify) + } + } + }; + + let conn = match get_conn() { + Ok(conn) => conn, + Err(notify) => { + notify.notified().await; + get_conn().map_err(|_| anyhow!("failed to create stream"))? + } + }; + + conn.new_stream(database_id).await + } + + /// Notify a subscription that new stream was openned + pub async fn notify_subscription( + &mut self, + database_id: DatabaseId, + stream: Stream, + ) -> color_eyre::Result<()> { + let maybe_sender = self.inner.lock().subscriptions.get(&database_id).cloned(); + + match maybe_sender { + Some(sender) => { + if sender.send(stream).await.is_err() { + bail!("subscription for {database_id} closed"); + } + + Ok(()) + } + None => { + bail!("no subscription for {database_id}") + } + } + } + + #[cfg(test)] + pub fn is_empty(&self) -> bool { + self.inner.lock().connections.is_empty() + } + + #[must_use] + pub fn register_connection(&self, node_id: NodeId, conn: ConnectionHandle) -> Registration { + let mut lock = self.inner.lock(); + match lock.connections.entry(node_id) { + Entry::Occupied(mut e) => { + if let ConnectionSlot::Interest(ref notify) = e.get() { + notify.notify_waiters(); + } + + *e.get_mut() = ConnectionSlot::Handle(conn); + } + Entry::Vacant(e) => { + e.insert(ConnectionSlot::Handle(conn)); + } + } + + Registration { + bus: self.clone(), + node_id, + } + } + + pub fn subscribe(&self, database_id: DatabaseId) -> color_eyre::Result { + let (sender, receiver) = mpsc::channel(1); + { + let mut inner = self.inner.lock(); + + if inner.subscriptions.contains_key(&database_id) { + bail!("a subscription already exist for that database"); + } + + inner.subscriptions.insert(database_id, sender); + } + + Ok(Subscription { + receiver, + bus: self.clone(), + database_id, + }) + } +} + +pub struct Registration { + bus: Bus, + node_id: NodeId, +} + +impl Drop for Registration { + fn drop(&mut self) { + assert!(self + .bus + .inner + .lock() + .connections + .remove(&self.node_id) + .is_some()); + } +} diff --git a/libsqlx-server/src/linc/connection.rs b/libsqlx-server/src/linc/connection.rs new file mode 100644 index 00000000..b5a8ce25 --- /dev/null +++ b/libsqlx-server/src/linc/connection.rs @@ -0,0 +1,723 @@ +use std::collections::HashMap; + +use async_bincode::tokio::AsyncBincodeStream; +use async_bincode::AsyncDestination; +use color_eyre::eyre::{bail, anyhow}; +use futures::{SinkExt, StreamExt}; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::sync::mpsc::error::TrySendError; +use tokio::sync::{mpsc, oneshot}; +use tokio::time::{Duration, Instant}; +use tokio_util::sync::PollSender; + +use crate::linc::proto::{NodeError, NodeMessage}; +use crate::linc::CURRENT_PROTO_VERSION; + +use super::bus::{Bus, Registration}; +use super::proto::{Message, StreamId, StreamMessage}; +use super::{DatabaseId, NodeId}; +use super::{StreamIdAllocator, MAX_STREAM_MSG}; + +#[derive(Debug, Clone)] +pub struct ConnectionHandle { + connection_sender: mpsc::Sender, +} + +impl ConnectionHandle { + pub async fn new_stream(&self, database_id: DatabaseId) -> color_eyre::eyre::Result { + let (send, ret) = oneshot::channel(); + self.connection_sender + .send(ConnectionMessage::StreamCreate { + database_id, + ret: send, + }) + .await + .unwrap(); + + Ok(ret.await?) + } +} + +/// A Bidirectional stream between databases on two nodes. +#[derive(Debug)] +pub struct Stream { + stream_id: StreamId, + /// sender to the connection + sender: tokio_util::sync::PollSender, + /// incoming message for this stream + recv: tokio_stream::wrappers::ReceiverStream, +} + +impl futures::Sink for Stream { + type Error = tokio_util::sync::PollSendError; + + fn poll_ready( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.sender.poll_ready_unpin(cx) + } + + fn start_send( + mut self: std::pin::Pin<&mut Self>, + payload: StreamMessage, + ) -> Result<(), Self::Error> { + let stream_id = self.stream_id; + self.sender + .start_send_unpin(ConnectionMessage::Message(Message::Stream { + stream_id, + payload, + })) + } + + fn poll_flush( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.sender.poll_flush_unpin(cx) + } + + fn poll_close( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.sender.poll_close_unpin(cx) + } +} + +impl futures::Stream for Stream { + type Item = StreamMessage; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.recv.poll_next_unpin(cx) + } +} + +impl Drop for Stream { + fn drop(&mut self) { + self.recv.close(); + assert!(self.recv.as_mut().try_recv().is_err()); + let mut sender = self.sender.clone(); + let id = self.stream_id; + if let Some(sender_ref) = sender.get_ref() { + // Try send here is mostly for turmoil, since it stops polling the future as soon as + // the test future returns which causes spawn to panic. In the tests, the channel will + // always have capacity. + if let Err(TrySendError::Full(m)) = + sender_ref.try_send(ConnectionMessage::CloseStream(id)) + { + tokio::task::spawn(async move { + let _ = sender.send(m).await; + }); + } + } + } +} + +struct StreamState { + sender: mpsc::Sender, +} + +/// A connection to another node. Manage the connection state, and (de)register streams with the +/// `Bus` +pub struct Connection { + /// Id of the current node + pub peer: Option, + /// State of the connection + pub state: ConnectionState, + /// Sink/Stream for network messages + conn: AsyncBincodeStream, + /// Collection of streams for that connection + streams: HashMap, + /// internal connection messages + connection_messages: mpsc::Receiver, + connection_messages_sender: mpsc::Sender, + /// Are we the initiator of this connection? + is_initiator: bool, + bus: Bus, + stream_id_allocator: StreamIdAllocator, + /// handle to the registration of this connection to the bus. + /// Dropping this deregister this connection from the bus + registration: Option, +} + +#[derive(Debug)] +pub enum ConnectionMessage { + StreamCreate { + database_id: DatabaseId, + ret: oneshot::Sender, + }, + CloseStream(StreamId), + Message(Message), +} + +#[derive(Debug)] +pub enum ConnectionState { + Init, + Connecting, + Connected, + // Closing the connection with an error + CloseError(color_eyre::eyre::Error), + // Graceful connection shutdown + Close, +} + +pub fn handshake_deadline() -> Instant { + const HANDSHAKE_TIMEOUT: Duration = Duration::from_secs(5); + Instant::now() + HANDSHAKE_TIMEOUT +} + +impl Connection +where + S: AsyncRead + AsyncWrite + Unpin, +{ + const MAX_CONNECTION_MESSAGES: usize = 128; + + pub fn new_initiator(stream: S, bus: Bus) -> Self { + let (connection_messages_sender, connection_messages) = + mpsc::channel(Self::MAX_CONNECTION_MESSAGES); + Self { + peer: None, + state: ConnectionState::Init, + conn: AsyncBincodeStream::from(stream).for_async(), + streams: HashMap::new(), + is_initiator: true, + bus, + stream_id_allocator: StreamIdAllocator::new(true), + connection_messages, + connection_messages_sender, + registration: None, + } + } + + pub fn new_acceptor(stream: S, bus: Bus) -> Self { + let (connection_messages_sender, connection_messages) = + mpsc::channel(Self::MAX_CONNECTION_MESSAGES); + Connection { + peer: None, + state: ConnectionState::Connecting, + streams: HashMap::new(), + connection_messages, + connection_messages_sender, + is_initiator: false, + bus, + conn: AsyncBincodeStream::from(stream).for_async(), + stream_id_allocator: StreamIdAllocator::new(false), + registration: None, + } + } + + pub fn handle(&self) -> ConnectionHandle { + ConnectionHandle { + connection_sender: self.connection_messages_sender.clone(), + } + } + + pub async fn run(mut self) { + while self.tick().await {} + } + + pub async fn tick(&mut self) -> bool { + match self.state { + ConnectionState::Connected => self.tick_connected().await, + ConnectionState::Init => match self.initiate_connection().await { + Ok(_) => { + self.state = ConnectionState::Connecting; + } + Err(e) => { + self.state = ConnectionState::CloseError(e); + } + }, + ConnectionState::Connecting => { + if let Err(e) = self + .wait_handshake_response_with_deadline(handshake_deadline()) + .await + { + self.state = ConnectionState::CloseError(e); + } + } + ConnectionState::CloseError(ref e) => { + tracing::error!("closing connection with {:?}: {e}", self.peer); + return false; + } + ConnectionState::Close => return false, + } + true + } + + async fn tick_connected(&mut self) { + tokio::select! { + m = self.conn.next() => { + match m { + Some(Ok(m)) => { + self.handle_message(m).await; + } + Some(Err(e)) => { + self.state = ConnectionState::CloseError(e.into()); + } + None => { + self.state = ConnectionState::Close; + } + } + } + Some(command) = self.connection_messages.recv() => { + self.handle_command(command).await; + }, + else => { + self.state = ConnectionState::Close; + } + } + } + + async fn handle_message(&mut self, message: Message) { + match message { + Message::Node(NodeMessage::OpenStream { + stream_id, + database_id, + }) => { + if self.streams.contains_key(&stream_id) { + self.send_message(Message::Node(NodeMessage::Error( + NodeError::StreamAlreadyExist(stream_id), + ))) + .await; + return; + } + let stream = self.create_stream(stream_id); + if let Err(e) = self.bus.notify_subscription(database_id, stream).await { + tracing::error!("{e}"); + self.send_message(Message::Node(NodeMessage::Error( + NodeError::UnknownDatabase(database_id, stream_id), + ))) + .await; + } + } + Message::Node(NodeMessage::Handshake { .. }) => { + self.close_error(anyhow!("unexpected handshake: closing connection")); + } + Message::Node(NodeMessage::CloseStream { stream_id: id }) => { + self.close_stream(id); + } + Message::Node(NodeMessage::Error(e @ NodeError::HandshakeVersionMismatch { .. })) => { + self.close_error(anyhow!("unexpected peer error: {e}")); + } + Message::Node(NodeMessage::Error(NodeError::UnknownStream(id))) => { + tracing::error!("unkown stream: {id}"); + self.close_stream(id); + } + Message::Node(NodeMessage::Error(e @ NodeError::StreamAlreadyExist(_))) => { + self.state = ConnectionState::CloseError(e.into()); + } + Message::Node(NodeMessage::Error(ref e @ NodeError::UnknownDatabase(_, stream_id))) => { + tracing::error!("{e}"); + self.close_stream(stream_id); + } + Message::Stream { stream_id, payload } => { + match self.streams.get_mut(&stream_id) { + Some(s) => { + // TODO: there is not stream-independant control-flow for now. + // When/if control-flow is implemented, it will be handled here. + if s.sender.send(payload).await.is_err() { + self.close_stream(stream_id); + } + } + None => { + self.send_message(Message::Node(NodeMessage::Error( + NodeError::UnknownStream(stream_id), + ))) + .await; + } + } + } + } + } + + fn close_error(&mut self, error: color_eyre::eyre::Error) { + self.state = ConnectionState::CloseError(error); + } + + fn close_stream(&mut self, id: StreamId) { + self.streams.remove(&id); + } + + async fn handle_command(&mut self, command: ConnectionMessage) { + match command { + ConnectionMessage::Message(m) => { + self.send_message(m).await; + } + ConnectionMessage::CloseStream(stream_id) => { + self.close_stream(stream_id); + self.send_message(Message::Node(NodeMessage::CloseStream { stream_id })) + .await; + } + ConnectionMessage::StreamCreate { database_id, ret } => { + let Some(stream_id) = self.stream_id_allocator.allocate() else { + // TODO: We close the connection here, which will cause a reconnections, and + // reset the stream_id allocator. If that happens in practice, it should be very quick to + // re-establish a connection. If this is an issue, we can either start using + // i64 stream_ids, or use a smarter id allocator. + self.state = ConnectionState::CloseError(anyhow!("Ran out of stream ids")); + return + }; + assert_eq!(stream_id.is_positive(), self.is_initiator); + assert!(!self.streams.contains_key(&stream_id)); + let stream = self.create_stream(stream_id); + self.send_message(Message::Node(NodeMessage::OpenStream { + stream_id, + database_id, + })) + .await; + let _ = ret.send(stream); + } + } + } + + async fn send_message(&mut self, message: Message) { + if let Err(e) = self.conn.send(message).await { + self.close_error(e.into()); + } + } + + fn create_stream(&mut self, stream_id: StreamId) -> Stream { + let (sender, recv) = mpsc::channel(MAX_STREAM_MSG); + let stream = Stream { + stream_id, + sender: PollSender::new(self.connection_messages_sender.clone()), + recv: recv.into(), + }; + self.streams.insert(stream_id, StreamState { sender }); + stream + } + + /// wait for a handshake response from peer + pub async fn wait_handshake_response_with_deadline( + &mut self, + deadline: Instant, + ) -> color_eyre::Result<()> { + assert!(matches!(self.state, ConnectionState::Connecting)); + + match tokio::time::timeout_at(deadline, self.conn.next()).await { + Ok(Some(Ok(Message::Node(NodeMessage::Handshake { + protocol_version, + node_id, + })))) => { + if protocol_version != CURRENT_PROTO_VERSION { + let _ = self + .conn + .send(Message::Node(NodeMessage::Error( + NodeError::HandshakeVersionMismatch { + expected: CURRENT_PROTO_VERSION, + }, + ))) + .await; + + bail!("handshake error: invalid peer protocol version"); + } else { + // when not initiating a connection, respond to handshake message with a + // handshake message + if !self.is_initiator { + self.conn + .send(Message::Node(NodeMessage::Handshake { + protocol_version: CURRENT_PROTO_VERSION, + node_id: self.bus.node_id, + })) + .await?; + } + + self.peer = Some(node_id); + self.state = ConnectionState::Connected; + self.registration = Some(self.bus.register_connection(node_id, self.handle())); + + Ok(()) + } + } + Ok(Some(Ok(Message::Node(NodeMessage::Error(e))))) => { + bail!("handshake error: {e}"); + } + Ok(Some(Ok(_))) => { + bail!("unexpected message from peer during handshake."); + } + Ok(Some(Err(e))) => { + bail!("failed to perform handshake with peer: {e}"); + } + Ok(None) => { + bail!("failed to perform handshake with peer: connection closed"); + } + Err(_e) => { + bail!("failed to perform handshake with peer: timed out"); + } + } + } + + async fn initiate_connection(&mut self) -> color_eyre::Result<()> { + self.conn + .send(Message::Node(NodeMessage::Handshake { + protocol_version: CURRENT_PROTO_VERSION, + node_id: self.bus.node_id, + })) + .await?; + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use std::sync::Arc; + + use tokio::sync::Notify; + use turmoil::net::{TcpListener, TcpStream}; + use uuid::Uuid; + + use super::*; + + #[test] + fn invalid_handshake() { + let mut sim = turmoil::Builder::new().build(); + + let host_node_id = NodeId::new_v4(); + sim.host("host", move || async move { + let bus = Bus::new(host_node_id); + let listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + let (s, _) = listener.accept().await.unwrap(); + let mut connection = Connection::new_acceptor(s, bus); + connection.tick().await; + + Ok(()) + }); + + sim.client("client", async move { + let s = TcpStream::connect("host:1234").await.unwrap(); + let mut s = AsyncBincodeStream::<_, Message, Message, _>::from(s).for_async(); + + s.send(Message::Node(NodeMessage::Handshake { + protocol_version: 1234, + node_id: Uuid::new_v4(), + })) + .await + .unwrap(); + let m = s.next().await.unwrap().unwrap(); + + assert!(matches!( + m, + Message::Node(NodeMessage::Error( + NodeError::HandshakeVersionMismatch { .. } + )) + )); + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn stream_closed() { + let mut sim = turmoil::Builder::new().build(); + + let database_id = DatabaseId::new_v4(); + let host_node_id = NodeId::new_v4(); + let notify = Arc::new(Notify::new()); + sim.host("host", { + let notify = notify.clone(); + move || { + let notify = notify.clone(); + async move { + let bus = Bus::new(host_node_id); + let mut sub = bus.subscribe(database_id).unwrap(); + let listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + let (s, _) = listener.accept().await.unwrap(); + let connection = Connection::new_acceptor(s, bus); + tokio::task::spawn_local(connection.run()); + let mut streams = Vec::new(); + loop { + tokio::select! { + Some(mut stream) = sub.next() => { + let m = stream.next().await.unwrap(); + stream.send(m).await.unwrap(); + streams.push(stream); + } + _ = notify.notified() => { + break; + } + } + } + + Ok(()) + } + } + }); + + sim.client("client", async move { + let stream_id = StreamId::new(1); + let node_id = NodeId::new_v4(); + let s = TcpStream::connect("host:1234").await.unwrap(); + let mut s = AsyncBincodeStream::<_, Message, Message, _>::from(s).for_async(); + + s.send(Message::Node(NodeMessage::Handshake { + protocol_version: CURRENT_PROTO_VERSION, + node_id, + })) + .await + .unwrap(); + let m = s.next().await.unwrap().unwrap(); + assert!(matches!(m, Message::Node(NodeMessage::Handshake { .. }))); + + // send message to unexisting stream: + s.send(Message::Stream { + stream_id, + payload: StreamMessage::Dummy, + }) + .await + .unwrap(); + let m = s.next().await.unwrap().unwrap(); + assert_eq!( + m, + Message::Node(NodeMessage::Error(NodeError::UnknownStream(stream_id))) + ); + + // open stream then send message + s.send(Message::Node(NodeMessage::OpenStream { + stream_id, + database_id, + })) + .await + .unwrap(); + s.send(Message::Stream { + stream_id, + payload: StreamMessage::Dummy, + }) + .await + .unwrap(); + let m = s.next().await.unwrap().unwrap(); + assert_eq!( + m, + Message::Stream { + stream_id, + payload: StreamMessage::Dummy + } + ); + + s.send(Message::Node(NodeMessage::CloseStream { + stream_id: StreamId::new(1), + })) + .await + .unwrap(); + s.send(Message::Stream { + stream_id, + payload: StreamMessage::Dummy, + }) + .await + .unwrap(); + let m = s.next().await.unwrap().unwrap(); + assert_eq!( + m, + Message::Node(NodeMessage::Error(NodeError::UnknownStream(stream_id))) + ); + + notify.notify_waiters(); + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn connection_closed_by_peer_close_connection() { + let mut sim = turmoil::Builder::new().build(); + + let notify = Arc::new(Notify::new()); + sim.host("host", { + let notify = notify.clone(); + move || { + let notify = notify.clone(); + async move { + let listener = TcpListener::bind("0.0.0.0:1234").await.unwrap(); + let (stream, _) = listener.accept().await.unwrap(); + notify.notified().await; + + // drop connection + drop(stream); + + Ok(()) + } + } + }); + + sim.client("client", async move { + let stream = TcpStream::connect("host:1234").await.unwrap(); + let bus = Bus::new(NodeId::new_v4()); + let mut conn = Connection::new_acceptor(stream, bus); + + notify.notify_waiters(); + + conn.tick().await; + + assert!(matches!(conn.state, ConnectionState::CloseError(_))); + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn zero_stream_id() { + let mut sim = turmoil::Builder::new().build(); + + let notify = Arc::new(Notify::new()); + sim.host("host", { + let notify = notify.clone(); + move || { + let notify = notify.clone(); + async move { + let listener = TcpListener::bind("0.0.0.0:1234").await.unwrap(); + let (stream, _) = listener.accept().await.unwrap(); + let (connection_messages_sender, connection_messages) = mpsc::channel(1); + let conn = Connection { + peer: Some(NodeId::new_v4()), + state: ConnectionState::Connected, + conn: AsyncBincodeStream::from(stream).for_async(), + streams: HashMap::new(), + connection_messages, + connection_messages_sender, + is_initiator: false, + bus: Bus::new(NodeId::new_v4()), + stream_id_allocator: StreamIdAllocator::new(false), + registration: None, + }; + + conn.run().await; + + Ok(()) + } + } + }); + + sim.client("client", async move { + let stream = TcpStream::connect("host:1234").await.unwrap(); + let mut stream = AsyncBincodeStream::<_, Message, Message, _>::from(stream).for_async(); + + stream + .send(Message::Stream { + stream_id: StreamId::new_unchecked(0), + payload: StreamMessage::Dummy, + }) + .await + .unwrap(); + + assert!(stream.next().await.is_none()); + + Ok(()) + }); + + sim.run().unwrap(); + } +} diff --git a/libsqlx-server/src/linc/connection_manager.rs b/libsqlx-server/src/linc/connection_manager.rs new file mode 100644 index 00000000..e69de29b diff --git a/libsqlx-server/src/linc/connection_pool.rs b/libsqlx-server/src/linc/connection_pool.rs new file mode 100644 index 00000000..f5f29c61 --- /dev/null +++ b/libsqlx-server/src/linc/connection_pool.rs @@ -0,0 +1,202 @@ +use std::collections::HashMap; + +use itertools::Itertools; +use tokio::task::JoinSet; +use tokio::time::Duration; + +use super::connection::Connection; +use super::net::Connector; +use super::{bus::Bus, NodeId}; + +/// Manages a pool of connections to other peers, handling re-connection. +struct ConnectionPool { + managed_peers: HashMap, + connections: JoinSet, + bus: Bus, +} + +impl ConnectionPool { + pub fn new(bus: Bus, managed_peers: impl IntoIterator) -> Self { + Self { + managed_peers: managed_peers.into_iter().collect(), + connections: JoinSet::new(), + bus, + } + } + + pub async fn run(mut self) { + self.init::().await; + + while self.tick::().await {} + } + + pub async fn tick(&mut self) -> bool { + if let Some(maybe_to_restart) = self.connections.join_next().await { + if let Ok(to_restart) = maybe_to_restart { + self.connect::(to_restart); + } + true + } else { + false + } + } + + async fn init(&mut self) { + let peers = self.managed_peers.keys().copied().collect_vec(); + peers.into_iter().for_each(|p| self.connect::(p)); + } + + fn connect(&mut self, peer_id: NodeId) { + let bus = self.bus.clone(); + let peer_addr = self.managed_peers[&peer_id].clone(); + let fut = async move { + let stream = match C::connect(peer_addr.clone()).await { + Ok(stream) => stream, + Err(e) => { + tracing::error!("error connection to peer {peer_id}@{peer_addr}: {e}"); + tokio::time::sleep(Duration::from_secs(1)).await; + return peer_id; + } + }; + let connection = Connection::new_initiator(stream, bus.clone()); + connection.run().await; + + peer_id + }; + + self.connections.spawn(fut); + } +} + +#[cfg(test)] +mod test { + use std::sync::Arc; + + use futures::SinkExt; + use tokio::sync::Notify; + use tokio_stream::StreamExt; + + use crate::linc::{server::Server, DatabaseId}; + + use super::*; + + #[test] + fn manage_connections() { + let mut sim = turmoil::Builder::new().build(); + let database_id = DatabaseId::new_v4(); + let notify = Arc::new(Notify::new()); + + let expected_msg = crate::linc::proto::StreamMessage::Proxy( + crate::linc::proto::ProxyMessage::ProxyRequest { + connection_id: 42, + req_id: 42, + program: "foobar".into(), + }, + ); + + let spawn_host = |node_id| { + let notify = notify.clone(); + let expected_msg = expected_msg.clone(); + move || { + let notify = notify.clone(); + let expected_msg = expected_msg.clone(); + async move { + let bus = Bus::new(node_id); + let mut sub = bus.subscribe(database_id).unwrap(); + let mut server = Server::new(bus.clone()); + let mut listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + + let mut has_closed = false; + let mut streams = Vec::new(); + loop { + tokio::select! { + _ = notify.notified() => { + if !has_closed { + streams.clear(); + server.close_connections().await; + has_closed = true; + } else { + break; + } + }, + _ = server.tick(&mut listener) => (), + Some(mut stream) = sub.next() => { + stream + .send(expected_msg.clone()) + .await + .unwrap(); + streams.push(stream); + } + } + } + + Ok(()) + } + } + }; + + let host1_id = NodeId::new_v4(); + sim.host("host1", spawn_host(host1_id)); + + let host2_id = NodeId::new_v4(); + sim.host("host2", spawn_host(host2_id)); + + let host3_id = NodeId::new_v4(); + sim.host("host3", spawn_host(host3_id)); + + sim.client("client", async move { + let bus = Bus::new(NodeId::new_v4()); + let pool = ConnectionPool::new( + bus.clone(), + vec![ + (host1_id, "host1:1234".into()), + (host2_id, "host2:1234".into()), + (host3_id, "host3:1234".into()), + ], + ); + + tokio::task::spawn_local(pool.run::()); + + // all three hosts are reachable: + let mut stream1 = bus.new_stream(host1_id, database_id).await.unwrap(); + let m = stream1.next().await.unwrap(); + assert_eq!(m, expected_msg); + + let mut stream2 = bus.new_stream(host2_id, database_id).await.unwrap(); + let m = stream2.next().await.unwrap(); + assert_eq!(m, expected_msg); + + let mut stream3 = bus.new_stream(host3_id, database_id).await.unwrap(); + let m = stream3.next().await.unwrap(); + assert_eq!(m, expected_msg); + + // sever connections + notify.notify_waiters(); + + assert!(stream1.next().await.is_none()); + assert!(stream2.next().await.is_none()); + assert!(stream3.next().await.is_none()); + + let mut stream1 = bus.new_stream(host1_id, database_id).await.unwrap(); + let m = stream1.next().await.unwrap(); + assert_eq!(m, expected_msg); + + let mut stream2 = bus.new_stream(host2_id, database_id).await.unwrap(); + let m = stream2.next().await.unwrap(); + assert_eq!(m, expected_msg); + + let mut stream3 = bus.new_stream(host3_id, database_id).await.unwrap(); + let m = stream3.next().await.unwrap(); + assert_eq!(m, expected_msg); + + // terminate test + notify.notify_waiters(); + + Ok(()) + }); + + sim.run().unwrap(); + } +} diff --git a/libsqlx-server/src/linc/mod.rs b/libsqlx-server/src/linc/mod.rs new file mode 100644 index 00000000..30b06285 --- /dev/null +++ b/libsqlx-server/src/linc/mod.rs @@ -0,0 +1,38 @@ +use uuid::Uuid; + +use self::proto::StreamId; + +pub mod bus; +pub mod connection; +pub mod connection_pool; +pub mod net; +pub mod proto; +pub mod server; + +type NodeId = Uuid; +type DatabaseId = Uuid; + +const CURRENT_PROTO_VERSION: u32 = 1; +const MAX_STREAM_MSG: usize = 64; + +#[derive(Debug)] +pub struct StreamIdAllocator { + direction: i32, + next_id: i32, +} + +impl StreamIdAllocator { + fn new(positive: bool) -> Self { + let direction = if positive { 1 } else { -1 }; + Self { + direction, + next_id: direction, + } + } + + pub fn allocate(&mut self) -> Option { + let id = self.next_id; + self.next_id = id.checked_add(self.direction)?; + Some(StreamId::new(id)) + } +} diff --git a/libsqlx-server/src/linc/net.rs b/libsqlx-server/src/linc/net.rs new file mode 100644 index 00000000..430b6d08 --- /dev/null +++ b/libsqlx-server/src/linc/net.rs @@ -0,0 +1,81 @@ +use std::io; +use std::net::SocketAddr; +use std::pin::Pin; + +use futures::Future; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::net::TcpListener; +use tokio::net::TcpStream; + +pub trait Connector +where + Self: Sized + AsyncRead + AsyncWrite + Unpin + 'static + Send, +{ + type Future: Future> + Send; + + fn connect(addr: String) -> Self::Future; +} + +impl Connector for TcpStream { + type Future = Pin> + Send>>; + + fn connect(addr: String) -> Self::Future { + Box::pin(TcpStream::connect(addr)) + } +} + +pub trait Listener { + type Stream: AsyncRead + AsyncWrite + Unpin + Send + 'static; + type Future<'a>: Future> + 'a + where + Self: 'a; + + fn accept(&self) -> Self::Future<'_>; +} + +pub struct AcceptFut<'a>(&'a TcpListener); + +impl<'a> Future for AcceptFut<'a> { + type Output = io::Result<(TcpStream, SocketAddr)>; + + fn poll( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + self.0.poll_accept(cx) + } +} + +impl Listener for TcpListener { + type Stream = TcpStream; + type Future<'a> = AcceptFut<'a>; + + fn accept(&self) -> Self::Future<'_> { + AcceptFut(self) + } +} + +#[cfg(test)] +mod test { + use super::*; + + use turmoil::net::{TcpListener, TcpStream}; + + impl Listener for TcpListener { + type Stream = TcpStream; + type Future<'a> = + Pin> + 'a>>; + + fn accept(&self) -> Self::Future<'_> { + Box::pin(self.accept()) + } + } + + impl Connector for TcpStream { + type Future = Pin> + Send + 'static>>; + + fn connect(addr: String) -> Self::Future { + Box::pin(Self::connect(addr)) + } + } +} diff --git a/libsqlx-server/src/linc/proto.rs b/libsqlx-server/src/linc/proto.rs new file mode 100644 index 00000000..7de1002a --- /dev/null +++ b/libsqlx-server/src/linc/proto.rs @@ -0,0 +1,214 @@ +use std::fmt; + +use bytes::Bytes; +use serde::{de::Error, Deserialize, Deserializer, Serialize}; +use uuid::Uuid; + +use super::DatabaseId; + +pub type Program = String; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)] +pub struct StreamId(#[serde(deserialize_with = "non_zero")] i32); + +impl fmt::Display for StreamId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +fn non_zero<'de, D>(d: D) -> Result +where + D: Deserializer<'de>, +{ + let value = i32::deserialize(d)?; + + if value == 0 { + return Err(D::Error::custom("invalid stream_id")); + } + + Ok(value) +} + +impl StreamId { + /// creates a new stream_id. + /// panics if val is zero. + pub fn new(val: i32) -> Self { + assert!(val != 0); + Self(val) + } + + pub fn is_positive(&self) -> bool { + self.0.is_positive() + } + + #[cfg(test)] + pub fn new_unchecked(i: i32) -> Self { + Self(i) + } +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum Message { + /// Messages destined to a node + Node(NodeMessage), + /// message destined to a database + Stream { + stream_id: StreamId, + payload: StreamMessage, + }, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum NodeMessage { + /// Initial message exchanged between nodes when connecting + Handshake { + protocol_version: u32, + node_id: Uuid, + }, + /// Request to open a bi-directional stream between the client and the server + OpenStream { + /// Id to give to the newly opened stream + /// Initiator of the connection create streams with positive ids, + /// and acceptor of the connection create streams with negative ids. + stream_id: StreamId, + /// Id of the database to open the stream to. + database_id: Uuid, + }, + /// Close a previously opened stream + CloseStream { stream_id: StreamId }, + /// Error type returned while handling a node message + Error(NodeError), +} + +#[derive(Debug, Serialize, Deserialize, thiserror::Error, PartialEq, Eq)] +pub enum NodeError { + /// The requested stream does not exist + #[error("unknown stream: {0}")] + UnknownStream(StreamId), + /// Incompatible protocol versions + #[error("invalid protocol version, expected: {expected}")] + HandshakeVersionMismatch { expected: u32 }, + #[error("stream {0} already exists")] + StreamAlreadyExist(StreamId), + #[error("cannot open stream {1}: unknown database {0}")] + UnknownDatabase(DatabaseId, StreamId), +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum StreamMessage { + /// Replication message between a replica and a primary + Replication(ReplicationMessage), + /// Proxy message between a replica and a primary + Proxy(ProxyMessage), + #[cfg(test)] + Dummy, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum ReplicationMessage { + HandshakeResponse { + /// id of the replication log + log_id: Uuid, + /// current frame_no of the primary + current_frame_no: u64, + }, + Replicate { + /// next frame no to send + next_frame_no: u64, + }, + /// a batch of frames that are part of the same transaction + Transaction { + /// if not None, then the last frame is a commit frame, and this is the new size of the database. + size_after: Option, + /// frame_no of the last frame in frames + end_frame_no: u64, + /// a batch of frames part of the transaction. + frames: Vec, + }, + /// Error occurred handling a replication message + Error(ReplicationError), +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub struct Frame { + /// Page id of that frame + page_id: u32, + /// Data + data: Bytes, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum ProxyMessage { + /// Proxy a query to a primary + ProxyRequest { + /// id of the connection to perform the query against + /// If the connection doesn't already exist it is created + /// Id of the request. + /// Responses to this request must have the same id. + connection_id: u32, + req_id: u32, + program: Program, + }, + /// Response to a proxied query + ProxyResponse { + /// id of the request this message is a response to. + req_id: u32, + /// Collection of steps to drive the query builder transducer. + row_step: Vec, + }, + /// Stop processing request `id`. + CancelRequest { req_id: u32 }, + /// Close Connection with passed id. + CloseConnection { connection_id: u32 }, + /// Error returned when handling a proxied query message. + Error(ProxyError), +} + +/// Steps applied to the query builder transducer to build a response to a proxied query. +/// Those types closely mirror those of the `QueryBuilderTrait`. +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum BuilderStep { + BeginStep, + FinishStep(u64, Option), + StepError(StepError), + ColsDesc(Vec), + BeginRows, + BeginRow, + AddRowValue(Value), + FinishRow, + FinishRos, + Finish(ConnectionState), +} + +// State of the connection after a query was executed +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum ConnectionState { + /// The connection is still in a open transaction state + OpenTxn, + /// The connection is idle. + Idle, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum Value {} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub struct Column { + /// name of the column + name: String, + /// Declared type of the column, if any. + decl_ty: Option, +} + +/// for now, the stringified version of a sqld::error::Error. +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub struct StepError(String); + +/// TBD +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum ProxyError {} + +/// TBD +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +pub enum ReplicationError {} diff --git a/libsqlx-server/src/linc/server.rs b/libsqlx-server/src/linc/server.rs new file mode 100644 index 00000000..08c205ef --- /dev/null +++ b/libsqlx-server/src/linc/server.rs @@ -0,0 +1,347 @@ +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::task::JoinSet; + +use crate::linc::connection::Connection; + +use super::bus::Bus; + +pub struct Server { + /// reference to the bus + bus: Bus, + /// Connection tasks owned by the server + connections: JoinSet>, +} + +impl Server { + pub fn new(bus: Bus) -> Self { + Self { + bus, + connections: JoinSet::new(), + } + } + + /// Close all connections + #[cfg(test)] + pub async fn close_connections(&mut self) { + self.connections.abort_all(); + while self.connections.join_next().await.is_some() {} + assert!(self.bus.is_empty()); + } + + pub async fn run(mut self, mut listener: L) + where + L: super::net::Listener, + { + while self.tick(&mut listener).await {} + } + + pub async fn tick(&mut self, listener: &mut L) -> bool + where + L: super::net::Listener, + { + match listener.accept().await { + Ok((stream, _addr)) => { + self.make_connection(stream).await; + true + } + Err(e) => { + tracing::error!("error creating connection: {e}"); + false + } + } + } + + async fn make_connection(&mut self, stream: S) + where + S: AsyncRead + AsyncWrite + Unpin + Send + 'static, + { + let bus = self.bus.clone(); + let fut = async move { + let connection = Connection::new_acceptor(stream, bus.clone()); + connection.run().await; + Ok(()) + }; + + self.connections.spawn(fut); + } +} + +#[cfg(test)] +mod test { + use std::sync::Arc; + + use crate::linc::{ + proto::{ProxyMessage, StreamMessage}, + DatabaseId, NodeId, + }; + + use super::*; + + use futures::{SinkExt, StreamExt}; + use tokio::sync::Notify; + use turmoil::net::TcpStream; + + #[test] + fn server_respond_to_handshake() { + let mut sim = turmoil::Builder::new().build(); + + let host_node_id = NodeId::new_v4(); + let notify = Arc::new(tokio::sync::Notify::new()); + sim.host("host", move || { + let notify = notify.clone(); + async move { + let bus = Bus::new(host_node_id); + let mut server = Server::new(bus); + let mut listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + server.tick(&mut listener).await; + notify.notified().await; + + Ok(()) + } + }); + + sim.client("client", async move { + let node_id = NodeId::new_v4(); + let mut c = Connection::new_initiator( + TcpStream::connect("host:1234").await.unwrap(), + Bus::new(node_id), + ); + + c.tick().await; + c.tick().await; + + assert_eq!(c.peer, Some(host_node_id)); + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn client_create_stream_client_close() { + let mut sim = turmoil::Builder::new().build(); + + let host_node_id = NodeId::new_v4(); + let stream_db_id = DatabaseId::new_v4(); + let notify = Arc::new(Notify::new()); + let expected_msg = StreamMessage::Proxy(ProxyMessage::ProxyRequest { + connection_id: 12, + req_id: 1, + program: "hello".to_string(), + }); + + sim.host("host", { + let notify = notify.clone(); + let expected_msg = expected_msg.clone(); + move || { + let notify = notify.clone(); + let expected_msg = expected_msg.clone(); + async move { + let bus = Bus::new(host_node_id); + let server = Server::new(bus.clone()); + let listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + let mut subs = bus.subscribe(stream_db_id).unwrap(); + tokio::task::spawn_local(server.run(listener)); + + let mut stream = subs.next().await.unwrap(); + + let msg = stream.next().await.unwrap(); + + assert_eq!(msg, expected_msg); + + notify.notify_waiters(); + + assert!(stream.next().await.is_none()); + + notify.notify_waiters(); + + Ok(()) + } + } + }); + + sim.client("client", async move { + let node_id = NodeId::new_v4(); + let bus = Bus::new(node_id); + let mut c = Connection::new_initiator( + TcpStream::connect("host:1234").await.unwrap(), + bus.clone(), + ); + c.tick().await; + c.tick().await; + let _h = tokio::spawn(c.run()); + let mut stream = bus.new_stream(host_node_id, stream_db_id).await.unwrap(); + stream.send(expected_msg).await.unwrap(); + + notify.notified().await; + + drop(stream); + + notify.notified().await; + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn client_create_stream_server_close() { + let mut sim = turmoil::Builder::new().build(); + + let host_node_id = NodeId::new_v4(); + let database_id = DatabaseId::new_v4(); + let notify = Arc::new(Notify::new()); + + sim.host("host", { + let notify = notify.clone(); + move || { + let notify = notify.clone(); + async move { + let bus = Bus::new(host_node_id); + let server = Server::new(bus.clone()); + let listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + let mut subs = bus.subscribe(database_id).unwrap(); + tokio::task::spawn_local(server.run(listener)); + + let stream = subs.next().await.unwrap(); + drop(stream); + + notify.notify_waiters(); + notify.notified().await; + + Ok(()) + } + } + }); + + sim.client("client", async move { + let node_id = NodeId::new_v4(); + let bus = Bus::new(node_id); + let mut c = Connection::new_initiator( + TcpStream::connect("host:1234").await.unwrap(), + bus.clone(), + ); + c.tick().await; + c.tick().await; + let _h = tokio::spawn(c.run()); + let mut stream = bus.new_stream(host_node_id, database_id).await.unwrap(); + + notify.notified().await; + assert!(stream.next().await.is_none()); + notify.notify_waiters(); + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn server_create_stream_server_close() { + let mut sim = turmoil::Builder::new().build(); + + let host_node_id = NodeId::new_v4(); + let notify = Arc::new(Notify::new()); + let client_id = NodeId::new_v4(); + let database_id = DatabaseId::new_v4(); + let expected_msg = StreamMessage::Proxy(ProxyMessage::ProxyRequest { + connection_id: 12, + req_id: 1, + program: "hello".to_string(), + }); + + sim.host("host", { + let notify = notify.clone(); + let expected_msg = expected_msg.clone(); + move || { + let notify = notify.clone(); + let expected_msg = expected_msg.clone(); + async move { + let bus = Bus::new(host_node_id); + let server = Server::new(bus.clone()); + let listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + tokio::task::spawn_local(server.run(listener)); + + let mut stream = bus.new_stream(client_id, database_id).await.unwrap(); + stream.send(expected_msg).await.unwrap(); + notify.notified().await; + drop(stream); + + Ok(()) + } + } + }); + + sim.client("client", async move { + let bus = Bus::new(client_id); + let mut subs = bus.subscribe(database_id).unwrap(); + let c = Connection::new_initiator( + TcpStream::connect("host:1234").await.unwrap(), + bus.clone(), + ); + let _h = tokio::spawn(c.run()); + + let mut stream = subs.next().await.unwrap(); + let msg = stream.next().await.unwrap(); + assert_eq!(msg, expected_msg); + notify.notify_waiters(); + assert!(stream.next().await.is_none()); + + Ok(()) + }); + + sim.run().unwrap(); + } + + #[test] + fn server_create_stream_client_close() { + let mut sim = turmoil::Builder::new().build(); + + let host_node_id = NodeId::new_v4(); + let client_id = NodeId::new_v4(); + let database_id = DatabaseId::new_v4(); + + sim.host("host", { + move || async move { + let bus = Bus::new(host_node_id); + let server = Server::new(bus.clone()); + let listener = turmoil::net::TcpListener::bind("0.0.0.0:1234") + .await + .unwrap(); + tokio::task::spawn_local(server.run(listener)); + + let mut stream = bus.new_stream(client_id, database_id).await.unwrap(); + assert!(stream.next().await.is_none()); + + Ok(()) + } + }); + + sim.client("client", async move { + let bus = Bus::new(client_id); + let mut subs = bus.subscribe(database_id).unwrap(); + let c = Connection::new_initiator( + TcpStream::connect("host:1234").await.unwrap(), + bus.clone(), + ); + let _h = tokio::spawn(c.run()); + + let stream = subs.next().await.unwrap(); + drop(stream); + + Ok(()) + }); + + sim.run().unwrap(); + } +} diff --git a/libsqlx-server/src/main.rs b/libsqlx-server/src/main.rs index a8829093..16e6a38e 100644 --- a/libsqlx-server/src/main.rs +++ b/libsqlx-server/src/main.rs @@ -18,6 +18,7 @@ mod hrana; mod http; mod manager; mod meta; +mod linc; #[tokio::main] async fn main() -> Result<()> {