diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index cef5538..2abb3af 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -103,8 +103,19 @@ fn main() { let _ = emit_handle.emit("thumbs-ready", ids); }, )); - // 앱 시작 시 미처리 썸네일 백필 - thumbs.enqueue_pending(&db, None); + // 앱 시작 시 미처리 썸네일 백필 — 백그라운드로. + // (대용량/네트워크(SMB) 소스에서 시작 시 메인 스레드 블로킹 방지) + { + let thumbs = thumbs.clone(); + let db = db.clone(); + std::thread::Builder::new() + .name("thumb-backfill".into()) + .spawn(move || { + archive_indexer::prio::set_current_thread_low(); + thumbs.enqueue_pending(&db, None); + }) + .ok(); + } #[cfg(debug_assertions)] tracing::info!( @@ -131,13 +142,26 @@ fn main() { )), }); - // 파일 워처: 등록된 로컬 소스 전체 감시 (AppState manage 이후에 초기화) + // 파일 워처: 매니저는 즉시 등록하되, 실제 watch() 등록은 백그라운드에서. + // SMB/네트워크 경로에서 watch()가 느리거나 블로킹될 수 있어 시작(메인 스레드)을 막지 않게 한다. + // (재실행 시 백지+응답없음 원인: 소스가 있는 상태에서 setup의 refresh가 SMB watch()로 멈춤) { let state = app.state::(); let manager = watcher::WatcherManager::new(app.handle().clone()); - manager.refresh(&state.db); let _ = state.watchers.set(manager); } + { + let handle = app.handle().clone(); + std::thread::Builder::new() + .name("watch-refresh".into()) + .spawn(move || { + let state = handle.state::(); + if let Some(w) = state.watchers.get() { + w.refresh(&state.db); + } + }) + .ok(); + } // 원격 소스 자동 재연결 (키체인 자격증명 기준 — 볼트는 잠금해제 후 수동). {