Coordinate foreground search and background inference CPU budgets
This commit is contained in:
1 parent
6b78c8bb7f
commit
d85746db5b
12 files changed
+858
-60
No files matched your search
@@ -7,7 +7,7 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
const SETTINGS_VERSION: u32 = 1;
|
||||
const SETTINGS_VERSION: u32 = 2;
|
||||
const MAX_SETTINGS_BYTES: u64 = 128 * 1024;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
@@ -27,7 +27,7 @@ impl Default for Settings {
|
||||
Self {
|
||||
version: SETTINGS_VERSION,
|
||||
roots: Vec::new(),
|
||||
cpu_threads: 1,
|
||||
cpu_threads: 2,
|
||||
model_directory: None,
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ pub struct SettingsStore {
|
||||
|
||||
impl SettingsStore {
|
||||
pub fn load(path: PathBuf) -> Result<Self, String> {
|
||||
let value = match fs::metadata(&path) {
|
||||
let mut value = match fs::metadata(&path) {
|
||||
Ok(metadata) => {
|
||||
if metadata.len() > MAX_SETTINGS_BYTES {
|
||||
return Err("Settings file exceeds the size limit.".into());
|
||||
@@ -82,6 +82,15 @@ impl SettingsStore {
|
||||
Err(error) if error.kind() == std::io::ErrorKind::NotFound => Settings::default(),
|
||||
Err(error) => return Err(error.to_string()),
|
||||
};
|
||||
// Version 1 applied the value independently to both workers. Reserve
|
||||
// one background thread while retaining the old query allocation.
|
||||
if value.version == 1 {
|
||||
if !(1..=8).contains(&value.cpu_threads) {
|
||||
return Err("CPU threads must be between 1 and 8.".into());
|
||||
}
|
||||
value.version = SETTINGS_VERSION;
|
||||
value.cpu_threads = (value.cpu_threads + 1).min(8);
|
||||
}
|
||||
let store = Self { path, value };
|
||||
store.value.validate()?;
|
||||
Ok(store)
|
||||
@@ -126,7 +135,7 @@ mod tests {
|
||||
let directory = tempfile::tempdir().unwrap();
|
||||
let path = directory.path().join("settings.json");
|
||||
let mut store = SettingsStore::load(path.clone()).unwrap();
|
||||
assert_eq!(store.value.cpu_threads, 1);
|
||||
assert_eq!(store.value.cpu_threads, 2);
|
||||
store.add_root(directory.path()).unwrap();
|
||||
store.add_root(directory.path()).unwrap();
|
||||
let mut next = store.value.clone();
|
||||
@@ -175,6 +184,8 @@ mod tests {
|
||||
fs::write(&path, r#"{"version":1,"roots":[],"cpu_threads":1}"#).unwrap();
|
||||
let store = SettingsStore::load(path).unwrap();
|
||||
assert!(store.value.model_directory.is_none());
|
||||
assert_eq!(store.value.version, 2);
|
||||
assert_eq!(store.value.cpu_threads, 2);
|
||||
let invalid = Settings {
|
||||
model_directory: Some(PathBuf::from("relative")),
|
||||
..Settings::default()
|
||||
@@ -199,3 +210,22 @@ mod tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod budget_migration_tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn version_two_single_thread_is_explicit_and_invalid_legacy_budget_is_rejected() {
|
||||
let directory = tempfile::tempdir().unwrap();
|
||||
let path = directory.path().join("settings.json");
|
||||
fs::write(&path, r#"{"version":2,"roots":[],"cpu_threads":1}"#).unwrap();
|
||||
assert_eq!(
|
||||
SettingsStore::load(path.clone()).unwrap().value.cpu_threads,
|
||||
1
|
||||
);
|
||||
fs::write(&path, r#"{"version":1,"roots":[],"cpu_threads":9}"#).unwrap();
|
||||
assert!(SettingsStore::load(path.clone()).is_err());
|
||||
fs::write(&path, r#"{"version":1,"roots":[],"cpu_threads":8}"#).unwrap();
|
||||
assert_eq!(SettingsStore::load(path).unwrap().value.cpu_threads, 8);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user