Tauri v2의 Rust 비동기: 내가 겪은 문제와 해결법
Source: Dev.to
모든 테스트는 8년 된 MacBook Air에서 실행되었습니다.
모든 결과는 혼자서 7개의 Mac 앱을 배포한 경험을 바탕으로 한 것입니다. 스폰서된 의견이 아닙니다.
“스레드 간에 전달될 수 없음” 장벽
Tauri 개발에서 가장 흔히 마주치는 async 오류:
MutexGuard cannot be sent between threads safely
이는 .await 지점에서 락을 보유하고 있을 때 발생합니다. Tauri 명령은 Tokio 위에서 실행되며, await 지점에서 스레드가 전환될 수 있습니다. std::sync::Mutex의 MutexGuard는 Send가 아닙니다.
해결 방법: await 지점 사이에 상태를 보관해야 한다면 std::sync::Mutex 대신 tokio::sync::Mutex를 사용하거나, await 전에 가드를 해제하도록 구조를 바꾸세요.
// 잘못된 예 — await 앞뒤로 MutexGuard를 보유
async fn bad(state: State>) {
let guard = state.lock().unwrap();
some_async_call().await; // 여기서도 MutexGuard가 아직 살아있음
guard.do_something();
}
// 올바른 예 — await 전에 가드 해제
async fn good(state: State>) {
let value = {
let guard = state.lock().unwrap();
guard.get_value()
}; // 여기서 guard가 해제됨
some_async_call().await;
use_value(value);
}
async 명령 안에서의 블로킹 호출
rusqlite, 파일 I/O, 그 외 동기식 작업은 현재 스레드를 차단합니다. async 컨텍스트에서는 이 때문에 Tokio 스레드 풀 전체가 블로킹됩니다.
- 아주 짧은 작업(서브밀리초 수준)이라면 블로킹이 크게 문제되지 않습니다.
- 그보다 오래 걸린다면 전용 스레드 풀로 오프로드하세요:
let result = tokio::task::spawn_blocking(|| {
// 여기서 블로킹 작업 수행
do_something_slow()
}).await??;
spawn_blocking을 사용하면 async 런타임이 계속 반응성을 유지합니다.
장시간 작업과 진행 상황 업데이트
몇 초가 걸리는 작업(파일 동기화, 대용량 전송 등)에서는 프론트엔드에 진행 상황을 알려줘야 합니다. Tauri의 이벤트 시스템을 활용하세요:
#[tauri::command]
async fn sync_files(handle: AppHandle) -> Result {
for (i, file) in files.iter().enumerate() {
process_file(file).await?;
handle.emit("sync-progress", i).ok();
}
Ok(())
}
프론트엔드에서는 listen('sync-progress', …) 로 이벤트를 수신해 UI와 비동기 작업을 깔끔히 분리할 수 있습니다.
취소 가능한 작업을 위한 abort 패턴
사용자가 작업을 중단할 수 있으므로, 처음부터 취소 로직을 설계하세요:
let (tx, rx) = tokio::sync::oneshot::channel::();
tokio::spawn(async move {
tokio::select! {
_ = do_long_work() => { /* 작업 완료 */ }
_ = rx => { /* 취소됨 */ }
}
});
// 필요할 때 `tx`를 저장해 두었다가 보내면 취소됩니다
처음 설계에 취소 기능을 넣지 않은 장시간 작업에 나중에 끼워 넣는 것은 매우 고통스럽습니다. 가능한 한 초기에 설계에 포함시키세요.
결론
Tauri에서 Async Rust를 사용하려면 Send + Sync 규칙을 몸에 익히고, 어느 뮤텍스를 써야 하는지 알면 충분히 관리할 수 있습니다. 컴파일러 오류가 구체적이어서 방향을 제시해 줍니다.
위 패턴들은 실제 Tauri 앱을 배포하면서 마주하게 될 상황의 약 90 %를 커버합니다.
이 글이 도움이 되었다면, ❤️ 하나가 생각보다 큰 힘이 됩니다 — 감사합니다!
Hiyoko PDF Vault →
X →