재실행 시 백지+응답없음(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:
+28
-4
@@ -103,8 +103,19 @@ fn main() {
|
|||||||
let _ = emit_handle.emit("thumbs-ready", ids);
|
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)]
|
#[cfg(debug_assertions)]
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
@@ -131,13 +142,26 @@ fn main() {
|
|||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
|
|
||||||
// 파일 워처: 등록된 로컬 소스 전체 감시 (AppState manage 이후에 초기화)
|
// 파일 워처: 매니저는 즉시 등록하되, 실제 watch() 등록은 백그라운드에서.
|
||||||
|
// SMB/네트워크 경로에서 watch()가 느리거나 블로킹될 수 있어 시작(메인 스레드)을 막지 않게 한다.
|
||||||
|
// (재실행 시 백지+응답없음 원인: 소스가 있는 상태에서 setup의 refresh가 SMB watch()로 멈춤)
|
||||||
{
|
{
|
||||||
let state = app.state::<AppState>();
|
let state = app.state::<AppState>();
|
||||||
let manager = watcher::WatcherManager::new(app.handle().clone());
|
let manager = watcher::WatcherManager::new(app.handle().clone());
|
||||||
manager.refresh(&state.db);
|
|
||||||
let _ = state.watchers.set(manager);
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
// 원격 소스 자동 재연결 (키체인 자격증명 기준 — 볼트는 잠금해제 후 수동).
|
// 원격 소스 자동 재연결 (키체인 자격증명 기준 — 볼트는 잠금해제 후 수동).
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user