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

[FIXED] Protocols received right after first PONG may not be processed #348

Merged
merged 2 commits into from
Mar 6, 2018

Conversation

kozlovic
Copy link
Member

@kozlovic kozlovic commented Mar 6, 2018

This manifested with the recent changes where server may send
an async INFO protocol right after sending the initial PONG to
the client.
After the client sends the CONNECT protocol, it expects to receive
a PONG. The reading of the protocol is done in place (in the
sendConnect() function) but a buffer reader was used. This is wrong
since any data/protocol sent right after by the server may be
consumed when trying to read the PONG instead of leaving that to
the readLoop.
Since we are just looking for the PONG (or OK and PONG) here, perform
a byte-by-byte read there. Alternatively, if doing a buffered read,
the buffer will have to be passed to the readLoop so that whatever
is in the buffer is read prior to resuming reading from socket.

This manifested with the recent changes where server may send
an async INFO protocol right after sending the initial PONG to
the client.
After the client sends the CONNECT protocol, it expects to receive
a PONG. The reading of the protocol is done in place (in the
sendConnect() function) but a buffer reader was used. This is wrong
since any data/protocol sent right after by the server may be
consumed when trying to read the PONG instead of leaving that to
the readLoop.
Since we are just looking for the PONG (or OK and PONG) here, perform
a byte-by-byte read there. Alternatively, if doing a buffered read,
the buffer will have to be passed to the readLoop so that whatever
is in the buffer is read prior to resuming reading from socket.
@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 95.053% when pulling 41c5d2b on fix_read_after_connect into bfca8af on master.

kozlovic referenced this pull request in nats-io/nats-server Mar 6, 2018
This is the result of flapping tests in go-nats that were caused
by a defect (see PR https://github.com/nats-io/go-nats/pull/348).
However, during debugging, I realize that there were also things
that were not quite right in the server side. This change should
make it the notification of cluster topology changes to clients
more robust.
kozlovic referenced this pull request in nats-io/nats-server Mar 6, 2018
This is the result of flapping tests in go-nats that were caused
by a defect (see PR https://github.com/nats-io/go-nats/pull/348).
However, during debugging, I realize that there were also things
that were not quite right in the server side. This change should
make it the notification of cluster topology changes to clients
more robust.
nats.go Outdated
@@ -1283,6 +1285,24 @@ func (nc *Conn) sendConnect() error {
return nil
}

// read byte-by-byte from the connection until the given 'c' character is found.
func (nc *Conn) readStringUpTo(c byte) (string, error) {
Copy link
Member

Choose a reason for hiding this comment

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

I think their is a func in the stdlib that does this no?

Copy link
Member Author

Choose a reason for hiding this comment

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

I could not find. We cannot use a buffered reader because it does fill up the buffer in the background, thing that we don't want to happen. I looked at a buffered reader with io.LimitedReader, but then you need to know the number of bytes you want to read.

I did rename the function to readProto and don't pass the delimiter anymore. This function is not meant to be an all purpose function.

Copy link
Member

Choose a reason for hiding this comment

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

ok

In some cases the server may send an authorization violation and
closes the connection right away. With the original change, the
test in server would fail. Handling the EOF here solves the issue.
From tests it looks like the last `\n` is often missing but it
is fine since the client library when not getting a PONG assumes
it is an error and strips away the `-ERR` prefix and the new line
suffix anyway.

Updated a test since we changed the server DefaultTestOptions
port to be -1 instead of 4222.
@kozlovic kozlovic merged commit f90dee2 into master Mar 6, 2018
@kozlovic kozlovic deleted the fix_read_after_connect branch March 6, 2018 23:48
@kozlovic kozlovic changed the title [FIXED] Protocols received right after first PONG may be processed [FIXED] Protocols received right after first PONG may not be processed Mar 17, 2018
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.

3 participants