fix(sync): 修复 WebDAV 同步卡死(原 #781 的止血部分,不动云端格式) - #807
Open
codedogQBY wants to merge 2 commits into
Open
codedogQBY wants to merge 2 commits into
codedogQBY wants to merge 2 commits into
Conversation
During a sync the app froze: clicks stopped registering, opening a book did nothing, and the window eventually died. Three compounding causes: - Transfer progress was pushed to the store on EVERY chunk. With 3-5 concurrent transfers that sustains a synchronous React update storm on the renderer main thread (readest hit the same bug — their Sentry READEST-2 — and ships a progress throttle). Chunk progress is now throttled to one emit per 300ms per task; task start/completion still emit immediately. - Every DB write wrapped in runWithDbRetry waited up to 12s for a running sync to finish before even attempting the write (waitForSyncToSettle), so opening a book stalled for the full timeout. The settle wait is now capped at 1.5s — genuine SQLite lock contention is already handled by the retry loop itself. - applyChanges yielded the main thread only every 100 applied records; large remote snapshots could hog it for seconds between yields. Now every 25.
…ss the webview heap plugin-http serializes request bodies via Array.from(new Uint8Array(body)) into a JSON number array over IPC: every multi-megabyte book upload froze the renderer main thread for seconds and stalled the whole app during sync. Implement the desktop uploadFile/downloadFile platform methods as Tauri commands that stream directly between disk and the WebDAV server (reqwest on the tokio pool, 300s timeout, optional insecure-TLS). The per-book engine already prefers these entry points, so book/cover transfers now bypass the webview entirely and downloads report progress over an IPC channel (throttled by the engine's progress gate).
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
从 #781 拆出来的可安全验证部分,对应 #741(同步时应用整体卡死:点书籍无响应、菜单点不动、最终判未响应)。
为什么拆
#781 里其实是两件事,风险完全不一样:
/readany/sync/重传一次。第 2 件没法在现有书库上随手验(要动真实云端数据),所以先把第 1 件独立出来合掉。
改动(对应 #781 的前两个 commit,作者 @jenken827)
1. 桌面端缺的原生流式传输(卡死主因)
webdav-client.ts一直有platform.uploadFile / downloadFile快路径,但桌面端从来没实现过,所以每本 multi-MB 的书都走兜底路径:@tauri-apps/plugin-http把 body 变成Array.from(new Uint8Array(buffer))—— 千万级元素的 JS 数组,在渲染主线程上序列化,单次阻塞数秒。本 PR 补上 Tauri 侧实现:新增 Rust 命令
webdav_upload_file/webdav_download_file(reqwest,tokio 线程池里直接在磁盘与服务器之间流式读写,字节不进 webview 进程,进度经 IPC Channel 上报)。2. 响应性止血
waitForSyncToSettle上限 12s → 1.5s —— 这是「同步时点书打不开」的直接原因(同步期间任何 DB 写入先空等最多 12 秒);applyChanges每 25 行让出一次主线程。为什么这个能验
device-*.json布局照旧,不需要清空远端、不需要重新全量同步;验证
已跑:
pnpm --filter @readany/core test— 81 files / 598 passedpnpm --filter app exec tsc --noEmit— cleancargo check(packages/app/src-tauri)— cleantauri-platform-service.ts的 import 与当前 main 的import type写法对齐(1 行)待真机验证(桌面端 + WebDAV):
与 #781 的关系
#781 剩余的三个 commit(按书同步引擎 + 可配置并发 + 单条目容错)保留在 #781 继续推进,那部分要单独排一次「清空远端重同步」的验证。