fix(workspace): route Postgres-backed watch/update through the shared DB instead of local wiki.db - #2160
Open
Aman-goel-04 wants to merge 1 commit into
Conversation
… DB instead of local wiki.db
Aman-goel-04
requested review from
RaghavChamadiya and
swati510
as code owners
September 8, 2026 06:49
|
🔍 2 things to check
✅ Health of changed files: 3.3 → 3.5 (+0.1) ✅ Health gate: passed 👀 Suggested reviewers @RaghavChamadiya 📊 See the full report for this PR |
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.
Summary
reconcile_repo_head_commit, and_merged_repo_excludesinupdate.py. All four assumed a repo-local.repowise/wiki.dbas the "already indexed" signal, which never exists under a shared Postgres database, sorepowise watch --workspacefull-reindexed on every single file change instead of updating incrementally.reconcile_repo_head_commit's early return specifically: on Postgres,repositories.head_commit/updated_atwere never stamped after an update, which left the UI's "index behind checkout" warning and freshness timestamp permanently stuck even after a successful sync.create_engine()ashort_livedparameter (defaultTrue) so PostgreSQL usesNullPoolfor every short-lived engine (one connection per checkout, closed on dispose) instead of SQLAlchemy's defaultAsyncAdaptedQueuePool(up to 15 idle server slots per engine, and the failure class behind [Bug] Async PostgreSQL cleanup races with event-loop shutdown #2062, a pooled connection surviving past its creating event loop and getting handed to a later, unrelated caller). The two long-lived engines (FastAPI app, MCP server) opt out withshort_lived=Falseto keep pooled reuse across requests.Related Issues
Fixes #2148
Test Plan
pytest), full suite (tests/unit/,tests/providers/): 17528 passed, 4 pre-existing failures unrelated to this change (confirmed identical against a cleanmainviagit stash: an OS-path baseline test, a Python-version-dependent regex test, and a test hardcoding amasterbranch name).tests/unit/workspace/test_incremental_update.py+tests/unit/server/mcp/test_config.py: 19/19 passed.ruff check .)npm run build) (if frontend changes) — not applicable, Python-only changeManual reproduction (before fix): two disposable repos against a Docker
postgres:16instance viaREPOWISE_DB_URL. Confirmed Postgres held arepositoriesrow fortest-repowith a matchingstate.json.last_sync_commit, and no localwiki.db. Runningrepowise watch --workspace -vand editing a tracked file reliably producedtier=fullon every single-line change across dozens of edits.Regression tests added:
test_shared_db_indexed_repo_takes_incremental_path: a repo indexed in a configured shared DB (simulated with a file-backedsqlite+aiosqliteURL, no live Postgres required) takes the incremental path even with no localwiki.db. Fails onmainwithfull pipeline must not run for indexed repos.test_shared_db_config_drift_does_not_crash: combinesconfig_changed=Truewith the shared-DB/no-local-wiki.dbcase. Regression test for an ordering bug caught during self-review: an earlier version of this fix computedhas_persisted_indexafter the config-drift branch already read it, which would raiseUnboundLocalErrorthe moment a shared-DB repo's config actually drifted. The existingtest_config_drift_runs_full_reindexonly covers the local-SQLite case and never would have caught it.test_mcp_lifespan_uses_cli_database_env_varupdated to assert the MCP server's engine is created withshort_lived=False, locking in the long-lived opt-out so a future cleanup pass can't silently drop it.On the connection-leak half of #2148: I was not able to reproduce an accumulating leak (a rising floor between update cycles) from
watchalone, across ~65 cycles spanning sequential single-repo, sequential dual-repo, and forced-concurrent dual-repo edits against a live Postgres instance withserve+mcpalso running. Every observed connection spike drained back to baseline. This is consistent withfull_index.py's existingtry/finally: await engine.dispose()already disposing correctly on both the success and exception paths. Theshort_lived/NullPoolchange in this PR closes the mechanism regardless (an idle pooled connection can never be picked up by a later, unrelated caller after this change, since there's no pool to hold it), rather than relying on a leak having been empirically observed.Checklist
create_engine,reconcile_repo_head_commit, and_merged_repo_excludesupdated to describe the shared-DB behavior