Skip to content
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

Ensure connect callback is invoked on premature socket hangup #546

Merged
merged 6 commits into from Apr 6, 2014

Conversation

strk
Copy link
Contributor

@strk strk commented Mar 18, 2014

Closes #534
Applies to 2.11.1, only really fixes the case with node-0.10, 0.8 is still being researched upon.
Deprecates pull #542

Sandro Santilli added 2 commits March 18, 2014 13:19
Test adapted by that provided by Jess Sheneberger in brianc#534
This time, I hope, travis will confirm that the fix works with
node-0.10 but not with node-0.8
@strk
Copy link
Contributor Author

strk commented Mar 18, 2014

Confirmation of this change fixing the bug for node-0.10 but not for node-0.8: https://travis-ci.org/brianc/node-postgres/builds/21012687

Looking at the node-0.8 case next

@strk
Copy link
Contributor Author

strk commented Mar 18, 2014

So it turns out node-0.8 does not send the 'end' stream event on backend close.
Here the trace with node-0.10:

server listening
client connecting
server connected
server socket destroyed.
server closed
got stream 'connect'
got stream 'end'
Error on connect: Error: Stream unexpectedly ended before getting ready for query execution

Here the trace with node-0.8:

server listening
client connecting
got stream 'connect'
server connected
server socket destroyed.
server closed

@strk
Copy link
Contributor Author

strk commented Mar 18, 2014

Got it: node-0.8 emits 'close' !

Should fix missing connect callback call with node-0.8 (brianc#534)
@strk
Copy link
Contributor Author

strk commented Mar 18, 2014

Catching "close" fixes if for node-0.8 too: https://travis-ci.org/brianc/node-postgres/builds/21015203

@brianc
Copy link
Owner

brianc commented Mar 18, 2014

This is great! Thanks! I'll get this tested & merged in ASAP.

@@ -60,6 +60,13 @@ Connection.prototype.connect = function(port, host) {
self.emit('end');
});

this.stream.on('close', function() {
// TODO: avoid emitting 'end' twice ?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this TODO still needed? did you already fix this for v0.8.x and v0.10.x?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Sat, Mar 22, 2014 at 08:50:57AM -0700, Brian C wrote:

@@ -60,6 +60,13 @@ Connection.prototype.connect = function(port, host) {
self.emit('end');
});

  • this.stream.on('close', function() {
  • // TODO: avoid emitting 'end' twice ?

is this TODO still needed? did you already fix this for v0.8.x and v0.10.x?

My problem was fixed and tested with both v0.8 and v0.10

The TODO is needed as it asks for an opinion from you :)
You see that both "end" and "close" events trigger "end".
Do you think that's a problem ?
Node-0.8 only sends "close".

client.js effects on 'end' are all protected by double-call
except for further sending 'end' to upper levels.

the pool calls 'destroy' and receiving 'end' from client but
is protected by the double call with this:

      // Remove connection from pool on disconnect
      client.on('end', function(e) {
        // Do not enter infinite loop between pool.destroy
        // and client 'end' event...
        if ( ! client._destroying ) {
          pool.destroy(client);
        }
      });

So is not a problem, but you migt not like the double 'end'
event anyway.

--strk;

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation! Yeah, definitely emitting end twice would be something to avoid. I don't think it should be too hard, just have a like 'this._ended' flag or something on the client, set it the first time, and check if it's set & don't emit. What you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that's ok for me, but I'm going to do it myself, do you mind ?

I've seen it used already for the connection object, so maybe you could
reuse an existing flag or something like that... It was called _ending
or _closing or something similar...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In v0.10 and forward 'end' means the readable stream has received EOF, 'close' means the underlying resource (socket/fd) has been closed. It should only be necessary to listen to 'close'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. It should be tested with node-0.8 if only listening for "close" is ok.
I guess we'd still need to emit "end" to maintain compatibility in the higher levels.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think only listening for close is okay. As long as we don't emit end twice and it works on v0.8 and v0.10 I'm cool with it. Lemme know when you're ready for another 🔍 and hopefully a merge!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed a commit for only listening on 'close'. Tested locally with node 0.8.9, 0.8.25 and 0.10.26

@brianc
Copy link
Owner

brianc commented Apr 4, 2014

Hmm....with the new commit travis tests are failing. :(

@strk
Copy link
Contributor Author

strk commented Apr 4, 2014

Oops, my testing was bogus as I assumed all failures were being shown while first (unrelated) failure was interrupting the continuation of suite.

@strk
Copy link
Contributor Author

strk commented Apr 4, 2014

The failing test "simulates" a stream emitting an 'end' event, so 'close' is never sent.
I could change the test so it emits 'close' instead, but can we be sure that all streams always send 'close' on end with all node versions ?

@brianc
Copy link
Owner

brianc commented Apr 6, 2014

Hey thanks for your patience on all the back and forth on this! I'll get it merged in today & doing a new release with it & a bunch of other changes. It's long over-due! 😄 👍

brianc added a commit that referenced this pull request Apr 6, 2014
Ensure connect callback is invoked on premature socket hangup
@brianc brianc merged commit f3fc6ff into brianc:master Apr 6, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pg doesn't invoke callback if server accepts the connection and immediately disconnects
3 participants