Skip to content

test: [YW-266] stabilize native-DB-concurrency test flakes (WsManager + mapping-store)#147

Merged
youhaowei merged 2 commits into
mainfrom
charixandra/yw-266-stabilize-native-db-test-flakes
Jun 17, 2026
Merged

test: [YW-266] stabilize native-DB-concurrency test flakes (WsManager + mapping-store)#147
youhaowei merged 2 commits into
mainfrom
charixandra/yw-266-stabilize-native-db-test-flakes

Conversation

@youhaowei

@youhaowei youhaowei commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Problem

Two native-DB (PGlite/WASM) test races ate CI re-runs across unrelated PRs this cycle (e.g. #138 hit the mapping-store flake despite touching zero server-core files). They are a class, not one test:

  1. @wystack/client WsManager > does not reconnect on close code 4001 — original report.
  2. @wystack/server-core mapping-store.test.ts > DrizzleMappingStore > get returns the record written by set — flaked on a PR touching zero server-core files; 53s file duration = native-DB timing contention.

Both are test-setup races, fixed at the mechanism level — no test.retry(), no bare timeout bumps to mask the race.

Fixes

server-core — vitest.config.ts (this repo)

vitest 4.x runs all five server-core test files in parallel forks. Every file spins up PGlite (WASM Postgres), so they cold-start the WASM module simultaneously and contend for FDs/memory on a loaded runner. The first test in each file runs before any warm-up query, so it's the victim. Serialize the suite (maxWorkers: 1 / minWorkers: 1) so files cold-start one at a time. Tests are I/O-bound — small wall-clock cost.

client / WsManager — wystack submodule bump

ws.test.ts leaked ~12 PGlite WASM instances (sync afterEach never closed them), squeezing the 2500ms-sleep no-reconnect tests against the 5s bun timeout. The submodule commit adds a tracked-handle registry drained in an async afterEach, plus timeout headroom. Detail in youhaowei/wystack#46.

Verification

De-flake proven by looped local runs (a single green run does not prove a flake fixed):

  • mapping-store.test.ts: 20/20 pass, 0 fail
  • ws.test.ts (submodule): 20/20 pass, 0 fail
  • Full server-core suite (maxWorkers:1): 70 passed, 1 todo
  • typecheck + lint clean (DashFrame + wystack)

Submodule sequencing

The libs/wystack pointer references the YW-266 branch commit so CI runs green against the fix now. Re-point to the merged wystack main commit before merging this PR (depends on youhaowei/wystack#46).

Tracked internally as YW-266.

🤖 Generated with Claude Code

Greptile Summary

This PR stabilizes two recurring CI flakes caused by PGlite/WASM test-setup races — no retries or timeout masking. Both fixes target the mechanism: serializing the server-core vitest worker pool so five PGlite files no longer cold-start simultaneously, and bumping the wystack submodule to pick up an async afterEach that properly drains leaked WASM handles in ws.test.ts.

  • packages/server-core/vitest.config.ts: adds maxWorkers: 1 / minWorkers: 1 with a detailed comment; forces sequential file execution and eliminates the FD/memory contention that caused the first test in each file to be the flake victim.
  • libs/wystack: advances the submodule pointer to the wystack YW-266 branch commit (4bed431) which adds a tracked-handle registry drained via async afterEach; the PR description explicitly notes this must be re-pointed to the merged main SHA before merging.

Confidence Score: 5/5

Safe to merge once the wystack submodule is re-pointed to the merged main commit as documented.

Both changes are targeted and low-risk: the vitest config serializes existing test files (no production code touched), and the submodule bump only affects test infrastructure. The pre-merge gate (re-pointing the submodule to wystack main after wystack#46 merges) is clearly documented in the PR description and acknowledged by the author.

No files require special attention beyond the documented pre-merge step of re-pointing libs/wystack to the merged wystack main SHA.

Important Files Changed

Filename Overview
packages/server-core/vitest.config.ts Adds maxWorkers: 1 / minWorkers: 1 to serialize PGlite-based test files and eliminate WASM cold-start contention; well-commented and correct.
libs/wystack Submodule pointer bumped from 6b5f7c1 to 4bed431 (wystack YW-266 branch) to pick up the async afterEach PGlite handle drain fix; intentionally on a pre-merge branch SHA per PR description.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[CI: server-core test run] --> B{Before fix\nmaxWorkers default}
    B --> C[Fork 1: mapping-store.test.ts\nPGlite WASM cold-start]
    B --> D[Fork 2: other.test.ts\nPGlite WASM cold-start]
    B --> E[Fork 3: ...\nPGlite WASM cold-start]
    C & D & E --> F[Contend for FDs/memory\non loaded CI runner]
    F --> G[First test in each file\nflakes / times out]
    A2[CI: server-core test run] --> B2{After fix\nmaxWorkers: 1}
    B2 --> H[Fork 1: mapping-store.test.ts\nPGlite WASM cold-start]
    H --> I[Fork 1 done]
    I --> J[Fork 2: other.test.ts\nPGlite WASM cold-start]
    J --> K[... sequential ...]
    K --> L[All tests pass]
    style G fill:#f88,stroke:#c00
    style L fill:#8f8,stroke:#0c0
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[CI: server-core test run] --> B{Before fix\nmaxWorkers default}
    B --> C[Fork 1: mapping-store.test.ts\nPGlite WASM cold-start]
    B --> D[Fork 2: other.test.ts\nPGlite WASM cold-start]
    B --> E[Fork 3: ...\nPGlite WASM cold-start]
    C & D & E --> F[Contend for FDs/memory\non loaded CI runner]
    F --> G[First test in each file\nflakes / times out]
    A2[CI: server-core test run] --> B2{After fix\nmaxWorkers: 1}
    B2 --> H[Fork 1: mapping-store.test.ts\nPGlite WASM cold-start]
    H --> I[Fork 1 done]
    I --> J[Fork 2: other.test.ts\nPGlite WASM cold-start]
    J --> K[... sequential ...]
    K --> L[All tests pass]
    style G fill:#f88,stroke:#c00
    style L fill:#8f8,stroke:#0c0
Loading

Reviews (3): Last reviewed commit: "chore: re-point libs/wystack to main (YW..." | Re-trigger Greptile

@linear-code

linear-code Bot commented Jun 17, 2026

Copy link
Copy Markdown

YW-266

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Updates the libs/wystack git submodule to a new commit and modifies packages/server-core/vitest.config.ts to force test execution to a single worker (maxWorkers: 1, minWorkers: 1) with comments noting the constraint is for PGlite (WASM) integration tests on CI.

Changes

CI and Test Configuration

Layer / File(s) Summary
Vitest single-worker constraint
packages/server-core/vitest.config.ts
Adds maxWorkers: 1 and minWorkers: 1 with explanatory comments to serialize PGlite-bound integration test execution and avoid parallel cold-start contention on CI.
wystack submodule bump
libs/wystack
Advances the submodule pointer from one commit SHA to another.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: stabilizing native-DB-concurrency test flakes in WsManager and mapping-store via Vitest config and submodule updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering problem statement, fixes, verification details, and important pre-merge requirements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@youhaowei youhaowei force-pushed the charixandra/yw-266-stabilize-native-db-test-flakes branch from c3854eb to f4d8486 Compare June 17, 2026 14:25
Comment thread libs/wystack Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3854eb69b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread libs/wystack Outdated
Comment thread packages/server-core/vitest.config.ts Outdated
@youhaowei youhaowei force-pushed the charixandra/yw-266-stabilize-native-db-test-flakes branch from f4d8486 to 582c24f Compare June 17, 2026 19:51
… + mapping-store)

Two native-DB (PGlite/WASM) test races that ate CI re-runs across unrelated
PRs this cycle. Fixed at the mechanism level — no test.retry(), no bare
timeout bumps to mask the races.

server-core (mapping-store flake):
  vitest 4.x runs all five server-core test files in parallel forks. Every
  file spins up PGlite (WASM Postgres), so they cold-start the WASM module
  simultaneously and contend for file descriptors and memory on a loaded CI
  runner. The first test in each file — "mapping-store > get returns the
  record written by set" — was the most frequent victim because it runs
  before any warm-up query. Serialize the suite (maxWorkers/minWorkers 1) so
  the files cold-start one at a time. The tests are I/O-bound, so the
  wall-clock cost is small.

client / WsManager (the original report) is fixed in the wystack submodule
  bump: ws.test.ts leaked ~12 PGlite WASM instances (sync afterEach never
  closed them), squeezing the 2500ms-sleep no-reconnect tests against the 5s
  bun timeout. The submodule commit adds a tracked-handle registry drained in
  an async afterEach plus timeout headroom. See wystack PR for detail.

De-flake verified locally, each file run 20x with 0 failures:
  - server-core mapping-store.test.ts: 20/20 pass
  - client ws.test.ts (submodule): 20/20 pass

NOTE: submodule points at the wystack YW-266 branch commit; re-point to the
merged wystack main commit before merging this PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@youhaowei youhaowei force-pushed the charixandra/yw-266-stabilize-native-db-test-flakes branch from 582c24f to f91dade Compare June 17, 2026 19:52
… fix)

The submodule was pinned to the YW-266 PR-branch commit (6bd39da, parent
6b5f7c1) which predated YW-120. Re-point to wystack main 4bed431b, which
includes both YW-120 (#45) and YW-266 (#46).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@youhaowei youhaowei merged commit e67e8c7 into main Jun 17, 2026
6 checks passed
@youhaowei youhaowei deleted the charixandra/yw-266-stabilize-native-db-test-flakes branch June 17, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant