Harden worker IPC and recoverable runtime staging
This commit is contained in:
1 parent
0bba1a0aa7
commit
b3ebd7a894
12 files changed
+1152
-75
No files matched your search
@@ -0,0 +1,44 @@
|
||||
//! Explicit data-directory isolation for portable use and native release QA.
|
||||
//! Ordinary launches continue to use the operating system's app-data directory.
|
||||
use std::{ffi::OsString, io, path::PathBuf};
|
||||
|
||||
pub fn resolve(default: PathBuf, override_path: Option<OsString>) -> io::Result<PathBuf> {
|
||||
let Some(value) = override_path else {
|
||||
return Ok(default);
|
||||
};
|
||||
let path = PathBuf::from(value);
|
||||
if !path.is_absolute() || path.as_os_str().len() > 32768 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"SEARCHI_DATA_DIR must be an absolute bounded directory path",
|
||||
));
|
||||
}
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn explicit_directory_isolates_settings_and_index_without_changing_default() {
|
||||
let default = std::env::temp_dir().join("searchi-default");
|
||||
let isolated = std::env::temp_dir().join("searchi-isolated");
|
||||
assert_eq!(resolve(default.clone(), None).unwrap(), default);
|
||||
assert_eq!(
|
||||
resolve(default, Some(isolated.clone().into_os_string())).unwrap(),
|
||||
isolated
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_override_is_rejected_without_falling_back_to_user_data() {
|
||||
let default = std::env::temp_dir().join("searchi-default");
|
||||
for value in [OsString::new(), OsString::from("relative/data")] {
|
||||
assert_eq!(
|
||||
resolve(default.clone(), Some(value)).unwrap_err().kind(),
|
||||
io::ErrorKind::InvalidInput
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
#[cfg(all(not(debug_assertions), not(feature = "custom-protocol")))]
|
||||
compile_error!("Release desktop builds require --features custom-protocol to embed the frontend");
|
||||
|
||||
mod ai_commands;
|
||||
mod data_directory;
|
||||
mod model_download;
|
||||
mod semantic_commands;
|
||||
mod settings;
|
||||
@@ -394,7 +398,10 @@ fn main() {
|
||||
}
|
||||
}).build())
|
||||
.setup(|app| {
|
||||
let directory = app.path().app_data_dir()?;
|
||||
let directory = data_directory::resolve(
|
||||
app.path().app_data_dir()?,
|
||||
std::env::var_os("SEARCHI_DATA_DIR"),
|
||||
)?;
|
||||
std::fs::create_dir_all(&directory)?;
|
||||
let database = directory.join("searchi.sqlite");
|
||||
let lexical = Arc::new(Mutex::new(SearchIndex::open(&database)?));
|
||||
@@ -413,15 +420,15 @@ fn main() {
|
||||
let development_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../..");
|
||||
let development_models = development_root.join(".searchi/models/embeddinggemma2");
|
||||
let bundled_models = app.path().resource_dir()?.join("embeddinggemma2");
|
||||
let model_directory = settings.value.model_directory.clone().unwrap_or_else(|| {
|
||||
if cfg!(debug_assertions) && development_models.is_dir() {
|
||||
development_models.canonicalize().unwrap_or(development_models)
|
||||
} else if bundled_models.is_dir() {
|
||||
bundled_models
|
||||
} else {
|
||||
searchi_assets::default_model_directory().unwrap_or_else(|_| directory.join("Models"))
|
||||
}
|
||||
});
|
||||
let model_directory = if let Some(configured) = settings.value.model_directory.clone() {
|
||||
configured
|
||||
} else if cfg!(debug_assertions) && development_models.is_dir() {
|
||||
development_models.canonicalize().unwrap_or(development_models)
|
||||
} else if searchi_assets::has_model_files(&bundled_models)? {
|
||||
bundled_models
|
||||
} else {
|
||||
searchi_assets::default_model_directory().unwrap_or_else(|_| directory.join("Models"))
|
||||
};
|
||||
let worker_name = if cfg!(windows) { "searchi-gemma-worker.exe" } else { "searchi-gemma-worker" };
|
||||
let development_worker = development_root.join(".searchi/runtime/cpu")
|
||||
.join(if cfg!(windows) { "Release" } else { "" }).join(worker_name);
|
||||
|
||||
Reference in new issue
Block a user