diff --git a/Cargo.lock b/Cargo.lock index 158a8b77..6719bd3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,6 +356,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + [[package]] name = "blocking" version = "1.6.1" @@ -654,6 +663,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctrlc" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" +dependencies = [ + "dispatch2", + "nix 0.30.1", + "windows-sys 0.61.2", +] + [[package]] name = "data-encoding" version = "2.9.0" @@ -712,6 +732,22 @@ dependencies = [ "syn 2.0.105", ] +[[package]] +name = "dhat" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827" +dependencies = [ + "backtrace", + "lazy_static", + "mintex", + "parking_lot", + "rustc-hash", + "serde", + "serde_json", + "thousands", +] + [[package]] name = "digest" version = "0.10.7" @@ -722,6 +758,18 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.0", + "block2", + "libc", + "objc2", +] + [[package]] name = "document-features" version = "0.2.11" @@ -1532,6 +1580,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.27" @@ -1636,6 +1693,12 @@ dependencies = [ "adler2", ] +[[package]] +name = "mintex" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c505b3e17ed6b70a7ed2e67fbb2c560ee327353556120d6e72f5232b6880d536" + [[package]] name = "mio" version = "1.0.3" @@ -1688,6 +1751,18 @@ dependencies = [ "memoffset 0.9.1", ] +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "no-std-net" version = "0.6.0" @@ -1722,6 +1797,21 @@ dependencies = [ "libc", ] +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + [[package]] name = "object" version = "0.36.7" @@ -1749,6 +1839,29 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + [[package]] name = "paste" version = "1.0.15" @@ -2010,6 +2123,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "regex" version = "1.11.3" @@ -2076,6 +2198,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.44" @@ -2219,6 +2347,8 @@ dependencies = [ "axum", "bitvec", "control_core", + "ctrlc", + "dhat", "ethercat_hal", "ethercrab", "futures", @@ -2238,6 +2368,7 @@ dependencies = [ "tracing-journald", "tracing-subscriber", "units", + "utils", ] [[package]] @@ -2515,6 +2646,12 @@ dependencies = [ "syn 2.0.105", ] +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + [[package]] name = "thread_local" version = "1.1.8" @@ -2879,6 +3016,14 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utils" +version = "0.1.0" +dependencies = [ + "backtrace", + "dhat", +] + [[package]] name = "valuable" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index a459f94c..2e28f463 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ #"ethercat-eeprom-dump", "control-core-derive", "units", + "utils", ] exclude = [] resolver = "2" diff --git a/electron/src/client/socketioStore.ts b/electron/src/client/socketioStore.ts index 5940aa70..335d9fee 100644 --- a/electron/src/client/socketioStore.ts +++ b/electron/src/client/socketioStore.ts @@ -353,7 +353,6 @@ const useSocketioStore = create()((set, get) => ({ namespaceId.machine_identification_unique.serial, ); //console.log(machineExists); - socket.connect(); if (machineExists && !socket.connected) { socket.connect(); clearInterval(intervalId); // stop polling diff --git a/machines/Cargo.toml b/machines/Cargo.toml index 998b7eac..043cf63a 100644 --- a/machines/Cargo.toml +++ b/machines/Cargo.toml @@ -46,5 +46,8 @@ io-uring = [] development-build = [] + + + [package.metadata.cargo-machete] ignored = ["tonic"] diff --git a/server/Cargo.toml b/server/Cargo.toml index d68eb1f1..5be36804 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -43,8 +43,12 @@ tracing-subscriber = { version = "0.3.20", features = [ "chrono", "registry", ] } +utils = { version = "0.1.0", path="../utils" } tonic = { version = "0.13.1", optional = true } spin_sleep = "1.3.3" +dhat = { version = "0.3.3", optional = true } +ctrlc = { version = "3.3", optional = true } + [dev-dependencies] approx = "0.5.1" @@ -58,7 +62,11 @@ tracing-journald = ["dep:tracing-journald"] mock-machine = [] memory-locking = [] io-uring = [] -development-build = [] +development-build = ["ctrlc"] +heap-profile = ["dhat"] + + + [profile.release] codegen-units = 1 diff --git a/server/src/loop.rs b/server/src/loop.rs index 1a3299c3..35e8055d 100644 --- a/server/src/loop.rs +++ b/server/src/loop.rs @@ -105,7 +105,7 @@ pub fn start_loop_thread( } } - if let Err(e) = smol::block_on(loop_once(&mut rt_loop_inputs)) { + if let Err(e) = loop_once(&mut rt_loop_inputs) { tracing::error!( "Loop failed\n {:?} \n Last Loop Took: {:?}", e, @@ -237,7 +237,7 @@ pub fn execute_machines(machines: &mut Vec>) { } // No more logging in loop_once -pub async fn loop_once<'maindevice>(inputs: &mut RtLoopInputs<'_>) -> Result<(), anyhow::Error> { +pub fn loop_once<'maindevice>(inputs: &mut RtLoopInputs<'_>) -> Result<(), anyhow::Error> { let loop_once_start = std::time::Instant::now(); if inputs.ethercat_setup.is_some() && inputs.ethercat_perf_metrics.is_some() { inputs @@ -278,7 +278,7 @@ pub async fn loop_once<'maindevice>(inputs: &mut RtLoopInputs<'_>) -> Result<(), // We do this, so that when no rt relevant code runs the cpu doesnt spin at 100% for no reason let loop_duration = loop_once_start.elapsed(); if inputs.cycle_target > loop_once_start.elapsed() { - smol::Timer::after(inputs.cycle_target - loop_duration).await; + smol::block_on(smol::Timer::after(inputs.cycle_target - loop_duration)); } } diff --git a/server/src/main.rs b/server/src/main.rs index d81be794..9bd99f44 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -38,6 +38,7 @@ use smol::{ use socketio::{main_namespace::machines_event::MachineObj, queue::start_socketio_queue}; use socketioxide::extract::SocketRef; use std::{collections::HashMap, sync::Arc, time::Duration}; + pub mod app_state; pub mod ethercat; pub mod logging; @@ -265,11 +266,38 @@ async fn handle_async_requests(recv: Receiver, shared_state: } } +#[cfg(feature = "development-build")] +use std::sync::atomic::{AtomicBool, Ordering}; + +#[cfg(feature = "development-build")] +fn setup_ctrlc_handler() -> Arc { + let running = Arc::new(AtomicBool::new(true)); + let r = running.clone(); + + ctrlc::set_handler(move || { + eprintln!("Ctrl-C pressed, shutting down..."); + r.store(false, Ordering::SeqCst); + }) + .expect("Error setting Ctrl-C handler"); + + running +} + +#[cfg(feature = "heap-profile")] +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + fn main() { logging::init_tracing(); tracing::info!("Tracing initialized successfully"); init_panic_handling(); + #[cfg(feature = "heap-profile")] + let _profiler = dhat::Profiler::new_heap(); + + #[cfg(feature = "development-build")] + let running = setup_ctrlc_handler(); + const CYCLE_TARGET_TIME: Duration = Duration::from_micros(300); // for the "hot thread" @@ -297,6 +325,11 @@ fn main() { smol::block_on(async { loop { + #[cfg(feature = "development-build")] + if !running.load(Ordering::SeqCst) { + tracing::info!("Shutdown signal received, exiting main loop."); + break; + } // lets the async runtime decide which future to run next select! { res = ethercat_fut => { diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 index 00000000..0b4bd1e3 --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "utils" +version = "0.1.0" +edition = "2021" + +[dependencies] +backtrace = "0.3" +dhat = "0.3.3" + +[features] +heap-profile = [] diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 index 00000000..99677de8 --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,3 @@ +#[cfg(feature = "heap-profile")] +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc;