-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Queued query errors #1503
Queued query errors #1503
Conversation
(Tests are failing because this is missing the changes for lib/native. Does it still offer a significant performance advantage, by the way?) |
Hi, just read your test case. Can you please test with two or more queries after the connection is downed? As reported in #1500 , the first query after the connection fails was already emitting an error. It was the second query that was locked forever. |
connection.emit('error', err) | ||
connection.emit('readyForQuery') | ||
return | ||
return new Error('A query must have either text or a name. Supplying neither is unsupported.') |
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.
Returning an error doesn't seem like a widely-used practice. Why are we not throwing it?
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.
It would have to be caught to be passed to the callback and it wouldn’t be easy to distinguish from other errors at that point.
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.
Now that you mention it, do we need to distinguish it from other errors? Reporting an error that occurred in the stack when calling Query.submit as a "query error" sounds rather intuitive.
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.
There shouldn’t be any other errors so I prefer not to treat those like they’re expected if they do occur.
@rkaw92 In your case, the connection was terminated between queries. In the test, the connection is terminated during the first query, and there is no subsequent |
lib/client.js
Outdated
@@ -389,25 +422,36 @@ Client.prototype.query = function (config, values, callback) { | |||
query._result._getTypeParser = this._types.getTypeParser.bind(this._types) | |||
} | |||
|
|||
if (!this._queryable) { | |||
query.handleError(new Error('Client has encountered a connection error and is not queryable'), this.connection) | |||
return |
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.
Returning undefined
causes breakage for Promise users when calling .query()
after the connection has gone down. Should return result
instead.
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.
Thanks!
Something is not quite right, still. Tested with my original gist:
It appears I was wrong in my initial assessment of the sequence of events in case the connection goes down (ends) between queries (
After your |
I think a user should be checking error codes if they expect certain types of errors and not sending a second query after the connection failed. The |
Nice. All queries are now receiving the same error in the scenario from my gist. |
@brianc, is the right way to implement this for pg-native to change https://github.com/brianc/node-pg-native/blob/25d12eb2a26d10a8c32036acf19253e131c266f5/index.js#L208 to a query error and all other errors to fatal errors? |
85969ea
to
9c2ba4b
Compare
@charmander - yah I think so. I know it's kinda a pain to have to go change something over in |
…-level errors Separates socket errors from error messages, sends socket errors to all queries in the queue, marks clients as unusable after socket errors. This is not very pleasant but should maintain backwards compatibility…?
This doesn’t match the original behaviour of the type errors, but it’s correct.
For brianc/node-postgres#1503. Not backwards-compatible (semver major).
9c2ba4b
to
57bd144
Compare
Guys, where are we on this? Any roadblocks? |
For brianc/node-postgres#1503. Not backwards-compatible (semver major).
@charmander I updated pg-native w/ the breaking change to emit errors more regularly here. Looks like the tests are still failing here for some reason. |
…e the same behaviour
705d89c
to
913a7e2
Compare
and do so in the native Client as well.
@brianc Tests fixed. Thanks for all the work today! |
Ah nice! I'll merge this tonight, put together a final release for the 7.x branch, and the major version bump for the small change to not being able to call |
👋Wanted to check in on progress of this PR. I've been following an issue around (#1105) and I think this PR might fix our issues we are seeing in production. When do you expect to merge this? Thanks! |
Conflicts: test/integration/connection-pool/error-tests.js
@brianc ^? |
@brianc What happened here? Why wasn't it merged? |
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.
Sometimes I fall off the edge of the earth. SO many github notification emails it's too hard to keep up. I apologize for letting this slip for so long. 😬 Merging & pushing a new minor version today.
Something makes me scratch my head in these changes.... It removed the process.nextTick(() => {
callback(err)
}) However, the internal method sets Line 181 in 3828aa8
And since the direct call was replaced to use |
yeah that might be possible - could you write a failing test for this? I'll fix it in a PR if you can reproduce. |
@brianc That's the known specific of race conditions, they are almost impossible to test in a controlled environment. I don't think I can create one, sorry. I can only logically deduct that such a situation can occur under a heavy load. Time will tell, just as people start upgrading... It would be a safe bet to return the check, that's for sure... process.nextTick(() => {
if(callback) {
callback(err)
}
}) https://github.com/brianc/node-postgres/blob/master/lib/client.js#L77 This would also make internal method |
I thought about this a bit more - I don't think its possible. Each call to |
and checking for |
Ok, I trust you this, but time will tell, if there is any issue there 😉 And in the second post you referred to what I was describing myself, but the issue I mentioned was that internally |
@brianc @vitaly-t Just did a quick reading of the function and it looks OK - generating the error and registering the handler for On the weird occasion that handlers for both |
I don’t know if this is how you want to handle the issue, but it should address #1454 and #632.
Maybe in a future version the query queue and clients pending
connect()
won’t need to exist at all?