From efd1af13255e614559fbf037d23dc0ae46f2dbd4 Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Tue, 30 Jul 2019 13:38:06 +0900 Subject: Closes #544. (#607) Prepare for release 0.10.1 --- CHANGELOG.md | 8 ++++++++ Cargo.toml | 2 +- src/directory/directory.rs | 2 +- src/directory/managed_directory.rs | 2 +- src/directory/mmap_directory.rs | 33 +++++++++++++++++++++++++-------- src/directory/ram_directory.rs | 4 ++-- src/directory/tests.rs | 2 +- src/reader/mod.rs | 5 ++++- 8 files changed, 43 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f40ff2..2cf860c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ Tantivy 0.11.0 - Added f64 field. Internally reuse u64 code the same way i64 does (@fdb-hiroshima) +Tantivy 0.10.1 +===================== + +- Closes #544. A few users experienced problems with the directory watching system. +Avoid watching the mmap directory until someone effectively creates a reader that uses +this functionality. + + Tantivy 0.10.0 ===================== diff --git a/Cargo.toml b/Cargo.toml index 7fc6a58..a19f539 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tantivy" -version = "0.10.0" +version = "0.10.1" authors = ["Paul Masurel "] license = "MIT" categories = ["database-implementations", "data-structures"] diff --git a/src/directory/directory.rs b/src/directory/directory.rs index 8648ba1..3e786c2 100644 --- a/src/directory/directory.rs +++ b/src/directory/directory.rs @@ -204,7 +204,7 @@ pub trait Directory: DirectoryClone + fmt::Debug + Send + Sync + 'static { /// Internally, tantivy only uses this API to detect new commits to implement the /// `OnCommit` `ReloadPolicy`. Not implementing watch in a `Directory` only prevents the /// `OnCommit` `ReloadPolicy` to work properly. - fn watch(&self, watch_callback: WatchCallback) -> WatchHandle; + fn watch(&self, watch_callback: WatchCallback) -> crate::Result; } /// DirectoryClone diff --git a/src/directory/managed_directory.rs b/src/directory/managed_directory.rs index ea914a5..c33ff1b 100644 --- a/src/directory/managed_directory.rs +++ b/src/directory/managed_directory.rs @@ -241,7 +241,7 @@ impl Directory for ManagedDirectory { self.directory.acquire_lock(lock) } - fn watch(&self, watch_callback: WatchCallback) -> WatchHandle { + fn watch(&self, watch_callback: WatchCallback) -> crate::Result { self.directory.watch(watch_callback) } } diff --git a/src/directory/mmap_directory.rs b/src/directory/mmap_directory.rs index e19b430..afe90b8 100644 --- a/src/directory/mmap_directory.rs +++ b/src/directory/mmap_directory.rs @@ -161,7 +161,7 @@ impl InnerWatcherWrapper { } #[derive(Clone)] -pub(crate) struct WatcherWrapper { +struct WatcherWrapper { inner: Arc, } @@ -231,7 +231,7 @@ struct MmapDirectoryInner { root_path: PathBuf, mmap_cache: RwLock, _temp_directory: Option, - watcher: RwLock, + watcher: RwLock>, } impl MmapDirectoryInner { @@ -239,19 +239,36 @@ impl MmapDirectoryInner { root_path: PathBuf, temp_directory: Option, ) -> Result { - let watch_wrapper = WatcherWrapper::new(&root_path)?; let mmap_directory_inner = MmapDirectoryInner { root_path, mmap_cache: Default::default(), _temp_directory: temp_directory, - watcher: RwLock::new(watch_wrapper), + watcher: RwLock::new(None), }; Ok(mmap_directory_inner) } - fn watch(&self, watch_callback: WatchCallback) -> WatchHandle { - let mut wlock = self.watcher.write().unwrap(); - wlock.watch(watch_callback) + fn watch(&self, watch_callback: WatchCallback) -> crate::Result { + // a lot of juggling here, to ensure we don't do anything that panics + // while the rwlock is held. That way we ensure that the rwlock cannot + // be poisoned. + // + // The downside is that we might create a watch wrapper that is not useful. + let need_initialization = self.watcher.read().unwrap().is_none(); + if need_initialization { + let watch_wrapper = WatcherWrapper::new(&self.root_path)?; + let mut watch_wlock = self.watcher.write().unwrap(); + // the watcher could have been initialized when we released the lock, and + // we do not want to lose the watched files that were set. + if watch_wlock.is_none() { + *watch_wlock = Some(watch_wrapper); + } + } + if let Some(watch_wrapper) = self.watcher.write().unwrap().as_mut() { + return Ok(watch_wrapper.watch(watch_callback)); + } else { + unreachable!("At this point, watch wrapper is supposed to be initialized"); + } } } @@ -514,7 +531,7 @@ impl Directory for MmapDirectory { }))) } - fn watch(&self, watch_callback: WatchCallback) -> WatchHandle { + fn watch(&self, watch_callback: WatchCallback) -> crate::Result { self.inner.watch(watch_callback) } } diff --git a/src/directory/ram_directory.rs b/src/directory/ram_directory.rs index 53e7715..2ac8626 100644 --- a/src/directory/ram_directory.rs +++ b/src/directory/ram_directory.rs @@ -193,7 +193,7 @@ impl Directory for RAMDirectory { Ok(()) } - fn watch(&self, watch_callback: WatchCallback) -> WatchHandle { - self.fs.write().unwrap().watch(watch_callback) + fn watch(&self, watch_callback: WatchCallback) -> crate::Result { + Ok(self.fs.write().unwrap().watch(watch_callback)) } } diff --git a/src/directory/tests.rs b/src/directory/tests.rs index d249778..716fe94 100644 --- a/src/directory/tests.rs +++ b/src/directory/tests.rs @@ -121,7 +121,7 @@ fn test_watch(directory: &mut dyn Directory) { thread::sleep(Duration::new(0, 10_000)); assert_eq!(0, counter.load(Ordering::SeqCst)); - let watch_handle = directory.watch(watch_callback); + let watch_handle = directory.watch(watch_callback).unwrap(); for i in 0..10 { assert_eq!(i, counter.load(Ordering::SeqCst)); assert!(directory diff --git a/src/reader/mod.rs b/src/reader/mod.rs index cea65ca..ffd3305 100644 --- a/src/reader/mod.rs +++ b/src/reader/mod.rs @@ -85,7 +85,10 @@ impl IndexReaderBuilder { ); } }; - let watch_handle = inner_reader_arc.index.directory().watch(Box::new(callback)); + let watch_handle = inner_reader_arc + .index + .directory() + .watch(Box::new(callback))?; watch_handle_opt = Some(watch_handle); } } -- cgit v1.2.3