diff --git a/.cargo/config.toml b/.cargo/config.toml index 05780a6..69d8527 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,4 +3,7 @@ rustflags = [ # (Nightly) Make the current crate share its generic instantiations "-Zshare-generics=y", + # Make sure that tokio console works + "--cfg", + "tokio_unstable" ] diff --git a/.direnv/flake-profile b/.direnv/flake-profile index f9f4da1..0a3af66 120000 --- a/.direnv/flake-profile +++ b/.direnv/flake-profile @@ -1 +1 @@ -flake-profile-18-link \ No newline at end of file +flake-profile-25-link \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 7b87935..303cdcb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,56 +1,57 @@ { - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "CloverHub: Server", - "cargo": { - "args": [ - "build", - "--bin=clover-hub", - "--package=clover-hub" - ], - "filter": { - "name": "clover-hub", - "kind": "bin" - } - }, - "args": [ - "run", - "server" - ], - "env": { - "CLOVER_LOG": "clover=debug", - "CLOVER_MASTER_PRINT": "true" - }, - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Unit Tests: CloverHub: Server", - "cargo": { - "args": [ - "test", - "--no-run", - "--bin=clover-hub", - "--package=clover-hub" - ], - "filter": { - "name": "clover-hub", - "kind": "bin" - } - }, - "args": [ - "run", - "server" - ], - "env": { - "CLOVER_LOG": "clover=debug", - "CLOVER_MASTER_PRINT": "true" - }, - "cwd": "${workspaceFolder}" + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "CloverHub: Server", + "program": "target/debug/clover-hub", + "cargo": { + "args": [ + "build", + "--bin=clover-hub", + "--package=clover-hub" + ], + "filter": { + "name": "clover-hub", + "kind": "bin" } - ] -} \ No newline at end of file + }, + "args": [ + "run", + "server" + ], + "env": { + "CLOVER_LOG": "clover=debug", + "CLOVER_MASTER_PRINT": "true" + }, + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Unit Tests: CloverHub: Server", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=clover-hub", + "--package=clover-hub" + ], + "filter": { + "name": "clover-hub", + "kind": "bin" + } + }, + "args": [ + "run", + "server" + ], + "env": { + "CLOVER_LOG": "clover=debug,console-subscriber=debug", + "CLOVER_MASTER_PRINT": "true" + }, + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/Cargo.lock b/Cargo.lock index f1a69b6..cbf255b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,15 +77,6 @@ dependencies = [ "winit", ] -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.0" @@ -587,18 +578,46 @@ dependencies = [ ] [[package]] -name = "backtrace" -version = "0.3.75" +name = "axum" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", + "axum-core", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", ] [[package]] @@ -2010,7 +2029,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -2121,9 +2140,9 @@ dependencies = [ "can", "chrono", "clap", + "console-subscriber", "crossterm 0.28.1", "decorum", - "dyn_serde", "env_logger", "futures", "git2", @@ -2242,6 +2261,46 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console-api" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8599749b6667e2f0c910c1d0dff6901163ff698a52d5a39720f61b5be4b20d3" +dependencies = [ + "futures-core", + "prost", + "prost-types", + "tonic", + "tonic-prost", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4915b7d8dd960457a1b6c380114c2944f728e7c65294ab247ae6b6f1f37592" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures-task", + "hdrhistogram", + "humantime", + "hyper-util", + "prost", + "prost-types", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -2895,15 +2954,6 @@ dependencies = [ "linux-raw-sys 0.6.5", ] -[[package]] -name = "dyn_serde" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42501063765b768d479b7c61ff59de45bbe9ab37675d13a253647f2d4748a1d6" -dependencies = [ - "serde", -] - [[package]] name = "either" version = "1.15.0" @@ -3495,12 +3545,6 @@ dependencies = [ "windows 0.61.1", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "git2" version = "0.19.0" @@ -3747,6 +3791,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", + "indexmap 2.9.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.6.0" @@ -3812,6 +3875,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "base64 0.21.7", + "byteorder", + "flate2", + "nom", + "num-traits", +] + [[package]] name = "headers" version = "0.3.9" @@ -3990,6 +4066,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + [[package]] name = "hyper" version = "0.14.32" @@ -4000,14 +4082,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.9", "tokio", "tower-service", "tracing", @@ -4023,6 +4105,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.13", "http 1.3.1", "http-body 1.0.1", "httparse", @@ -4049,6 +4132,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper 1.6.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.11" @@ -4063,7 +4159,7 @@ dependencies = [ "hyper 1.6.0", "libc", "pin-project-lite", - "socket2", + "socket2 0.5.9", "tokio", "tower-service", "tracing", @@ -5049,6 +5145,12 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "maybe-rayon" version = "0.1.1" @@ -5824,15 +5926,6 @@ dependencies = [ "cc", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "oboe" version = "0.6.1" @@ -6393,6 +6486,38 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -6885,12 +7010,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -7143,18 +7262,28 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -7467,6 +7596,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "socketcan" version = "1.7.0" @@ -7495,7 +7634,7 @@ dependencies = [ "nb", "neli", "nix 0.29.0", - "socket2", + "socket2 0.5.9", "thiserror 2.0.12", ] @@ -7959,6 +8098,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + [[package]] name = "synstructure" version = "0.13.2" @@ -8238,27 +8383,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.45.1" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "backtrace", "bytes", "libc", "mio 1.0.3", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.2", "tokio-macros", - "windows-sys 0.52.0", + "tracing", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -8349,6 +8494,71 @@ dependencies = [ "winnow", ] +[[package]] +name = "tonic" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a286e33f82f8a1ee2df63f4fa35c0becf4a85a0cb03091a15fd7bf0b402dc94a" +dependencies = [ + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2 0.4.13", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.6.0", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2 0.6.2", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c55a2d6a14174563de34409c9f92ff981d006f56da9c6ecd40d9d4a31500b0" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 2.9.0", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" version = "0.3.3" @@ -9346,7 +9556,7 @@ dependencies = [ "windows-collections", "windows-core 0.61.0", "windows-future", - "windows-link", + "windows-link 0.1.1", "windows-numerics", ] @@ -9411,7 +9621,7 @@ checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ "windows-implement 0.60.0", "windows-interface 0.59.1", - "windows-link", + "windows-link 0.1.1", "windows-result 0.3.2", "windows-strings 0.4.0", ] @@ -9423,7 +9633,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" dependencies = [ "windows-core 0.61.0", - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -9498,6 +9708,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-numerics" version = "0.2.0" @@ -9505,7 +9721,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ "windows-core 0.61.0", - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -9532,7 +9748,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -9551,7 +9767,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -9590,6 +9806,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -9629,13 +9863,30 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -9654,6 +9905,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -9672,6 +9929,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -9690,12 +9953,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -9714,6 +9989,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -9732,6 +10013,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -9750,6 +10037,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -9768,6 +10061,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winit" version = "0.30.10" diff --git a/clover-hub/Cargo.toml b/clover-hub/Cargo.toml index afcff65..61be494 100644 --- a/clover-hub/Cargo.toml +++ b/clover-hub/Cargo.toml @@ -104,6 +104,6 @@ queues = "1.1.0" anyhow = "1.0.97" strum = { version = "0.27.1", features = ["derive"] } base64 = "0.22.1" -dyn_serde = "1.0.2" rmp-serde = "1.3.0" rodio = "0.20.1" +console-subscriber = "0.5.0" diff --git a/clover-hub/src/main.rs b/clover-hub/src/main.rs index 7e4e973..61e26ab 100644 --- a/clover-hub/src/main.rs +++ b/clover-hub/src/main.rs @@ -344,6 +344,8 @@ async fn main() -> Result<(), Box> { env_logger::Builder::new() .parse_filters(&env::var("CLOVER_LOG").unwrap_or("info".to_string())) .init(); + // Debugging console for tokio + // console_subscriber::init(); let big_boy_token = CancellationToken::new(); diff --git a/clover-hub/src/server/appd/mod.rs b/clover-hub/src/server/appd/mod.rs index 3a95fcb..9b4270b 100644 --- a/clover-hub/src/server/appd/mod.rs +++ b/clover-hub/src/server/appd/mod.rs @@ -57,6 +57,17 @@ pub async fn appd_main( info!("Connected to docker on {}!", docker_path.clone()); let docker = Arc::new(docker_conn); + let ipc_recv_token = cancellation_tokens.0.clone(); + let (ipc_rx, ipc_handle) = user.subscribe(); + let ipc_recv_handle = tokio::task::spawn(async move { + tokio::select! { + _ = ipc_recv_token.cancelled() => { + debug!("ipc_recv exited"); + }, + _ = handle_ipc_msg(ipc_rx) => {} + } + }); + let init_store = Arc::new(store.clone()); let init_user = Arc::new(user.clone()); let init_docker = docker.clone(); @@ -132,17 +143,6 @@ pub async fn appd_main( }) .await; - let ipc_recv_token = cancellation_tokens.0.clone(); - let (ipc_rx, ipc_handle) = user.subscribe(); - let ipc_recv_handle = tokio::task::spawn(async move { - tokio::select! { - _ = ipc_recv_token.cancelled() => { - debug!("ipc_recv exited"); - }, - _ = handle_ipc_msg(ipc_rx) => {} - } - }); - let cleanup_store = store.clone(); let cleanup_docker = docker.clone(); let cleanup_token = cancellation_tokens.0.clone(); diff --git a/clover-hub/src/server/inference_engine/mod.rs b/clover-hub/src/server/inference_engine/mod.rs index 243c55c..419cc6e 100644 --- a/clover-hub/src/server/inference_engine/mod.rs +++ b/clover-hub/src/server/inference_engine/mod.rs @@ -57,6 +57,17 @@ pub async fn inference_engine_main( ) { info!("Starting Inference Engine..."); + let ipc_recv_token = cancellation_tokens.0.clone(); + let (ipc_rx, ipc_handle) = user.subscribe(); + let ipc_recv_handle = tokio::task::spawn(async move { + tokio::select! { + _ = ipc_recv_token.cancelled() => { + debug!("ipc_recv exited"); + }, + _ = handle_ipc_msg(ipc_rx) => {} + } + }); + let init_user = Arc::new(user.clone()); cancellation_tokens .0 @@ -77,17 +88,6 @@ pub async fn inference_engine_main( }) .await; - let ipc_recv_token = cancellation_tokens.0.clone(); - let (ipc_rx, ipc_handle) = user.subscribe(); - let ipc_recv_handle = tokio::task::spawn(async move { - tokio::select! { - _ = ipc_recv_token.cancelled() => { - debug!("ipc_recv exited"); - }, - _ = handle_ipc_msg(ipc_rx) => {} - } - }); - let cleanup_token = cancellation_tokens.0.clone(); tokio::select! { _ = cleanup_token.cancelled() => { diff --git a/clover-hub/src/server/mod.rs b/clover-hub/src/server/mod.rs index 1e68609..30802ca 100644 --- a/clover-hub/src/server/mod.rs +++ b/clover-hub/src/server/mod.rs @@ -169,6 +169,9 @@ pub async fn server_main( .unwrap(); debug!("Created AppDaemon Nexus user!"); + // Create oneshot channel for ready signal + let (nexus_ready_tx, nexus_ready_rx) = tokio::sync::oneshot::channel(); + // Start Nexus debug!("Starting Nexus..."); let nexus_port = Arc::new(port); @@ -198,10 +201,23 @@ pub async fn server_main( (appd_user_config.clone(), 0, from_appd), ], nexus_tokens_clone, + Some(nexus_ready_tx), ) .await; }); + // WAIT for nexus to be ready before starting services + match nexus_ready_rx.await { + Ok(_) => { + info!("Nexus is ready! Starting services..."); + } + Err(_) => { + error!("Nexus failed to signal ready state!"); + server_token.cancel(); + return; + } + } + // Start Warehouse debug!("Starting Warehouse..."); let warehouse_store_clone = Arc::new(warehouse_store.clone()); diff --git a/clover-hub/src/server/modman/busses/proxies/uart.rs b/clover-hub/src/server/modman/busses/proxies/uart.rs index 3939d77..0330e79 100644 --- a/clover-hub/src/server/modman/busses/proxies/uart.rs +++ b/clover-hub/src/server/modman/busses/proxies/uart.rs @@ -10,7 +10,10 @@ use crate::server::modman::{ PortStatus, }, }; -use log::debug; +use log::{ + debug, + warn, +}; use nexus::server::{ models::IPCMessageWithId, websockets::WsIn, @@ -37,6 +40,12 @@ impl Bus for UARTBus { from_bus: tokio::sync::broadcast::Sender, to_bus: tokio::sync::broadcast::Sender, ) -> Result>, anyhow::Error> { + let warn_config = self.store.config.lock().await; + if !(warn_config.modman.uart_ports.len() > 0) { + warn!("No UART ports configured to proxy messages to! You may see message delivery errors from `nexus::user` due to a closed channel (the UARTBus proxy); they can be safely ignored."); + } + drop(warn_config); + match serialport::available_ports() { Ok(port_info) => { let mut handles = vec![]; diff --git a/clover-hub/src/server/modman/mod.rs b/clover-hub/src/server/modman/mod.rs index 984a5f1..ff59b2d 100644 --- a/clover-hub/src/server/modman/mod.rs +++ b/clover-hub/src/server/modman/mod.rs @@ -64,6 +64,19 @@ pub async fn modman_main( } }); + let ipc_recv_token = cancellation_tokens.0.clone(); + let (ipc_rx, ipc_handle) = user.subscribe(); + let ipc_recv_store = store.clone(); + let ipc_user = Arc::new(user.clone()); + let ipc_recv_handle = tokio::task::spawn(async move { + tokio::select! { + _ = ipc_recv_token.cancelled() => { + debug!("ipc_recv exited"); + }, + _ = handle_ipc_msg(ipc_recv_store, ipc_rx, ipc_user) => {} + } + }); + let init_store = Arc::new(store.clone()); let init_user = Arc::new(user.clone()); cancellation_tokens @@ -163,19 +176,6 @@ pub async fn modman_main( }) .await; - let ipc_recv_token = cancellation_tokens.0.clone(); - let (ipc_rx, ipc_handle) = user.subscribe(); - let ipc_recv_store = store.clone(); - let ipc_user = Arc::new(user.clone()); - let ipc_recv_handle = tokio::task::spawn(async move { - tokio::select! { - _ = ipc_recv_token.cancelled() => { - debug!("ipc_recv exited"); - }, - _ = handle_ipc_msg(ipc_recv_store, ipc_rx, ipc_user) => {} - } - }); - let mod_clean_token = cancellation_tokens.0.clone(); tokio::select! { _ = mod_clean_token.cancelled() => { diff --git a/clover-hub/src/server/renderer/mod.rs b/clover-hub/src/server/renderer/mod.rs index 34fe8e7..5c9e6c9 100644 --- a/clover-hub/src/server/renderer/mod.rs +++ b/clover-hub/src/server/renderer/mod.rs @@ -75,10 +75,22 @@ pub async fn renderer_main( // TODO: Add this as a CLI/Config option! let custom_bevy_ipc = system_ui_ipc; - std::thread::spawn(move || system_ui_main(custom_bevy_ipc, Some(false))); + let bevy_thread = std::thread::spawn(move || system_ui_main(custom_bevy_ipc, Some(false))); // let display_handles = Arc::new(HashMap::new()); + let ipc_display_registration_queue = display_registration_queue.clone(); + let ipc_recv_token = cancellation_tokens.0.clone(); + let (ipc_rx, ipc_handle) = user.subscribe(); + let ipc_recv_handle = tokio::task::spawn(async move { + tokio::select! { + _ = ipc_recv_token.cancelled() => { + debug!("ipc_recv exited"); + }, + _ = handle_ipc_msg(ipc_rx, ipc_display_registration_queue) => {} + } + }); + let init_user = Arc::new(user.clone()); cancellation_tokens .0 @@ -114,18 +126,6 @@ pub async fn renderer_main( }) .await; - let ipc_display_registration_queue = display_registration_queue.clone(); - let ipc_recv_token = cancellation_tokens.0.clone(); - let (ipc_rx, ipc_handle) = user.subscribe(); - let ipc_recv_handle = tokio::task::spawn(async move { - tokio::select! { - _ = ipc_recv_token.cancelled() => { - debug!("ipc_recv exited"); - }, - _ = handle_ipc_msg(ipc_rx, ipc_display_registration_queue) => {} - } - }); - let cleanup_token = cancellation_tokens.0.clone(); tokio::select! { _ = cleanup_token.cancelled() => { @@ -136,6 +136,16 @@ pub async fn renderer_main( let _ = bevy_cancel_tx.send(bevy::prelude::AppExit::Success); + info!("Waiting for Bevy to shut down..."); + match bevy_thread.join() { + Ok(_) => { + info!("Bevy thread exited cleanly"); + } + Err(e) => { + error!("Bevy thread panicked during shutdown: {:?}", e); + } + } + // TODO: Clean up registered displays when server is shutting down. std::mem::drop(store); diff --git a/clover-hub/src/server/warehouse/mod.rs b/clover-hub/src/server/warehouse/mod.rs index 7941fdc..f23f897 100644 --- a/clover-hub/src/server/warehouse/mod.rs +++ b/clover-hub/src/server/warehouse/mod.rs @@ -234,6 +234,17 @@ pub async fn warehouse_main( )) .await; + let (mut ipc_rx, nexus_recv_handle) = user.subscribe(); + let ipc_recv_token = cancellation_tokens.0.clone(); + let ipc_recv_handle = tokio::task::spawn(async move { + tokio::select! { + _ = ipc_recv_token.cancelled() => { + debug!("ipc_recv exited"); + }, + _ = handle_ipc_msg(ipc_rx) => {} + } + }); + let init_store = Arc::new(store.clone()); let init_user = Arc::new(user.clone()); let init_tokens = cancellation_tokens.clone(); @@ -266,17 +277,6 @@ pub async fn warehouse_main( }) .await; - let (mut ipc_rx, nexus_recv_handle) = user.subscribe(); - let ipc_recv_token = cancellation_tokens.0.clone(); - let ipc_recv_handle = tokio::task::spawn(async move { - tokio::select! { - _ = ipc_recv_token.cancelled() => { - debug!("ipc_recv exited"); - }, - _ = handle_ipc_msg(ipc_rx) => {} - } - }); - let cleanup_token = cancellation_tokens.0.clone(); tokio::select! { _ = cleanup_token.cancelled() => { diff --git a/flake.lock b/flake.lock index 4cc7717..a8ff4b0 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,39 @@ { "nodes": { + "crane": { + "locked": { + "lastModified": 1763511871, + "narHash": "sha256-KKZWi+ij7oT0Ag8yC6MQkzfHGcytyjMJDD+47ZV1YNU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "099f9014bc8d0cd6e445470ea1df0fd691d5a548", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": "nixpkgs", + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1763880175, + "narHash": "sha256-WfItZn6duisxCxyltbu7Hs7kxzNeylgZGOwCYwHe26g=", + "owner": "nix-community", + "repo": "fenix", + "rev": "a563f057979806c59da53070297502eb7af22f62", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -20,15 +54,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1748693115, - "narHash": "sha256-StSrWhklmDuXT93yc3GrTlb0cKSS0agTAxMGjLKAsY8=", - "owner": "NixOS", + "lastModified": 1763678758, + "narHash": "sha256-+hBiJ+kG5IoffUOdlANKFflTT5nO3FrrR2CA3178Y5s=", + "owner": "nixos", "repo": "nixpkgs", - "rev": "910796cabe436259a29a72e8d3f5e180fc6dfacc", + "rev": "117cc7f94e8072499b0a7aa4c52084fa4e11cc9b", "type": "github" }, "original": { - "owner": "NixOS", + "owner": "nixos", "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" @@ -36,42 +70,42 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1744536153, - "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "lastModified": 1763678758, + "narHash": "sha256-+hBiJ+kG5IoffUOdlANKFflTT5nO3FrrR2CA3178Y5s=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "rev": "117cc7f94e8072499b0a7aa4c52084fa4e11cc9b", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixpkgs-unstable", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, "root": { "inputs": { + "crane": "crane", + "fenix": "fenix", "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" + "nixpkgs": "nixpkgs_2" } }, - "rust-overlay": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, + "rust-analyzer-src": { + "flake": false, "locked": { - "lastModified": 1748832016, - "narHash": "sha256-TQSaFa1wWJr6GOs+K8lecK4AKKr8k6mwxHIPCOmVkgs=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "7ec2ea005b600dac9436a7c5c6b66d960cbfcea2", + "lastModified": 1763846202, + "narHash": "sha256-f5PvQONttEQCjnQ52zAEVJvXDZ5l2gbItLfDyfcyGgk=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "50621856a594a357c3aff0c5176ba8db4118133d", "type": "github" }, "original": { - "owner": "oxalica", - "repo": "rust-overlay", + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 633e91f..3a558b1 100644 --- a/flake.nix +++ b/flake.nix @@ -1,72 +1,151 @@ { - description = "CLOVER's Flake"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - rust-overlay.url = "github:oxalica/rust-overlay"; - flake-utils.url = "github:numtide/flake-utils"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + crane.url = "github:ipetkov/crane"; + fenix.url = "github:nix-community/fenix"; + flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, nixpkgs, rust-overlay, flake-utils, ... }: - flake-utils.lib.eachDefaultSystem (system: + outputs = + { + nixpkgs, + flake-utils, + ... + }@inputs: + let + fenix = inputs.fenix.packages; + in + # Iterate over Arm, x86 for macOS and Linux + (flake-utils.lib.eachDefaultSystem ( + system: let - overlays = [ (import rust-overlay) ]; - pkgs = import nixpkgs { - inherit system overlays; - config.allowUnfree = true; + pkgs = nixpkgs.legacyPackages.${system}; + crane = inputs.crane.mkLib pkgs; + # Toolchain + toolchain = fenix.${system}.fromToolchainFile { + file = ./rust-toolchain.toml; + sha256 = "sha256-mDF70Zk2wfWYsYRIdAUMn5ixGahle3VFtGjjyz8oiHU="; + }; + craneLib = crane.overrideToolchain toolchain; + + # Deps for all software packages + buildInputs = with pkgs; [ + openssl.dev + pkg-config + wayland + ]; + + src = pkgs.lib.cleanSourceWith { + src = craneLib.path ./.; + filter = path: type: (pkgs.lib.hasInfix "/assets" path) || (craneLib.filterCargoSources path type); + }; + commonArgs = { + doCheck = false; + inherit src buildInputs; + nativeBuildInputs = libraries; }; + + libraries = with pkgs; [ + openssl + pkg-config + vulkan-loader + libxkbcommon + wayland + xorg.libX11 + xorg.libxcb + alsa-lib + udev + vulkan-loader + xorg.libX11 + xorg.libXrandr + xorg.libXcursor + xorg.libXi + at-spi2-atk + atkmm + cairo + gdk-pixbuf + glib + gtk3 + harfbuzz + librsvg + libsoup_3 + pango + webkitgtk_4_1 + fontconfig + libz + ]; + # Compile all artifacts + appDeps = craneLib.buildDepsOnly commonArgs; + + appListings = [ + { + name = "clover-hub"; + path = ./clover-hub/Cargo.toml; + } + { + name = "ratchet"; + path = ./toolbox/ratchet/Cargo.toml; + } + ]; + + # Compile + pkg = + listing: + craneLib.buildPackage ( + commonArgs + // { + cargoExtraArgs = "-p ${listing.name}"; + cargoArtifacts = appDeps; + pname = listing.name; + version = (builtins.fromTOML (builtins.readFile listing.path)).package.version; + } + ); + app = + listing: + flake-utils.lib.mkApp { + drv = pkg listing; + }; in { - devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ - openssl - pkg-config - (rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override { - extensions = [ "rust-src" ]; - targets = [ "arm-unknown-linux-gnueabihf" "aarch64-unknown-linux-gnu" "x86_64-pc-windows-gnu" ]; - })) - alsa-lib - udev - vulkan-loader - xorg.libX11 - xorg.libXrandr - xorg.libXcursor - xorg.libXi - kdePackages.qtbase + # nix build + packages = { + default = pkg (builtins.elemAt appListings 0); + } + // builtins.listToAttrs ( + map (listing: { + name = listing.name; + value = pkg listing; + }) appListings + ); + + # nix run + apps = { + default = app (builtins.elemAt appListings 0); + } + // builtins.listToAttrs ( + map (listing: { + name = listing.name; + value = app listing; + }) appListings + ); + + # nix develop + devShells.default = craneLib.devShell { + inherit buildInputs; + + packages = [ + toolchain + ] + ++ (with pkgs; [ nodejs_22 yarn-berry - trunk-io rust-analyzer - at-spi2-atk - atkmm - cairo - gdk-pixbuf - glib - gtk3 - harfbuzz - librsvg - libsoup_3 - pango - webkitgtk_4_1 - openssl - wayland - waylandpp - fontconfig - ]; + tokio-console + ]) + ++ libraries; - shellHook = '' - export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${ - pkgs.lib.makeLibraryPath [ - pkgs.udev - pkgs.alsa-lib - pkgs.vulkan-loader - pkgs.libxkbcommon - pkgs.wayland - ] - }" - RUST_SRC_PATH = "${pkgs.rust-bin.nightly.latest.default}/lib/rustlib/src/rust/library"; - ''; + LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath libraries}"; }; } - ); + )); }