Skip to content

diag(web): instrument in-process open sequence to locate remaining #418 hang (1.3.8) - #421

Merged
zknpr merged 3 commits into
mainfrom
diag/418-instrument-web-open
Jun 1, 2026
Merged

diag(web): instrument in-process open sequence to locate remaining #418 hang (1.3.8)#421
zknpr merged 3 commits into
mainfrom
diag/418-instrument-web-open

Conversation

@zknpr

@zknpr zknpr commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Summary

Diagnostic build (1.3.8) — instrumentation only, not a fix.

The 1.3.7 in-process engine fix (#420) removed the worker-construction crash (new Worker(blobUrl) blocked by Trusted Types), confirmed in real vscode.dev: 1.3.7 loads, no TrustedScriptURL error. But databases still hang on the loading screen — a second, environment-specific stall in the sandboxed web extension host.

I can't pin it down by other means:

  • It does not reproduce locally — the real engine code runs the full open sequence (initializeDatabasefetchSchemafetchTableCountfetchTableData) against the real 8.6 MB test.db in a plain browser page in <20 ms.
  • It's invisible to DevTools/CDP — no error in any reachable console, no pending network request; the stall is inside the ext-host worker.

What this adds

Per-step logging around each await in the browser establishConnection:

  • ▶ loadDatabaseFiles … start / ✓ … ok (Nms)
  • ▶ readFile(sqlite3.wasm) … start / ✓ … ok
  • ▶ initializeDatabase (sql.js engine) … start / ✓ … ok

Output goes to the SQLite Explorer output channel (revealed automatically) and console (captured by the Extension Host (Worker) output channel), so we get the trace regardless of activation timing. The last start with no matching ok is the hanging call. Each step is wrapped so a thrown error surfaces as an error notification instead of an infinite spinner.

Not a behavior change

Desktop path untouched. The browser path logic is unchanged except for the logging wrappers. Bumps 1.3.7 → 1.3.8.

Verification

node scripts/build.mjs ✓ (browser bundle worker-free; diag marker present) · tsc --noEmit ✓ · npm test ✓ · existing workerFactory_browser.test.ts passes with the instrumentation in place.

Plan

Publish 1.3.8, open a DB in vscode.dev, read the output channel → the last logged step identifies the stalling call → real fix in a follow-up. This build will be superseded once the cause is found.

Refs #418.

Summary by CodeRabbit

  • New Features
    • Added comprehensive step-by-step diagnostic logging for web version operations, providing detailed visibility into database reading, WebAssembly file loading, and SQL engine initialization phases
    • Enhanced error handling with detailed error notifications that clearly display initialization failures along with timing and error details
  • Chores
    • Version bumped to 1.3.8

1.3.7 removed the worker-construction crash but databases still hang on the
loading screen in vscode.dev due to a second stall in the sandboxed web
extension host that does NOT reproduce locally (the engine + full open
sequence pass against the real test.db in a plain page) and is invisible to
DevTools/network inspection.

This adds per-step logging around each await in the browser establishConnection
(loadDatabaseFiles, readFile(sqlite3.wasm), initializeDatabase) to the SQLite
Explorer output channel AND console (captured by Extension Host (Worker)
output). The last '▶ … start' with no matching '✓ … ok' pinpoints the hanging
call; each step is wrapped so a thrown error surfaces as an error notification
instead of an infinite spinner.

Diagnostic only — no behavior change. Bumps 1.3.7 -> 1.3.8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sq-lite-explorer Ready Ready Preview, Comment Jun 1, 2026 8:12am

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@zknpr, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 31 minutes and 20 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79263437-d08d-4e15-b70d-2eaca5d53f54

📥 Commits

Reviewing files that changed from the base of the PR and between aac28fd and 8ca599c.

📒 Files selected for processing (1)
  • src/workerFactory.ts
📝 Walkthrough

Walkthrough

This release adds detailed diagnostic logging to the web/vscode.dev database initialization sequence to diagnose the remaining "loading hang" issue (#418). Each initialization phase—database read, WASM load, and engine init—is now instrumented with timing and error reporting. The version is bumped to 1.3.8, changelog and gitignore are updated accordingly.

Changes

Web Diagnostics Instrumentation & Release

Layer / File(s) Summary
Web diagnostics wrapper and instrumentation
src/workerFactory.ts
The establishConnection function wraps each async initialization phase (database file read, WASM byte load, SQL.js engine init) in a diagStep wrapper that logs "start/ok/FAILED" status with timing to GlobalOutputChannel and console, shows user error messages on failure, and re-throws errors.
Version and release coordination
package.json, CHANGELOG.md, .gitignore
Extension version bumped to 1.3.8, changelog entry added describing the new web diagnostics feature for issue #418, and _endpoint_bundle.mjs added to .gitignore to exclude the generated bundle from version control.

Sequence Diagram

sequenceDiagram
  participant establishConnection
  participant diagStep
  participant GlobalOutputChannel
  participant vscode.window
  participant endpoint
  
  establishConnection->>diagStep: diagStep("Open DB")
  diagStep->>GlobalOutputChannel: log "Open DB... start"
  diagStep->>endpoint: read database bytes
  endpoint-->>diagStep: bytes + timing
  diagStep->>GlobalOutputChannel: log "Open DB... ok"
  
  establishConnection->>diagStep: diagStep("Load WASM")
  diagStep->>GlobalOutputChannel: log "Load WASM... start"
  diagStep->>endpoint: load sqlite3.wasm
  endpoint-->>diagStep: wasm bytes
  diagStep->>GlobalOutputChannel: log "Load WASM... ok"
  
  establishConnection->>diagStep: diagStep("Init engine")
  diagStep->>GlobalOutputChannel: log "Init engine... start"
  diagStep->>endpoint: initializeDatabase()
  endpoint-->>diagStep: isReadOnly status
  diagStep->>GlobalOutputChannel: log "Init engine... ok (read-only: X)"
  
  Note over establishConnection,endpoint: On any failure: log FAILED + error to output channel, show vscode.window.showErrorMessage, re-throw
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • zknpr/SQLite-Explorer#420: Both PRs modify src/workerFactory.ts in the browser/in-process WASM createInProcessWasmDatabaseConnection/establishConnection flow for issue #418, adding/using in-process initialization so diagnostics and the connection setup align.

Poem

🐰 A bundle excluded, a version ascends,
Diagnostic steps log where the loading hangs end.
From database bytes to WASM so bright,
Each phase now shines with timing's own light.
Web Explorer hops forward with clarity's grace.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding diagnostic instrumentation to the in-process web open sequence to locate issue #418 hang, with version bump to 1.3.8.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch diag/418-instrument-web-open

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.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces diagnostic instrumentation to troubleshoot a web-only loading hang in VS Code for Web (vscode.dev). It adds logging and error handling around critical asynchronous steps during database connection establishment, specifically database file loading, WASM file reading, and database initialization. The review feedback suggests improving the diagStep helper's type signature to accept PromiseLike<T> instead of Promise<T>, which would allow passing VS Code's native Thenable objects directly and eliminate the need for manual Promise.resolve wrapping.

Comment thread src/workerFactory.ts Outdated
GlobalOutputChannel?.appendLine(line);
console.log(line);
};
const diagStep = async <T>(label: string, fn: () => Promise<T>): Promise<T> => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using PromiseLike<T> instead of Promise<T> in the fn signature allows the utility to accept both standard ES6 Promise objects and VS Code's Thenable objects (which are returned by VS Code workspace filesystem APIs) without requiring manual wrapping via Promise.resolve at the call sites.

Suggested change
const diagStep = async <T>(label: string, fn: () => Promise<T>): Promise<T> => {
const diagStep = async <T>(label: string, fn: () => PromiseLike<T>): Promise<T> => {

Comment thread src/workerFactory.ts Outdated
const wasmUri = vsc.Uri.joinPath(extensionUri, 'assets', 'sqlite3.wasm');
const wasmContent = await vsc.workspace.fs.readFile(wasmUri);
diag(` wasmUri=${wasmUri.toString()}`);
const wasmContent = await diagStep('readFile(sqlite3.wasm)', () => Promise.resolve(vsc.workspace.fs.readFile(wasmUri)));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

With diagStep updated to accept PromiseLike<T>, you can pass the Thenable returned by vsc.workspace.fs.readFile directly, removing the redundant Promise.resolve wrapper.

Suggested change
const wasmContent = await diagStep('readFile(sqlite3.wasm)', () => Promise.resolve(vsc.workspace.fs.readFile(wasmUri)));
const wasmContent = await diagStep('readFile(sqlite3.wasm)', () => vsc.workspace.fs.readFile(wasmUri));

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/workerFactory.ts`:
- Around line 225-229: The diag helper currently prints to console.log which
violates extension-host logging policy; update the diag function (the const diag
= (m: string) => { ... }) to stop calling console.log and route diagnostics only
through GlobalOutputChannel?.appendLine(line) (keep the existing line formatting
`[`#418` web-open] ${m}`), ensuring no other console.* calls remain in that
helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 518f2289-79a2-46e2-8756-6628548e18b1

📥 Commits

Reviewing files that changed from the base of the PR and between f16680a and aac28fd.

📒 Files selected for processing (4)
  • .gitignore
  • CHANGELOG.md
  • package.json
  • src/workerFactory.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build, typecheck & test
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.ts: Use prepared statements with ? placeholders for all query parameter values to prevent SQL injection
Always use escapeIdentifier() function for table and column names in SQL queries to prevent identifier-based SQL injection
Use validateSqlType() for all user-provided SQL types in DDL statements to prevent type-based SQL injection
Validate PRAGMA string values with the regex /^[a-zA-Z0-9_-]+$/ whitelist and check numeric PRAGMA values with Number.isFinite()
Use escapeLikePattern() for user input in LIKE queries with the ESCAPE '\\' clause to prevent LIKE wildcard injection
Use zero-copy transfer for large binary data (ArrayBuffers) in RPC communication by wrapping with the Transfer wrapper
Use SAVEPOINT/RELEASE/ROLLBACK TO instead of BEGIN TRANSACTION in updateCellBatch to safely handle nested transactions
Use the safeRollback(context) helper when handling transaction errors to log failures instead of throwing, preventing secondary rollback errors
Check for SQLite json_patch() availability at engine construction time and use it in UPDATE statements when available, falling back to JS-side applyMergePatch() when unavailable
Use getNodeFs() from sqlite-db.ts to safely require the Node.js fs module, which returns undefined in browser environments
Check import.meta.env.VSCODE_BROWSER_EXT to conditionally handle environment-specific code paths for browser vs Node.js platforms
Use the Core RPC protocol defined in src/core/rpc.ts for all Worker communication and when the Extension invokes Webview methods
Use buildMethodProxy() from src/core/rpc.ts to create proxy objects that automatically serialize RPC calls to workers or the webview
Record database modifications in ModificationTracker via recordModification() before committing changes to track undo/redo history
Write all executed SQL (both read and write operations) to the 'SQLite Explorer' output channel via GlobalOutputChannel?.appendLine() for debugging...

Files:

  • src/workerFactory.ts
{src/**/*.ts,core/ui/modules/*.js}

📄 CodeRabbit inference engine (CLAUDE.md)

Serialize Uint8Array using the marker format { __type: 'Uint8Array', base64: '...' } with exactly 2 keys to prevent collisions with user data

Files:

  • src/workerFactory.ts
🔇 Additional comments (3)
package.json (1)

6-6: LGTM!

CHANGELOG.md (1)

3-10: LGTM!

.gitignore (1)

40-40: LGTM!

Comment thread src/workerFactory.ts
Comment on lines +225 to +229
const diag = (m: string) => {
const line = `[#418 web-open] ${m}`;
GlobalOutputChannel?.appendLine(line);
console.log(line);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Route diagnostics through the output channel only

The new diagnostic logger writes to console.log on Line 228, which violates extension-host logging policy for this path. Keep diagnostics on GlobalOutputChannel?.appendLine() only.

Proposed change
       const diag = (m: string) => {
         const line = `[`#418` web-open] ${m}`;
         GlobalOutputChannel?.appendLine(line);
-        console.log(line);
       };

As per coding guidelines, "Use GlobalOutputChannel?.appendLine() instead of console.log in the extension host for all logging to ensure output appears in the 'SQLite Explorer' output channel".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const diag = (m: string) => {
const line = `[#418 web-open] ${m}`;
GlobalOutputChannel?.appendLine(line);
console.log(line);
};
const diag = (m: string) => {
const line = `[`#418` web-open] ${m}`;
GlobalOutputChannel?.appendLine(line);
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workerFactory.ts` around lines 225 - 229, The diag helper currently
prints to console.log which violates extension-host logging policy; update the
diag function (the const diag = (m: string) => { ... }) to stop calling
console.log and route diagnostics only through
GlobalOutputChannel?.appendLine(line) (keep the existing line formatting `[`#418`
web-open] ${m}`), ensuring no other console.* calls remain in that helper.

#421 review)

Applies Gemini's review feedback: typing diagStep's fn as PromiseLike<T>
lets VS Code's Thenable (from vsc.workspace.fs.readFile) pass directly, so
the Promise.resolve wrapper around the wasm readFile is removed. tsc clean.

Keeps the dual output-channel + console.log diagnostic logging
(CodeRabbit flagged the console.log): intentional for this throwaway
diagnostic build so the trace is captured by the 'Extension Host (Worker)'
output channel even if our own channel is not yet created at editor-open
time. Will be removed with the diagnostic once the hang is located.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zknpr

zknpr commented Jun 1, 2026

Copy link
Copy Markdown
Owner Author

Review feedback addressed (pushed in d3e76b6)

Thanks @gemini-code-assist, @coderabbitai.

✅ Applied — PromiseLike<T> in diagStep (Gemini, ×2)

Typed diagStep's fn as () => PromiseLike<T> so VS Code's Thenable (returned by vsc.workspace.fs.readFile) passes directly, and removed the now-redundant Promise.resolve(...) wrapper around the wasm read. tsc --noEmit clean.

⏭️ Keeping — dual console.log + output-channel logging (CodeRabbit, "Major")

Respectfully keeping the console.log for this diagnostic build only, deliberately against the usual "output channel only" guideline. Reason: this build exists to surface the open-sequence trace in vscode.dev, where our own "SQLite Explorer" output channel may not be created yet at editor-open time. In the web extension host, console.log is captured by the "Extension Host (Worker)" output channel, which is always available — so the dual log guarantees we capture the trace regardless of activation timing. The output-channel write (the canonical path) is still there too.

This is throwaway instrumentation — both the console.log and the whole diagStep block get removed once the hang is located and the real fix lands. I didn't want to weaken the diagnostic's reliability for a build whose entire purpose is to produce that one log line.

Verification

build ✓ (browser bundle worker-free; diag marker present) · tsc --noEmit ✓ · workerFactory_browser.test.ts ✓.

@gemini-code-assist

Copy link
Copy Markdown

Thank you for the update and for providing the context on why the console.log is necessary for this specific diagnostic build. Your reasoning regarding the potential unavailability of the GlobalOutputChannel during the early stages of editor activation in the web extension host is sound. Given that this is temporary instrumentation intended to isolate a specific, elusive hang, the approach of using both logging mechanisms is a pragmatic and effective way to ensure the trace is captured. I look forward to hearing the results of the diagnostic once you've had a chance to test it in the environment where the issue occurs.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@zknpr: Understood — the reasoning is solid. The "Extension Host (Worker)" channel being unconditionally available in the web extension host is exactly the right fallback when your own output channel's activation timing is uncertain, and for a single-purpose diagnostic build whose entire value is that one trace line, erring on the side of reliability makes complete sense. Happy to revisit the console.log guideline in the follow-up PR once the hang is pinned down and the instrumentation is removed.

Good luck with the reproduction on vscode.dev!

(ᴗ_ ᴗ。)


✏️ Learnings added
Learnt from: zknpr
URL: https://github.com/zknpr/SQLite-Explorer/pull/421

Timestamp: 2026-06-01T07:53:00.629Z
Learning: In SQLite Explorer (TypeScript VS Code extension), when adding diagnostic instrumentation for vscode.dev (web extension host), dual `console.log` + output-channel logging is intentional and acceptable. The reason: the extension's own "SQLite Explorer" output channel may not yet be created at editor-open time in the web extension host, but `console.log` is always captured by the built-in "Extension Host (Worker)" output channel. This dual logging pattern is only used in throwaway diagnostic builds and is removed once the issue is identified and fixed.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@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: d3e76b602b

ℹ️ 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 src/workerFactory.ts
};

const result = await endpoint.initializeDatabase(displayName, initConfig);
const result = await diagStep('initializeDatabase (sql.js engine)', () => endpoint.initializeDatabase(displayName, initConfig));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Instrument the post-connect RPC calls

This diagnostic stops once initializeDatabase resolves, but the web loading screen still performs additional awaited backend calls immediately afterward: core/ui/viewer.js awaits backendApi.ping() and then refreshSchema(), and restored views also await fetchTableCount/fetchTableData. In a vscode.dev hang in any of those calls, the last new trace will be establishConnection complete rather than an unmatched start, so this build will not identify the remaining #418 stall it was published to diagnose. Please wrap/log the browser ping, fetchSchema, fetchTableCount, and fetchTableData facade calls as well.

Useful? React with 👍 / 👎.

Comment thread src/workerFactory.ts Outdated
// There is no file-path fast path because the web extension host cannot
// access local disk paths directly.
const [dbContent, walContent] = await loadDatabaseFiles(fileUri);
const [dbContent, walContent] = await diagStep('loadDatabaseFiles', () => loadDatabaseFiles(fileUri));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Log the individual filesystem reads

If the vscode.dev stall is inside loadDatabaseFiles, this single wrapper only reports loadDatabaseFiles … start and does not distinguish the helper's separate stat, main database readFile, and optional -wal readFile awaits (loadDatabaseFiles later waits on both reads with Promise.all). In particular, a never-settling optional WAL read would make the database open hang even after the main DB bytes are available, but this diagnostic build would not identify that call. Please add nested browser-only diagnostics around those filesystem operations.

Useful? React with 👍 / 👎.

…421 Codex review)

Codex correctly flagged that the diagnostic would miss the actual #418 stall:

1. (P2) The trace stopped at initializeDatabase, but the loading screen then
   awaits ping -> fetchSchema -> fetchTableCount/fetchTableData (viewer.js). A
   hang in any of those would show 'establishConnection complete' then nothing,
   with no unmatched 'start'. Now the browser facade wraps ping, fetchSchema,
   fetchTableCount, fetchTableData, getTableInfo, getPragmas in diagStep too.

2. (P2) loadDatabaseFiles was a single wrapper hiding three awaits (stat, main
   readFile, optional -wal readFile via Promise.all). A never-settling -wal read
   over vscode-vfs would hang the open with no specific marker. loadDatabaseFiles
   now takes an optional diag callback and logs each fs op independently.

tsc clean; build worker-free; workerFactory_browser.test.ts passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@zknpr

zknpr commented Jun 1, 2026

Copy link
Copy Markdown
Owner Author

Codex feedback addressed (pushed in 8ca599c)

Thanks @codex — both findings were correct and would have defeated the purpose of this diagnostic. Fixed both:

✅ P2 — Instrument the post-connect RPC calls

You're right: the trace stopped at initializeDatabase, but the loading screen then awaits pingfetchSchemafetchTableCount/fetchTableData (viewer.js). A hang in any of those would have shown establishConnection complete then silence, with no unmatched start — exactly the signal this build needs. The browser operationsFacade now wraps ping, fetchSchema, fetchTableCount, fetchTableData, getTableInfo, and getPragmas in diagStep, so a stall in the read path is pinpointed too.

✅ P2 — Log the individual filesystem reads

Also correct, and this is the prime suspect. loadDatabaseFiles did stat + main readFile + optional -wal readFile (via Promise.all) under one wrapper. A never-settling -wal read over vscode-vfs would hang the open with no specific marker. loadDatabaseFiles now takes an optional diag callback and logs each fs op independently:
▶ fs.stat(db) / ▶ fs.readFile(db) / ▶ fs.readFile(-wal, optional), each with its own settle line.

Net effect: the full open path — stat, db read, wal read, wasm read, engine init, ping, schema, count, data — is now individually traced. The last unmatched ▶ … start names the stall.

Verification

tsc --noEmit ✓ · build worker-free (diag markers present) ✓ · workerFactory_browser.test.ts ✓.

@chatgpt-codex-connector

Copy link
Copy Markdown

Review Result

  • I reviewed the current PR head (8ca599c) and confirmed the two Codex P2 findings have been addressed.
  • No additional code changes were needed, so I did not create a commit or open a new PR.

Findings Verified

  • The post-connect read path is now instrumented: fetchTableData, fetchTableCount, fetchSchema, getTableInfo, getPragmas, and ping are wrapped with diagStep, so stalls after establishConnection complete should now produce an unmatched diagnostic start marker. src/workerFactory.tsL301-L319
  • loadDatabaseFiles now accepts an optional diagnostic callback and logs each filesystem await separately, including fs.stat(db), main database readFile, and optional -wal readFile. src/workerFactory.tsL556-L590
  • The earlier PromiseLike<T> cleanup is also present: diagStep accepts PromiseLike<T>, and the WASM readFile call is passed directly without a redundant Promise.resolve. src/workerFactory.tsL230-L257
  • The intentional dual output-channel plus console.log diagnostic logging remains documented in code for the temporary vscode.dev diagnostic build. src/workerFactory.tsL220-L228

Testing

  • npx tsc --noEmit
  • npx tsx --tsconfig tsconfig.test.json --test tests/unit/workerFactory_browser.test.ts
  • git status --short — working tree clean.

View task →

@zknpr
zknpr merged commit 24ec2da into main Jun 1, 2026
7 checks passed
@zknpr
zknpr deleted the diag/418-instrument-web-open branch June 1, 2026 08:29
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