-
Notifications
You must be signed in to change notification settings - Fork 158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixing connection with multiple hosts and unavailable replicas #579
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
# 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
aiopg
if 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=1
In 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
_poll
method and fails after timeout.Are there changes in behavior for the user?
Now
aiopg
usesconnect_timeout
param 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
SYN
packet.So now, if you have 3 hosts in your connection string, you should provide
connect_timeout
=timeout / 3
just as guarantee thataiopg
will try all 3 host during the timeout.You can also use
connect_timeout
inkwargs
:Related issue number
#275
Checklist
CHANGES
folder<issue_id>.<type>
(e.g.588.bugfix
)issue_id
change 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.