feat: Add multihost support for native js driver#3643
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds multihost connection support to the pg native JavaScript driver's Connection class, enabling TCP-level failover across multiple hosts and PostgreSQL target_session_attrs session attribute filtering (e.g., read-write, read-only, primary, standby, prefer-standby).
Changes:
- Extended
Connection.connect()to accept arrays of hosts and ports, with automatic failover to the next host on TCP connection errors - Implemented
targetSessionAttrssupport that checks PostgreSQL backend parameters (in_hot_standby,default_transaction_read_only) after connection, with a fallback toSHOW/SELECTqueries when parameters aren't available viaParameterStatusmessages - Added comprehensive unit tests covering multihost failover, all
targetSessionAttrsmodes, and the SHOW query fallback mechanism
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
packages/pg/lib/connection.js |
Core multihost and targetSessionAttrs logic in the Connection class, including stream factory support, emit interception for session attribute checking, and the isHostMatchTargetSessionAttrs helper function |
packages/pg/lib/client.js |
Passes targetSessionAttrs config option through to the Connection constructor |
packages/pg/test/unit/connection/multihost-tests.js |
Unit tests for multihost connectivity, all targetSessionAttrs modes, fallback SHOW queries, and edge cases |
.gitignore |
Adds .history directory to gitignore |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ffce1e3 to
02f5146
Compare
|
@brianc @charmander hello! can u please check this PR |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
928c27d to
2778d49
Compare
2778d49 to
ca31ecf
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1fab7a1 to
3917365
Compare
|
@brianc @charmander hello! can u please check this PR |
3917365 to
aebfe47
Compare
charmander
left a comment
There was a problem hiding this comment.
I’m not sure if/when I’ll get the chance to give this a thorough review, but the changes to Connection look kind of messy. Is there a reason the logic can’t be something that operates on Connections?
7857655 to
cb7fb4a
Compare
cb7fb4a to
6471c21
Compare
|
@brianc hello! can u please check this PR |
will do now. sorry for delay 🙏 |
It introduces a bunch of state on
Are you thinking of |
|
It doesn't look like vibe code which is good! Looks like you put a lot of thought into this which I appreciate. I think I share some of the concerns @charmander has about it being a lot of additional stuff in connection. I'm kinda okay with it though at first glance. I'm pulling down the branch to open it in my editor to kinda "feel it" more. From my perspective what I'd like to see...though I'm really not sure of the feasibility of it...is there any way to have any integration tests for this? Where maybe you try to connect to several hosts, only one of them being valid in the tests? But actually connect to a backend? I would love it if we could have a docker compose setup w/ multiple postgres's that have failover and readonly settings and all that but that's probably a bit out of scope and wouldn't work great w/ local testing (unless one were to run docker for local testing). |
|
I believe that logic in On integration tests — I completely agree they'd be valuable, and I'm keen to dig into that. To do it properly we'd need to set up CI with a multi-node environment (something like Patroni with a primary and read replicas), which would take a bit of infrastructure work. I'm absolutely willing to spend time on that, but I'm conscious it could become a significant addition and risk blocking this PR. Would you be comfortable if I tackled that as a follow-up PR, so we don't inflate the scope and complexity here? |
yeah for sure. there are some tests covering it already, and all existing tests pass which are big first steps. I am still churning through my backlog of PRs and issues today, returning to computer, so I might not get to do a comprehensive dive until tomorrow. If you don't hear back sometime in the afternoon USA time please ping me at brian.m.carlson@gmail.com or get on the discord and ping me directly there. My inbox is an absolute nightmare of github notification emails and things can get lost in the shuffle, but I want to bring this over the finish line one way or another as its pretty big & I don't want to break it w/ merge conflicts. |
Summary
Behavior Changes
When host and port are arrays, the driver tries each host in order. TCP-level errors before the first successful connect silently trigger a retry on the next host. With targetSessionAttrs set, hosts that connect successfully but don't match the session requirement are also silently skipped. If the list is exhausted without a match, an error is emitted.
Problem
The pure JS driver previously only accepted a single host and had no targetSessionAttrs support, unlike the native libpq driver. This made it impossible to use driver for high-availability Postgres setups where you want to connect to whichever replica is currently the primary, or explicitly route to a read replica.
The lack of multihost support meant users had to implement their own failover logic outside the driver, or switch to the native bindings just to get this feature.
Related issues
#1470