diff options
author | Daniel Schadt <kingdread@gmx.de> | 2020-05-01 22:12:00 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2020-05-01 22:12:00 +0200 |
commit | 0d1898ad881e05abf93c73fc8a13e4e5e5596335 (patch) | |
tree | 8cdcbb2c7f9dba7599020b1f5780349236706705 | |
parent | 4e02a34827b0ae3ef5eb957ab142f5a4c0ece301 (diff) | |
download | raidgrep-0d1898ad881e05abf93c73fc8a13e4e5e5596335.tar.gz raidgrep-0d1898ad881e05abf93c73fc8a13e4e5e5596335.tar.bz2 raidgrep-0d1898ad881e05abf93c73fc8a13e4e5e5596335.zip |
only cancel current search on Ctrl-C
This is not yet perfect, as it seems to still execute all queued threads
just to immediately exit them, so maybe we should try and see if we can
"clear" the rayon queue. But it's a good start, and the ctrlc crate
seems to work well for this job.
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 13 |
2 files changed, 14 insertions, 0 deletions
@@ -34,6 +34,7 @@ log = { version = "0.4", features = ["std"] } thiserror = "1.0" lalrpop-util = "0.18" rustyline = "6.1" +ctrlc = "3.1" [build-dependencies] lalrpop = { version = "0.18", features = ["lexer"] } diff --git a/src/main.rs b/src/main.rs index cb67968..61c332e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::{BufReader, Read, Seek}; use std::path::PathBuf; use std::str::FromStr; +use std::sync::atomic::{AtomicBool, Ordering}; use anyhow::{anyhow, Error, Result}; use chrono::{DateTime, TimeZone, Utc}; @@ -220,6 +221,10 @@ impl fmt::Display for InputError { impl std::error::Error for InputError {} +/// A flag that indicates whether the current search should be interrupted because the user pressed +/// Crtl-C. +static INTERRUPTED: AtomicBool = AtomicBool::new(false); + fn main() { let result = run(); if let Err(err) = result { @@ -290,11 +295,15 @@ fn single(opt: &Opt) -> Result<()> { } fn repl(opt: &Opt) -> Result<()> { + ctrlc::set_handler(|| INTERRUPTED.store(true, Ordering::Relaxed)) + .expect("Could not set interrupt hanlder"); + let mut rl = Editor::<()>::new(); loop { let line = rl.readline("Query> ")?; rl.add_history_entry(&line); let parsed = build_filter(&line); + INTERRUPTED.store(false, Ordering::Relaxed); match parsed { Ok(filter) => grep(&opt, &*filter)?, Err(err) => display_error(&err), @@ -333,6 +342,10 @@ fn grep(opt: &Opt, filter: &dyn LogFilter) -> Result<()> { for entry in walker { let entry = entry?; s.spawn(move |_| { + // Check first if we should even still continue + if INTERRUPTED.load(Ordering::Relaxed) { + return; + } if is_log_file(&entry) { let search = search_log(&entry, filter); match search { |