Repository navigation
Conversation
Load each connection's snapshot under its own lock instead of holding the write lock of the whole snapshot map during network I/O. check verifies the distinct databases of all configuration files concurrently and reports every one it can't reach, with its address and the folders that use it.
This was referenced Oct 24, 2026
This was referenced Oct 26, 2026
…snapshot-loading # Conflicts: # crates/pgls_cli/tests/assert_check.rs
This branch has not been deployed
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.
Stacked on #915 → #992 → #991.
With nested configurations (#881), one project can point at several databases, and one bad one stalled everything (C8):
SnapshotManager::loadtook the write lock of the whole snapshot map and kept it whileSnapshot::loadran against the database. Until an unreachable database timed out (10 s by default), every snapshot lookup for every database waited, including cache hits, so hover, completions and diagnostics stalled in all projects of the language server.checkverified the databases one after the other and stopped at the first failure. Three unreachable databases withconnTimeoutSecs: 2took 6.15 s and reported one error,Database error: pool timed out while waiting for an open connection, without saying which database or which configuration.What changed
Per-connection lock. The map holds a slot per connection; the map lock is only taken to find or create the slot. The slot's mutex is held while that connection loads, so callers for the same database wait for one load instead of starting their own, and other databases aren't affected. A failed load leaves the slot empty for the next attempt, as before.
Concurrent check.
check_database_connectioncollects the distinct connections of the root and nested settings (by host, port, user, database, connection string, password and timeout), checks them on scoped threads, and returnserrors: Vec<String>instead oferror: Option<String>, one per database it can't reach:The CLI turns each into its own
database/connectiondiagnostic. The same three databases now take 2.07 s (one timeout) and all three are reported.Tests
check_reports_every_unreachable_database_at_once(Linux): three blackholed databases, each reported with its address and folder, in under 5 s.check_fails_when_database_login_failssnapshot now has the address prefix; the test output normalizes the address (it names the databasesqlx::testcreates) and the working directory.Not covered
errorsinstead oferror) has no TS counterpart; the type isn't exported to the JS bindings.Update: brought up to date with main and the reworked #915 (merge commits). Main had since added a check for an invalid
db.connectionStringtocheck_database_connection, which returned that one error; it now goes intoerrorslike the connection failures, once per distinct message. The LSP's refresh of inlay hints and semantic tokens, also new on main, checkserrors.is_empty(). No other changes.