PlumeでTantivyのバージョンを上げたい
目標
課題
つまり非同期ランタイムを入れねばならない。
Slackのrust-jpで教えてもらったのだけど、smolっていう軽量な非同期ランタイムがあって、導入も手軽なので、これを入れるのはあり。 これが終わったら、何らかの形で非同期ランタイムは導入されているはずだし、自然に.awaitとか使えるはずなので、それを待つのがいい気がする。
というわけで、ここでの目標は、「garbage_collect_files()を、全部同期的なAPIだけで移行できるか調べる」ということになる。
調査
IndexWriter::garbage_collect_files()
code:src/indexer/index_writer.rs
/// Detects and removes the files that are not used by the index anymore.
pub fn garbage_collect_files(
&self,
) -> impl Future<Output = crate::Result<GarbageCollectionResult>> {
self.segment_updater.schedule_garbage_collect()
}
SegmentUpdater::schedule_garbage_collect()
code:src/indexer/segment_updater.rs
async fn garbage_collect_files(
segment_updater: SegmentUpdater,
) -> crate::Result<GarbageCollectionResult> {
info!("Running garbage collection");
let mut index = segment_updater.index.clone();
index
.directory_mut()
.garbage_collect(move || segment_updater.list_files())
}
SegmentUpdater::list_files()
はいいかな。呼べばいいだけだし。
Index::directory_mut()
&mut ManagedDirectoryを返す
ManagedDirectory::garbage_collect()
Result<GarbageCollectionResult>を返す
つまり非同期じゃない
これでいけそう。
アップグレード
Tantivyを0.12.0にしてビルドすると分かりやすい型のエラーが出るのでそれらは単純に直す。
最終的にこのエラーが出るのでこれが肝。
code:shell
% cargo clippy
Checking plume-models v0.4.0 (/home/kitaitimakoto/src/github.com/Plume-org/Plume/plume-models)
errorE0599: no method named map_err found for opaque type impl std::future::Future in the current scope --> plume-models/src/search/searcher.rs:140:14
|
140 | .map_err(|_| SearcherError::IndexEditionError)?;
| ^^^^^^^ method not found in impl std::future::Future
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope; perhaps add a use for it:
use futures_util::future::try_future::TryFutureExt;
error: aborting due to previous error
For more information about this error, try rustc --explain E0599.
error: could not compile plume-models.
To learn more, run the command again with --verbose.
調査結果に基づいて書き換えてみた。
code:diff
diff --git a/plume-models/src/search/searcher.rs b/plume-models/src/search/searcher.rs
index 12e8409..cfc1b37 100644
--- a/plume-models/src/search/searcher.rs
+++ b/plume-models/src/search/searcher.rs
@@ -135,8 +135,9 @@ impl Searcher {
let mut writer = index
.writer(50_000_000)
.map_err(|_| SearcherError::WriteLockAcquisitionError)?;
- writer
- .garbage_collect_files()
+ index
+ .directory_mut()
+ .garbage_collect(|| writer.segment_updater.list_files())
.map_err(|_| SearcherError::IndexEditionError)?;
Ok(Self {
writer: Mutex::new(Some(writer)),
が、エラー。
code:shell
% cargo clippy
Checking plume-models v0.4.0 (/home/kitaitimakoto/src/github.com/Plume-org/Plume/plume-models)
errorE0616: field segment_updater of struct tantivy::IndexWriter is private --> plume-models/src/search/searcher.rs:140:26
|
140 | .garbage_collect(|| writer.segment_updater.list_files())
| ^^^^^^^^^^^^^^^^^^^^^^
errorE0624: method list_files is private --> plume-models/src/search/searcher.rs:140:49
|
140 | .garbage_collect(|| writer.segment_updater.list_files())
| ^^^^^^^^^^
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0616, E0624.
For more information about an error, try rustc --explain E0616.
error: could not compile plume-models.
To learn more, run the command again with --verbose.
IndexWriterのsegment_updaterがプライベートだったので直接呼べない。
SegmentMeta::list_files()っていうのがあるからこれが使えないだろうか。
Index::list_all_segment_metas()っていうメソッドがあるからこれから辿れそう。
返す内容はSegmentUpdaterと一緒だろうか。
SegmentUpdater::list_files()
code:src/indexer/segment_updater.rs
/// List the files that are useful to the index.
///
/// This does not include lock files, or files that are obsolete
/// but have not yet been deleted by the garbage collector.
fn list_files(&self) -> HashSet<PathBuf> {
let mut files: HashSet<PathBuf> = self
.index
.list_all_segment_metas()
.into_iter()
.flat_map(|segment_meta| segment_meta.list_files())
.collect();
files.insert(META_FILEPATH.to_path_buf());
files
}
明らかに同じではない。
list_all_segment_metas()経由のファイルリストにMETA_FILEPATHが追加されてる。
これIndexにも実装されててほしいな・・・
しょうがないからコピーする
結果