From 5c6a87be7d99e3656b263c6da664cd9e734ebb2d Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Wed, 14 Jun 2023 12:04:24 +0200 Subject: [PATCH 1/5] Add `--delay-startup` argument to Ark --- Cargo.lock | 80 ++++++++++++++++++++++++++++++++++++++++++ crates/ark/Cargo.toml | 1 + crates/ark/src/main.rs | 29 +++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index cf84011a2..bb50f08b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,6 +106,7 @@ dependencies = [ "libc", "log", "nix", + "notify", "once_cell", "parking_lot", "regex", @@ -605,6 +606,18 @@ dependencies = [ "libc", ] +[[package]] +name = "filetime" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.48.0", +] + [[package]] name = "fnv" version = "1.0.7" @@ -620,6 +633,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "futf" version = "0.1.5" @@ -990,6 +1012,26 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "io-lifetimes" version = "1.0.10" @@ -1056,6 +1098,26 @@ dependencies = [ "rayon", ] +[[package]] +name = "kqueue" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1248,6 +1310,24 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "notify" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d9ba6c734de18ca27c8cef5cd7058aa4ac9f63596131e4c7e41e579319032a2" +dependencies = [ + "bitflags", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "walkdir", + "windows-sys 0.45.0", +] + [[package]] name = "num-integer" version = "0.1.45" diff --git a/crates/ark/Cargo.toml b/crates/ark/Cargo.toml index c53c2bafa..609b223e8 100644 --- a/crates/ark/Cargo.toml +++ b/crates/ark/Cargo.toml @@ -28,6 +28,7 @@ libR-sys = "0.5.0" libc = "0.2" log = "0.4.17" nix = { version = "0.26.2", features = ["signal"] } +notify = "6.0.0" once_cell = "1.17.1" parking_lot = "0.12.1" regex = "1.7.1" diff --git a/crates/ark/src/main.rs b/crates/ark/src/main.rs index 42039a8c9..0af06dcd2 100644 --- a/crates/ark/src/main.rs +++ b/crates/ark/src/main.rs @@ -24,6 +24,7 @@ use bus::Bus; use crossbeam::channel::bounded; use log::*; use nix::sys::signal::*; +use notify::Watcher; use stdext::unwrap; fn start_kernel(connection_file: ConnectionFile, capture_streams: bool) { @@ -203,6 +204,7 @@ fn main() { let mut connection_file: Option = None; let mut log_file: Option = None; + let mut delay_file: Option = None; let mut has_action = false; let mut capture_streams = true; @@ -241,6 +243,16 @@ fn main() { break; } }, + "--delay-startup" => { + if let Some(file) = argv.next() { + delay_file = Some(file); + } else { + eprintln!( + "A notification file must be specified with the --delay-startup argument." + ); + break; + } + }, other => { eprintln!("Argument '{}' unknown", other); break; @@ -248,6 +260,23 @@ fn main() { } } + if let Some(file) = delay_file { + let path = std::path::Path::new(&file); + let (tx, rx) = bounded(1); + + if let Err(err) = (|| -> anyhow::Result<()> { + let mut watcher = notify::RecommendedWatcher::new(tx, Default::default()).unwrap(); + watcher.watch(path, notify::RecursiveMode::NonRecursive)?; + + let _ = rx.recv()?; + watcher.unwatch(path)?; + + Ok(()) + })() { + eprintln!("Problem with the delay file: {:?}", err); + } + } + // If the user didn't specify an action, print the usage instructions and // exit if !has_action { From 6692b33499eb5c99f909444a6ecad4ca58aa3950 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Wed, 14 Jun 2023 20:48:53 +0200 Subject: [PATCH 2/5] Poll notification file with small interval --- crates/ark/src/main.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/ark/src/main.rs b/crates/ark/src/main.rs index 0af06dcd2..9eea2ee82 100644 --- a/crates/ark/src/main.rs +++ b/crates/ark/src/main.rs @@ -22,6 +22,7 @@ use ark::shell::Shell; use ark::version::detect_r; use bus::Bus; use crossbeam::channel::bounded; +use crossbeam::channel::unbounded; use log::*; use nix::sys::signal::*; use notify::Watcher; @@ -262,10 +263,14 @@ fn main() { if let Some(file) = delay_file { let path = std::path::Path::new(&file); - let (tx, rx) = bounded(1); + let (tx, rx) = unbounded(); if let Err(err) = (|| -> anyhow::Result<()> { - let mut watcher = notify::RecommendedWatcher::new(tx, Default::default()).unwrap(); + let config = notify::Config::default() + .with_poll_interval(std::time::Duration::from_millis(2)) + .with_compare_contents(false); + + let mut watcher = notify::RecommendedWatcher::new(tx, config).unwrap(); watcher.watch(path, notify::RecursiveMode::NonRecursive)?; let _ = rx.recv()?; From b1ca36b18251145dbdc5f08d349c00763e014b7e Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 15 Jun 2023 11:46:22 +0200 Subject: [PATCH 3/5] Ignore creation events --- crates/ark/src/main.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/crates/ark/src/main.rs b/crates/ark/src/main.rs index 9eea2ee82..be7484fc8 100644 --- a/crates/ark/src/main.rs +++ b/crates/ark/src/main.rs @@ -261,6 +261,9 @@ fn main() { } } + // Initialize the logger. + logger::initialize(log_file.as_deref()); + if let Some(file) = delay_file { let path = std::path::Path::new(&file); let (tx, rx) = unbounded(); @@ -273,9 +276,22 @@ fn main() { let mut watcher = notify::RecommendedWatcher::new(tx, config).unwrap(); watcher.watch(path, notify::RecursiveMode::NonRecursive)?; - let _ = rx.recv()?; - watcher.unwatch(path)?; + loop { + let ev = rx.recv()?; + match ev.unwrap().kind { + notify::event::EventKind::Modify(_) => { + break; + }, + notify::event::EventKind::Remove(_) => { + break; + }, + _ => { + continue; + }, + } + } + watcher.unwatch(path)?; Ok(()) })() { eprintln!("Problem with the delay file: {:?}", err); @@ -289,9 +305,6 @@ fn main() { return; } - // Initialize the logger. - logger::initialize(log_file.as_deref()); - // Register segfault handler to get a backtrace. Should be after // initialising `log!`. Note that R will not override this handler // because we set `R_SignalHandlers` to 0 before startup. From 799061eed6a5943d8d9ab1cef12bf05c7ad24a20 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 15 Jun 2023 12:32:54 +0200 Subject: [PATCH 4/5] Rename `--delay-startup` to `--startup-notifier-file` --- crates/ark/src/main.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/ark/src/main.rs b/crates/ark/src/main.rs index be7484fc8..7c3a133ad 100644 --- a/crates/ark/src/main.rs +++ b/crates/ark/src/main.rs @@ -205,7 +205,7 @@ fn main() { let mut connection_file: Option = None; let mut log_file: Option = None; - let mut delay_file: Option = None; + let mut startup_notifier_file: Option = None; let mut has_action = false; let mut capture_streams = true; @@ -244,12 +244,12 @@ fn main() { break; } }, - "--delay-startup" => { + "--startup-notifier-file" => { if let Some(file) = argv.next() { - delay_file = Some(file); + startup_notifier_file = Some(file); } else { eprintln!( - "A notification file must be specified with the --delay-startup argument." + "A notification file must be specified with the --startup-notifier-file argument." ); break; } @@ -264,7 +264,7 @@ fn main() { // Initialize the logger. logger::initialize(log_file.as_deref()); - if let Some(file) = delay_file { + if let Some(file) = startup_notifier_file { let path = std::path::Path::new(&file); let (tx, rx) = unbounded(); From 2ddb6baf668bcff8b50ff1b53aa0297e1228e5af Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 15 Jun 2023 12:40:06 +0200 Subject: [PATCH 5/5] Add `--startup-delay` argument --- crates/ark/src/main.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/ark/src/main.rs b/crates/ark/src/main.rs index 7c3a133ad..f3a288243 100644 --- a/crates/ark/src/main.rs +++ b/crates/ark/src/main.rs @@ -206,6 +206,7 @@ fn main() { let mut connection_file: Option = None; let mut log_file: Option = None; let mut startup_notifier_file: Option = None; + let mut startup_delay: Option = None; let mut has_action = false; let mut capture_streams = true; @@ -254,6 +255,21 @@ fn main() { break; } }, + "--startup-delay" => { + if let Some(delay_arg) = argv.next() { + if let Ok(delay) = delay_arg.parse::() { + startup_delay = Some(std::time::Duration::from_millis(delay)); + } else { + eprintln!("Can't parse delay in milliseconds"); + break; + } + } else { + eprintln!( + "A delay in milliseconds must be specified with the --startup-delay argument." + ); + break; + } + }, other => { eprintln!("Argument '{}' unknown", other); break; @@ -298,6 +314,10 @@ fn main() { } } + if let Some(delay) = startup_delay { + std::thread::sleep(delay); + } + // If the user didn't specify an action, print the usage instructions and // exit if !has_action {