Load model in parallel (#181)
This commit is contained in:
parent
61efe3cab8
commit
83970b0f44
2 changed files with 36 additions and 18 deletions
|
|
@ -28,6 +28,10 @@ impl ShortcutAction for TranscribeAction {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
debug!("TranscribeAction::start called for binding: {}", binding_id);
|
debug!("TranscribeAction::start called for binding: {}", binding_id);
|
||||||
|
|
||||||
|
// Load model in the background
|
||||||
|
let tm = app.state::<Arc<TranscriptionManager>>();
|
||||||
|
tm.initiate_model_load();
|
||||||
|
|
||||||
let binding_id = binding_id.to_string();
|
let binding_id = binding_id.to_string();
|
||||||
change_tray_icon(app, TrayIconState::Recording);
|
change_tray_icon(app, TrayIconState::Recording);
|
||||||
show_recording_overlay(app);
|
show_recording_overlay(app);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use anyhow::Result;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
use tauri::{App, AppHandle, Emitter, Manager};
|
use tauri::{App, AppHandle, Emitter, Manager};
|
||||||
|
|
@ -41,6 +41,8 @@ pub struct TranscriptionManager {
|
||||||
last_activity: Arc<AtomicU64>,
|
last_activity: Arc<AtomicU64>,
|
||||||
shutdown_signal: Arc<AtomicBool>,
|
shutdown_signal: Arc<AtomicBool>,
|
||||||
watcher_handle: Arc<Mutex<Option<thread::JoinHandle<()>>>>,
|
watcher_handle: Arc<Mutex<Option<thread::JoinHandle<()>>>>,
|
||||||
|
is_loading: Arc<Mutex<bool>>,
|
||||||
|
loading_condvar: Arc<Condvar>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TranscriptionManager {
|
impl TranscriptionManager {
|
||||||
|
|
@ -60,6 +62,8 @@ impl TranscriptionManager {
|
||||||
)),
|
)),
|
||||||
shutdown_signal: Arc::new(AtomicBool::new(false)),
|
shutdown_signal: Arc::new(AtomicBool::new(false)),
|
||||||
watcher_handle: Arc::new(Mutex::new(None)),
|
watcher_handle: Arc::new(Mutex::new(None)),
|
||||||
|
is_loading: Arc::new(Mutex::new(false)),
|
||||||
|
loading_condvar: Arc::new(Condvar::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start the idle watcher
|
// Start the idle watcher
|
||||||
|
|
@ -279,6 +283,26 @@ impl TranscriptionManager {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Kicks off the model loading in a background thread if it's not already loaded
|
||||||
|
pub fn initiate_model_load(&self) {
|
||||||
|
let mut is_loading = self.is_loading.lock().unwrap();
|
||||||
|
if *is_loading || self.is_model_loaded() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*is_loading = true;
|
||||||
|
let self_clone = self.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let settings = get_settings(&self_clone.app_handle);
|
||||||
|
if let Err(e) = self_clone.load_model(&settings.selected_model) {
|
||||||
|
eprintln!("Failed to load model: {}", e);
|
||||||
|
}
|
||||||
|
let mut is_loading = self_clone.is_loading.lock().unwrap();
|
||||||
|
*is_loading = false;
|
||||||
|
self_clone.loading_condvar.notify_all();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_current_model(&self) -> Option<String> {
|
pub fn get_current_model(&self) -> Option<String> {
|
||||||
let current_model = self.current_model_id.lock().unwrap();
|
let current_model = self.current_model_id.lock().unwrap();
|
||||||
current_model.clone()
|
current_model.clone()
|
||||||
|
|
@ -305,25 +329,15 @@ impl TranscriptionManager {
|
||||||
|
|
||||||
// Check if model is loaded, if not try to load it
|
// Check if model is loaded, if not try to load it
|
||||||
{
|
{
|
||||||
|
// If the model is loading, wait for it to complete.
|
||||||
|
let mut is_loading = self.is_loading.lock().unwrap();
|
||||||
|
while *is_loading {
|
||||||
|
is_loading = self.loading_condvar.wait(is_loading).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let engine_guard = self.engine.lock().unwrap();
|
let engine_guard = self.engine.lock().unwrap();
|
||||||
if engine_guard.is_none() {
|
if engine_guard.is_none() {
|
||||||
// Model not loaded, try to load the selected model from settings
|
return Err(anyhow::anyhow!("Model is not loaded for transcription."));
|
||||||
let settings = get_settings(&self.app_handle);
|
|
||||||
println!(
|
|
||||||
"Model not loaded, attempting to load: {}",
|
|
||||||
settings.selected_model
|
|
||||||
);
|
|
||||||
|
|
||||||
// Drop the guard before calling load_model to avoid deadlock
|
|
||||||
drop(engine_guard);
|
|
||||||
|
|
||||||
// Try to load the model
|
|
||||||
if let Err(e) = self.load_model(&settings.selected_model) {
|
|
||||||
return Err(anyhow::anyhow!(
|
|
||||||
"Failed to auto-load model '{}': {}. Please check that the model is downloaded and try again.",
|
|
||||||
settings.selected_model, e
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue