sqlite-persistence: leader term write on every page load delays reading rows
Maintainer thường phản hồi trong vòng 1 ngày
Một pull request liên quan đã được merge.
- #2219 của @KyleAMathews — đã merge
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 50/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
- Lĩnh vực
- database, performance
Hướng nghiên cứu
Start in BroadcastCollectionCoordinator, where the issue says collection election and term reservation occur, and trace subscribe through ensureCollectionState to acquireLeadership. Then follow the listed route waits and first-read completion path to see where ensureLeadership could start election; compare the two described patch shapes. Done means rows can be read before an eager collection reserves its term, while route waits still trigger election and terms, locks, and heartbeats retain their behavior.
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
Every page load, each persisted collection starts leader election as soon as it subscribes (subscribe → ensureCollectionState → acquireLeadership) and reserves a new term, a durable write, even though nothing has asked for a leader yet. On the browser OPFS adapter the driver runs one operation at a time and a transaction counts as one, so the term transaction sits in the queue ahead of the rows being read. Eager collections don't need a leader to read their rows, so this is time spent waiting on a write they don't use yet.
Trace of one collection's term on a reload (start ms, duration ms):
181.1 0.9 BEGIN IMMEDIATE
182.0 0.6 SELECT schema_version FROM collection_registry …
182.6 3.9 INSERT INTO leader_term (collection_id, latest_term) VALUES (?, ? + 1) ON CONFLICT …
186.5 0.4 SELECT latest_term FROM leader_term …
186.6 0.4 SELECT MAX(seq) AS max_seq FROM applied_tx …
186.6 0.6 SELECT latest_row_version FROM collection_version …
187.2 5.0 COMMIT
192.2 0.7 BEGIN IMMEDIATE
193.1 0.4 SELECT key, value, metadata, row_version FROM "c_qvzbpr_8"
That's about 11 ms for this collection, and every collection pays it before its rows are read.
To reproduce
@tanstack/browser-db-sqlite-persistence0.2.36,@tanstack/db-sqlite-persistence-core0.4.11- OPFS database, 8 persisted collections (
syncMode: "eager",schemaVersion: 1,BrowserCollectionCoordinator), all preloaded at once, fill them once, reload - Log the database's
executecalls
Expected behavior
Start a collection's election the first time it needs a leader instead of when it subscribes: when its first read finishes, or when something waits for a route (requestEnsureRemoteSubset, requestApplyCommittedTx, requestApplyLocalMutations, reconcileCommittedTx). Terms, locks and heartbeats stay as they are, only the timing changes.
Every route wait would need to start the election through ensureLeadership, or a single tab could wait for a leader that never gets elected. A first write would then wait for the read plus the term instead of just the term, a few ms.
A second option: keep electing at subscribe, but send the term write through the shared scheduler, so it waits behind reads that are already queued. I'm less sure of this one. A comment in main says election skips the scheduler on purpose, because a hydrate can be waiting for its first writer route. If the term write queued behind that hydrate, each would wait for the other. My test has no remote sync, so it never hit that case. The first option avoids it.
Numbers
Both shapes take 18–26 ms off the time until the first three collections have read their rows from disk, and both keep every term write.
I tried both as small patches to BroadcastCollectionCoordinator: one starts a collection's election once its first read finishes, the other runs reserveLeadershipTerm through adapter.runInRegularScope. Headless Chromium, 8 collections, 3 runs of 15 reloads, all variants alternating. Medians in ms from creating the collections until their rows were read.
First 3 collections read:
| Run | Election after first read | Term through the scheduler |
|---|---|---|
| 1 | 134 → 108 (−26) | 134 → 113 (−21) |
| 2 | 133 → 110 (−23) | 133 → 107 (−26) |
| 3 | 129 → 110 (−19) | 129 → 111 (−18) |
All 8 read:
| Run | Election after first read | Term through the scheduler |
|---|---|---|
| 1 | 234 → 213 (−21) | 234 → 224 (−10) |
| 2 | 237 → 228 (−9) | 237 → 214 (−23) |
| 3 | 234 → 214 (−20) | 234 → 215 (−19) |
Desktop
Headless Chromium 141 on Linux.
Additional context
Related to #2204, which is about the table setup each collection runs on the same path.
Happy to send a PR with an oracle test if you want this.
- Ngôn ngữ chính
- TypeScript
- Star
- 3.9k
- Fork
- 277
- Merge trung bình
- 18 giờ 12 phút
- Pull request đã merge (30 ngày)
- 229
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ó 4/5 1-2 ngày Mức phù hợp với người mới 48/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Ordered-replay oracle: terminal error after a failed settle following truncate markersCó thể đã có người làm @KyleAMathews đã nhận hôm nay. Đang mở
Độ khó 4/5 3-5 ngày 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
-
Độ 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
-
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 58/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 48/100
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
createAI: the ai peer range allows ai@6, which the provider cannot work withCó thể đã có người làm @akhil9tiet đã nhận hôm nay. Đang mởbug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 83/100
cloudflare/agents#2690 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[fullsend] E2E: theme — global-header ignores app.branding.fullLogo (RHDHBUGS-3670)Có thể đã có người làm @fullsend-ai-coder đã nhận hôm nay. Đang mởe2e-failure ready-to-code
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
redhat-developer/rhdh-plugin-export-overlays#4503 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
needs triage 📥
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 86/100
ethereum/ethereum-org-website#19601 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: Circular app layout navigation and help icons are shifted upward in the official demoĐang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
cloudscape-design/components#5184 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
agilepathway/label-checker#805 ·
Maintainer thường phản hồi trong vòng 1 ngày