openBrowserWASQLiteOPFSDatabase() never settles while a frozen tab holds the database
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- sqlite, typescript, vite
Hướng nghiên cứu
Start with openBrowserWASQLiteOPFSDatabase() and opfs-database.ts, then trace the OPFSCoopSyncVFS hand-over and Web Lock wait. Review create(), open_v2, and handleWorkerRequest for cancellation and error propagation, using the frozen-tab reproduction as the first test case. Done means callers can bound or abort the open, late completion releases the database, and relevant errors remain distinguishable.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
- I've validated the bug against the latest version of DB packages
Describe the bug
If another tab has the database open and that tab is frozen, openBrowserWASQLiteOPFSDatabase() in a new tab never settles. The bundled OPFSCoopSyncVFS asks the current holder to hand over its access handles over a BroadcastChannel, then waits for the holder's Web Lock. A frozen tab can't answer. The open has no timeout or AbortSignal, so the caller can't give up and fall back to non-persisted sync. Anything waiting on the open, such as persisted collections reading their startup metadata, waits until the other tab thaws.
To Reproduce
A Vite app with @tanstack/[email protected] and [email protected]:
hang.html
<!doctype html>
<meta charset="utf-8" />
<title>Frozen holder repro</title>
<pre id="log">Opening…</pre>
<script type="module" src="./hang.js"></script>
hang.js
import { openBrowserWASQLiteOPFSDatabase } from "@tanstack/browser-db-sqlite-persistence";
// Tab A: load /hang.html and let it open the store. Freeze tab A, then load
// /hang.html in tab B. Tab B's open stays pending until tab A is thawed.
const log = document.querySelector("#log");
const started = performance.now();
const elapsed = () => `${((performance.now() - started) / 1000).toFixed(1)} s`;
const timer = setInterval(() => (log.textContent = `open pending for ${elapsed()}`), 250);
try {
const db = await openBrowserWASQLiteOPFSDatabase({ databaseName: "repro.sqlite" });
await db.execute("CREATE TABLE IF NOT EXISTS t (x)");
await db.execute("INSERT INTO t VALUES (1)");
log.textContent = `opened after ${elapsed()}`;
} catch (e) {
log.textContent = `failed after ${elapsed()}: ${e.name}: ${e.message}`;
}
clearInterval(timer);
- Open
/hang.htmlin tab A. It showsopened after 0.1 s. - Freeze tab A by sending the DevTools protocol command
Page.setWebLifecycleStatewith{"state": "frozen"}to it. - Open
/hang.htmlin tab B. It showsopen pending for 15.0 sand keeps counting. - Send
{"state": "active"}to tab A. Tab B showsopened after 15.1 s.
main at 4c5a8de, which includes #1844, behaves the same when I build its opfs-database.ts against the 0.2.23 worker. Freezing fires freeze, not pagehide, so the new cleanup never runs.
Expected behavior
A way to bound the wait, such as an AbortSignal or timeout option on openBrowserWASQLiteOPFSDatabase(), so the caller can fall back to non-persisted sync. An abandoned open that completes later should release the database rather than keep holding it.
Desktop:
- OS: Linux x86_64
- Browser: Chrome, headless, driven over CDP
- Version: 152.0.0.0
Additional context
- I forced the freeze over CDP and haven't pinned down which real-world freezes hold the lock this way. Mobile browsers suspend background tabs, and any holder that never answers the hand-over request blocks the open the same way.
- Our workaround races the open against a 2 s deadline, falls back to non-persisted semantics, and closes an open that lands after the deadline.
- A related gap: errors thrown while
OPFSCoopSyncVFS.create()runs still reach callers asOPFSWorkerRequestErrorwithcode: "INTERNAL"and only the message. #1844 adds the VFS cause toopen_v2failures, butcreate()runs outside thattry, andhandleWorkerRequestforwardserror.messagealone. Forwardingerror.nametoo would let callers tellNoModificationAllowedErrorcontention from other failures. The navigation failure that #1844 fixes arrived that way:Failed to execute 'removeEntry' on 'FileSystemDirectoryHandle'from the VFS's stale-directory sweep, reported upstream at rhashimoto/wa-sqlite#362.
- Ngôn ngữ chính
- TypeScript
- Star
- 3.9k
- Fork
- 267
- Merge trung bình
- 1 ngày 7 giờ
- Pull request đã merge (30 ngày)
- 123
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của TanStack/db
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 45/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 45/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
SerovalUnsupportedTypeError when TanStack Start SSR dehydrates an on-demand query collectionĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
Maintainer thường phản hồi trong vòng 1 ngày
-
MultiSet.consolidate merges keyed records whose keys or values differ only by number/string typeĐang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 76/100
TanStack/db#1948 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
lichess-org/api#678 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
PostHog/posthog.com#20628 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug status:Needs Triage
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
jupyterlab/jupyterlab#19964 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
agentscope-ai/QwenPaw#8064 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area: notebooks-jupyter bug theme: new notebook frontend
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
posit-dev/positron#16347 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày