Keep prepared search readers warm and verify abrupt indexing recovery
This commit is contained in:
1 parent
423a1ea57d
commit
6b78c8bb7f
17 files changed
+1011
-41
No files matched your search
@@ -25,6 +25,7 @@ pub struct SemanticState {
|
||||
downloaded_bytes: AtomicU64,
|
||||
error: Mutex<Option<String>>,
|
||||
service: Mutex<Option<HybridSearch>>,
|
||||
prepared_graphs: searchi_service::PreparedGraphs,
|
||||
media_tools: Option<searchi_media::FfmpegTools>,
|
||||
media_setup_error: Option<String>,
|
||||
}
|
||||
@@ -51,6 +52,7 @@ impl SemanticState {
|
||||
downloaded_bytes: AtomicU64::new(0),
|
||||
error: Mutex::new(None),
|
||||
service: Mutex::new(None),
|
||||
prepared_graphs: searchi_service::PreparedGraphs::default(),
|
||||
media_tools,
|
||||
media_setup_error,
|
||||
}
|
||||
@@ -76,6 +78,9 @@ impl SemanticState {
|
||||
let mut service =
|
||||
HybridSearch::open(database, &self.model_directory, &self.worker, threads)
|
||||
.map_err(|error| error.to_string())?;
|
||||
service
|
||||
.share_prepared_graphs(&self.prepared_graphs)
|
||||
.map_err(|error| error.to_string())?;
|
||||
service.warmup().map_err(|error| error.to_string())?;
|
||||
*self
|
||||
.service
|
||||
@@ -242,36 +247,15 @@ pub async fn index_embeddings(state: State<'_, AppState>) -> Result<EmbeddingRep
|
||||
threads,
|
||||
)
|
||||
.and_then(|mut service| {
|
||||
service.share_prepared_graphs(&semantic.prepared_graphs)?;
|
||||
let tools = semantic.media_tools.as_ref().ok_or_else(|| {
|
||||
anyhow::anyhow!("The media decoder is missing from this installation. Repair or reinstall searchi.")
|
||||
})?;
|
||||
service.index_embeddings_with_media(tools, &searchi_media::MediaLimits::default())
|
||||
})
|
||||
.map_err(|error| error.to_string());
|
||||
// Prepare the newly activated graph before advertising semantic readiness.
|
||||
// Keyword search stays available while the cached query session catches up.
|
||||
if result.is_ok() {
|
||||
semantic.warmed.store(false, Ordering::Release);
|
||||
semantic.warming.store(true, Ordering::Release);
|
||||
let _warming_guard = WorkGuard(&semantic.warming);
|
||||
let preparation = (|| {
|
||||
let mut cached = semantic
|
||||
.service
|
||||
.lock()
|
||||
.map_err(|_| "Semantic session is unavailable.".to_string())?;
|
||||
let service = cached
|
||||
.as_mut()
|
||||
.ok_or_else(|| "Semantic query session has not been prepared.".to_string())?;
|
||||
service.warmup().map_err(|error| error.to_string())
|
||||
})();
|
||||
semantic.warmed.store(preparation.is_ok(), Ordering::Release);
|
||||
if let Err(error) = preparation {
|
||||
semantic.record_error(Some(format!(
|
||||
"The index was saved, but search preparation failed: {error}"
|
||||
)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// The publisher shares its prepared immutable ANN before activation.
|
||||
// Keep the query model and its cached vectors warm throughout indexing.
|
||||
semantic.record_error(result.as_ref().err().cloned());
|
||||
result
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user