재실행 시 백지+응답없음(SMB 소스) 수정 — 시작 시 워처/썸네일백필을 메인 스레드에서 분리

증상: SMB(네트워크) 소스 + 자료 많음 상태에서 재실행하면 창이 백지 + "응답 없음".
원인: setup()가 메인 스레드에서 watcher.refresh()를 동기 호출 → 각 로컬 소스에
debouncer.watch(경로, Recursive)를 등록하는데, 재실행 직후 SMB 공유가 느리거나
재연결 중이면 watch()가 블로킹 → 메인 스레드(이벤트 루프)가 멈춰 창이 안 그려짐.
(처음 열 땐 소스가 없어 no-op이라 정상이었고, 소스 추가는 워커 스레드에서 refresh해
안 멈췄음 — 재실행 때만 메인 스레드에서 SMB를 건드려 멈춤.)

수정: 워처 매니저는 즉시 등록하되 refresh(watch 등록)는 백그라운드 스레드로,
시작 썸네일 백필(enqueue_pending)도 백그라운드로 이동. setup()가 SMB를 동기로
건드리지 않으므로 창이 즉시 렌더되고 응답 유지.

검증(로컬): 소스 있는 상태 재실행 → 창 ~0.7초에 렌더(사이드바+그리드 30셀),
새 파일 추가 시 워처가 3초 내 감지해 재스캔(31셀). 회귀 없음.
(실제 SMB 블로킹은 로컬 재현 불가 — 메인 스레드에서 SMB를 건드리는 유일한 지점을 제거.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
강 한
2026-07-19 22:05:33 +09:00
co-authored by Claude Fable 5
parent 938b3b840e
commit ffa737be98
+28 -4
View File
@@ -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::<AppState>();
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::<AppState>();
if let Some(w) = state.watchers.get() {
w.refresh(&state.db);
}
})
.ok();
}
// 원격 소스 자동 재연결 (키체인 자격증명 기준 — 볼트는 잠금해제 후 수동).
{