Skip to content

Commit

Permalink
Allow selecting a tick_rate for the debouncer
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpr03 committed Aug 6, 2022
1 parent 8158395 commit ffd2178
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
2 changes: 1 addition & 1 deletion examples/debounced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() {
}
});

let (rx, mut watcher) = new_debouncer(Duration::from_secs(2)).unwrap();
let (rx, mut watcher) = new_debouncer(Duration::from_secs(2), None).unwrap();

watcher
.watch(Path::new("."), RecursiveMode::Recursive)
Expand Down
45 changes: 34 additions & 11 deletions src/debouncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl EventData {
}
}

type DebounceChannelType = Result<Vec<DebouncedEvent>,Vec<Error>>;
type DebounceChannelType = Result<Vec<DebouncedEvent>, Vec<Error>>;

/// A debounced event kind.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -79,8 +79,10 @@ impl DebounceDataInner {
// TODO: perfect fit for drain_filter https://github.com/rust-lang/rust/issues/59618
for (k, v) in self.d.drain() {
if v.update.elapsed() >= self.timeout {
println!("normal timeout");
events_expired.push(DebouncedEvent::new(k, DebouncedEventKind::Any));
} else if v.insert.elapsed() >= self.timeout {
println!("continuous");
data_back.insert(k.clone(), v);
events_expired.push(DebouncedEvent::new(k, DebouncedEventKind::AnyContinuous));
} else {
Expand Down Expand Up @@ -116,24 +118,45 @@ impl DebounceDataInner {
}
}

/// Creates a new debounced watcher
/// Creates a new debounced watcher.
///
/// Timeout is the amount of time after which a debounced event is emitted or a Continuous event is send, if there still are events incoming for the specific path.
///
/// If tick_rate is None, notify will select a tick rate that is less than the provided timeout.
pub fn new_debouncer(
timeout: Duration,
tick_rate: Option<Duration>,
) -> Result<(Receiver<DebounceChannelType>, RecommendedWatcher), Error> {
let data = DebounceData::default();

let tick_div = 4;
let tick = match tick_rate {
Some(v) => {
if v > timeout {
return Err(Error::new(ErrorKind::Generic(format!(
"Invalid tick_rate, tick rate {:?} > {:?} timeout!",
v, timeout
))));
}
v
}
None => timeout.checked_div(tick_div).ok_or_else(|| {
Error::new(ErrorKind::Generic(format!(
"Failed to calculate tick as {:?}/{}!",
timeout, tick_div
)))
})?,
};

{
let mut data_w = data.lock().unwrap();
data_w.timeout = timeout;
}

let (tx, rx) = mpsc::channel();

let data_c = data.clone();
// TODO: do we want to add some ticking option ?
let tick_div = 4;
// TODO: use proper error kind (like InvalidConfig that requires passing a Config)
let tick = timeout.checked_div(tick_div).ok_or_else(|| {
Error::new(ErrorKind::Generic(format!(
"Failed to calculate tick as {:?}/{}!",
timeout, tick_div
)))
})?;

std::thread::Builder::new()
.name("notify-rs debouncer loop".to_string())
.spawn(move || {
Expand Down

0 comments on commit ffd2178

Please sign in to comment.