Skip to content

Commit 66f7e1d

Browse files
authored
Merge pull request #35 from posit-dev/feature/delay-startup
Add `--startup-notifier-file` and `--startup-delay` arguments to Ark
2 parents 351fed0 + 2ddb6ba commit 66f7e1d

File tree

3 files changed

+151
-3
lines changed

3 files changed

+151
-3
lines changed

Cargo.lock

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ark/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ libR-sys = "0.5.0"
2828
libc = "0.2"
2929
log = "0.4.17"
3030
nix = { version = "0.26.2", features = ["signal"] }
31+
notify = "6.0.0"
3132
once_cell = "1.17.1"
3233
parking_lot = "0.12.1"
3334
regex = "1.7.1"

crates/ark/src/main.rs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ use ark::shell::Shell;
2222
use ark::version::detect_r;
2323
use bus::Bus;
2424
use crossbeam::channel::bounded;
25+
use crossbeam::channel::unbounded;
2526
use log::*;
2627
use nix::sys::signal::*;
28+
use notify::Watcher;
2729
use stdext::unwrap;
2830

2931
fn start_kernel(connection_file: ConnectionFile, capture_streams: bool) {
@@ -203,6 +205,8 @@ fn main() {
203205

204206
let mut connection_file: Option<String> = None;
205207
let mut log_file: Option<String> = None;
208+
let mut startup_notifier_file: Option<String> = None;
209+
let mut startup_delay: Option<std::time::Duration> = None;
206210
let mut has_action = false;
207211
let mut capture_streams = true;
208212

@@ -241,23 +245,86 @@ fn main() {
241245
break;
242246
}
243247
},
248+
"--startup-notifier-file" => {
249+
if let Some(file) = argv.next() {
250+
startup_notifier_file = Some(file);
251+
} else {
252+
eprintln!(
253+
"A notification file must be specified with the --startup-notifier-file argument."
254+
);
255+
break;
256+
}
257+
},
258+
"--startup-delay" => {
259+
if let Some(delay_arg) = argv.next() {
260+
if let Ok(delay) = delay_arg.parse::<u64>() {
261+
startup_delay = Some(std::time::Duration::from_millis(delay));
262+
} else {
263+
eprintln!("Can't parse delay in milliseconds");
264+
break;
265+
}
266+
} else {
267+
eprintln!(
268+
"A delay in milliseconds must be specified with the --startup-delay argument."
269+
);
270+
break;
271+
}
272+
},
244273
other => {
245274
eprintln!("Argument '{}' unknown", other);
246275
break;
247276
},
248277
}
249278
}
250279

280+
// Initialize the logger.
281+
logger::initialize(log_file.as_deref());
282+
283+
if let Some(file) = startup_notifier_file {
284+
let path = std::path::Path::new(&file);
285+
let (tx, rx) = unbounded();
286+
287+
if let Err(err) = (|| -> anyhow::Result<()> {
288+
let config = notify::Config::default()
289+
.with_poll_interval(std::time::Duration::from_millis(2))
290+
.with_compare_contents(false);
291+
292+
let mut watcher = notify::RecommendedWatcher::new(tx, config).unwrap();
293+
watcher.watch(path, notify::RecursiveMode::NonRecursive)?;
294+
295+
loop {
296+
let ev = rx.recv()?;
297+
match ev.unwrap().kind {
298+
notify::event::EventKind::Modify(_) => {
299+
break;
300+
},
301+
notify::event::EventKind::Remove(_) => {
302+
break;
303+
},
304+
_ => {
305+
continue;
306+
},
307+
}
308+
}
309+
310+
watcher.unwatch(path)?;
311+
Ok(())
312+
})() {
313+
eprintln!("Problem with the delay file: {:?}", err);
314+
}
315+
}
316+
317+
if let Some(delay) = startup_delay {
318+
std::thread::sleep(delay);
319+
}
320+
251321
// If the user didn't specify an action, print the usage instructions and
252322
// exit
253323
if !has_action {
254324
print_usage();
255325
return;
256326
}
257327

258-
// Initialize the logger.
259-
logger::initialize(log_file.as_deref());
260-
261328
// Register segfault handler to get a backtrace. Should be after
262329
// initialising `log!`. Note that R will not override this handler
263330
// because we set `R_SignalHandlers` to 0 before startup.

0 commit comments

Comments
 (0)