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 reader is empty before calling Close #564

Merged
merged 2 commits into from
Jan 19, 2017
Merged

Conversation

prashantv
Copy link
Contributor

This triggers an extra Read which will avoid
#563

This is only an issue if the remote side is sending empty TChannel
frames, which should only happen during streaming.

Fixes #563

cc @willhug @akshayjshah

This triggers an extra Read which will avoid
#563

This is only an issue if the remote side is sending empty TChannel
frames, which should only happen during streaming.
Copy link

@willhug willhug left a comment

Choose a reason for hiding this comment

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

Seems good to me, maybe pass it by another person before landing, if you're confident, go for it.

"testing"

"io/ioutil"
Copy link

Choose a reason for hiding this comment

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

should this be with the other "top-level" imports?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@@ -72,6 +75,15 @@ func TestJSONInputOutput(t *testing.T) {
assert.Equal(t, 20756, outObj.Value)
}

func TestReadNotEmpty(t *testing.T) {
// Note: The contents need to be larger than the default buffer size of bufio.NewReader.
Copy link

Choose a reason for hiding this comment

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

Is there a constant we can pull for the default buffer size (as opposed to 10000)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, no constant we can use here.

Copy link

Choose a reason for hiding this comment

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

can we make a constant?

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 don't really think it adds much value to have a constant that's only used in a single test, and doesn't represent anything (e.g., it's counting the number of repeats for the string, not a number of bytes). It's pretty arbitrary.

Copy link

Choose a reason for hiding this comment

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

ztkau2p

@@ -72,6 +75,15 @@ func TestJSONInputOutput(t *testing.T) {
assert.Equal(t, 20756, outObj.Value)
}

func TestReadNotEmpty(t *testing.T) {
// Note: The contents need to be larger than the default buffer size of bufio.NewReader.
r := bytes.NewReader([]byte("{}" + strings.Repeat("{}\n", 10000)))
Copy link

Choose a reason for hiding this comment

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

so the "{}" is the 'end' of the thrift request right? Which is why anything after the first '{}' causes an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in this case it's using JSON, but yep.


"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/uber/tchannel-go/testutils/testreader"
Copy link

Choose a reason for hiding this comment

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

import ordering

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

// EnsureEmpty ensures that the specified reader is empty. If the reader is
// not empty, it returns an error with the specified stage in the message.
func EnsureEmpty(r io.Reader, stage string) error {
buf := make([]byte, 128)
Copy link
Contributor

Choose a reason for hiding this comment

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

should this just be,

var buff [128]byte
n, err := r.Read(buff[:])

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't really matter, buf escapes either way.

 31   var buf [128]byte
 32   n, err := r.Read(buf[:])
> go build  -gcflags=-m
# github.com/uber/tchannel-go/internal/argreader
./empty.go:32: buf escapes to heap
./empty.go:31: moved to heap: buf

Decided to instead pool the byte slices instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@prashantv prashantv merged commit 655757a into dev Jan 19, 2017
@prashantv prashantv deleted the handle_empty_frame branch January 19, 2017 01:05
prashantv added a commit that referenced this pull request Jan 19, 2017
This triggers an extra Read which will avoid
#563

This is only an issue if the remote side is sending empty TChannel
frames, which should only happen during streaming.
@prashantv prashantv mentioned this pull request Jan 19, 2017
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