Fixing connection with multiple hosts and unavailable replicas#579
Fixing connection with multiple hosts and unavailable replicas#579r-dmv wants to merge 3 commits intoaio-libs:masterfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #579 +/- ##
==========================================
+ Coverage 94.35% 94.41% +0.05%
==========================================
Files 27 27
Lines 3740 3780 +40
Branches 171 171
==========================================
+ Hits 3529 3569 +40
Misses 179 179
Partials 32 32 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| # If there is an error, we'll get it from poll. | ||
| self = weak_self() | ||
|
|
||
| if self._conn.status == CONN_STATUS_CONNECTING: |
There was a problem hiding this comment.
This occasionally fails due to self being None.
Minimal fix would be to skip the rest when that is the case,
but generally there shouldn't be active timers for a deleted object.
| # In socket.socket we should know type and family to shutdown socket by fd | ||
| # This function is used for shutdown libpq connection | ||
| # where family and type is unknown |
There was a problem hiding this comment.
What's the problem with just using the socket object?
|
Dmitry Rubtsov seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
What do these changes do?
Since PostgreSQL 10 it's possible to describe multiple hosts in connection string, it is useful when you have HA cluster of PostgreSQL with several replicas and you don't want to have some kind of balancer over your replicas.
And know it works in
aiopgif you're using libpq =< 10.But if there is a dead or unavailable replica in your connection string before your target host, exception is raised after timeout:
psycopg2.OperationalError: asynchronous connection attempt underway.It is also happens when you have host with multiple ip addresses in DNS, and first one is not responding.
You can simply reproduce this behavior by setting up 1 PostgreSQL server on 127.0.0.1:5432 and try to connect with connection string:
dbname=<db> user=<user> password=<password> host=8.8.8.8,127.0.0.1 port=5433,5432 target_session_attrs=read-write connect_timeout=1In sync psycopg2 connection it works properly, but this code:
raises
psycopg2.OperationalError: asynchronous connection attempt underway.This happens because libpq creates new connection, and closes failed, but we are waiting a failed one in
_pollmethod and fails after timeout.Are there changes in behavior for the user?
Now
aiopgusesconnect_timeoutparam fromdsn.It is used to timeout connection to the single host, in order to prevent getting stuck on connection to host which is not responding at all, even on first
SYNpacket.So now, if you have 3 hosts in your connection string, you should provide
connect_timeout=timeout / 3just as guarantee thataiopgwill try all 3 host during the timeout.You can also use
connect_timeoutinkwargs:Related issue number
#275
Checklist
CHANGESfolder<issue_id>.<type>(e.g.588.bugfix)issue_idchange it to the pr id after creating the PR.feature: Signifying a new feature..bugfix: Signifying a bug fix..doc: Signifying a documentation improvement..removal: Signifying a deprecation or removal of public API..misc: A ticket has been closed, but it is not of interest to users.Fix issue with non-ascii contents in doctest text files.