-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Leave overflow logic to go-msgio #1910
Conversation
There were the following issues with your Pull Request
Guidelines and a script are available to help. Your feedback on GitCop is welcome on this issue. This message was auto-generated by https://gitcop.com |
I'm able to run the tests locally. Things are failing. I'll see what's up. |
I believe we still need to have a buffer here, for the ETM behavior to work correctly. (also will want to be able to tune it here, separately from having to change go-msgio) |
There still is a buffer here and there can be tuning added, but right now what's here is just redundant. The exact same check and error is thrown by go-msgio. |
Unless I misunderstand, but it looks like one message from the msgio is one payload+mac, and the buffer here is just because the reader might request less than the full payload and, regardless of the chunking and chunk digests, it seems like the reader is meant to receive a continuous stream. |
e698aa2
to
d6474c3
Compare
There were the following issues with your Pull Request
Guidelines and a script are available to help. Your feedback on GitCop is welcome on this issue. This message was auto-generated by https://gitcop.com |
d6474c3
to
1c7e286
Compare
func (r *etmReader) Read(buf []byte) (int, error) { | ||
r.Lock() | ||
defer r.Unlock() | ||
|
||
// first, check if we have anything in the buffer | ||
copied := r.drainBuf(buf) | ||
buf = buf[copied:] |
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.
I think this was meant to deal with the case where buf
is smaller than r.buf
but I think it should read buf = buf[:copied]
(all the bytes up to copied
, not all the bytes after).
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.
no i believe this is right as is -- (this seems to be way more complicated than it should be, though).
buf
here is the user passed inbuf
which will receive the datar.drainBuf(buf)
will copy intobuf
all the stuff inr.buf
that fits intobuf
.- it also updates
r.buf
to ber.buf[n:]
(i.e. already copiedbuf[0:n]
intobuf
) copied
is the number of bytes copied intobuf
. this may be a number smaller thanlen(buf)
, and if so, we want to setbuf
to bebuf[copied:]
so that further copies into buf only fill up the remaining (unused) bytes.- below, we copy more into
buf
, and in that case we only write into the originalbuf[copied:]
, because that's what hasn't been written to.
all of this is useless anyway because exit if copied > 0
, which seems to have been added later, as a short circuit for simplicity.
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.
also, wow this code. @jbenet needs to write cleaner crap.
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.
Ah, thanks for the explanation. This is me being a go newbie, despite being an experience C programmer. I was thinking that somehow buf
was manipulating a reference and buf = buf[copied:]
was changing the result that the caller sees.
All fixed. Even if you don't want to remove this overflow logic, please see my comment in the changes: I think there is a bug. |
1c7e286
to
6c95889
Compare
Well, this is ready to be either closed or merged, I think. Your call :). |
I really like the simplicity, and this seems right to me. (tests seem to pass too, so should be right). the only thing i wonder about is whether the buffer should be held here or left to go-msgio. msgio may change again, not clear. and we may want to make this buffer configurable, not sure. @whyrusleeping is going to be a much better person to CR this than me. |
Oh, now i recall. the thing about using go-msgio |
Oh, I see. Since the caller is passing in a buffer, we can ask |
The |
Although, I never release the buffer back to the pool. @jbenet if there's still desire to make all of this more streaming somehow, I'm happy to hack at that instead. |
wow, so i've never looked at this etm code before. At first glance, this looks like the right idea to me. although one thing to note: you will need to keep track of the original buffer handed to you from msgio, and call I'll play with this a little more in the morning after you make the |
We haven't needed to release the messages because we used Read with a single buffer, no more allocations. — On Fri, Oct 30, 2015 at 3:49 AM, Jeromy Johnson notifications@github.com
|
@jbenet oooooh, right. |
Thanks, you two. Closing this. Good first exercise, though :). |
@tilgovi i think theres still something there worth pursuing in this PR. your PR would lower memory pressure (as long as you added the release call), and simplify this part of the code quite a bit. |
Re-opened. Definitely agree it simplifies, but I don't see how it alleviates any memory pressure. As @jbenet pointed out, the user is passing in a buffer here. Although, in the case that the user buffer is too small for the message, we're allocating a new buffer here anyway. That would be better to do in msgio since it's got a buffer pool. If you think it's helpful, I'll add the release back to the pool. Anything else you would like me to change? |
@whyrusleeping i believe the old way is much better for memory. It's a larger constant allocation, but it doesn't cause a bunch of sequential allocs of varying size which will undoubtedly lead to fragmentation. (worse mem and cpu utilization). Anyway, the simplification and cleanup is worth pursuing |
I'll just let it bake in my head over the weekend and see if there's anything I think is worthwhile on Monday. |
@jbenet the memory pools are rather efficient. they work quite well |
51808c7
to
42697e6
Compare
I've rewritten this but I'm sure I have a bug somewhere because the tests are failing. The current implementation aims to read directly into the output buffer when it is sufficiently large and to let msgio allocate from its pool otherwise, draining from and releasing that when it's been used up. This should be the best of both worlds: zero-copy if the output buffer is large enough and buffer pool otherwise. |
I'll let you know when I work out the kinks if no one spots it before I do. |
42697e6
to
f9684c6
Compare
There you go. |
this LGTM. thanks @tilgovi @whyrusleeping CR? |
@tilgovi sorry for taking so long on this one, could you rebase it on latest master? |
go-msgio implements the message length limit (currently 8MB), so the secio reader can get away without re-implementing this logic. Instead, the reader lets go-msgio allocate a buffer when the output buffer is too small to hold the incoming message. This buffer is kept and drained into the output buffer(s) of Read() calls and released back to the msgio instance once it is fully drained. License: MIT Signed-off-by: Randall Leeds <randall@bleeds.info>
f9684c6
to
6eedb6c
Compare
Done. Not all the CI passed, but I can't see how it's related to the change and they may be spurious. I don't know the state of the test suite. |
Moved to libp2p/go-libp2p#13 |
It seems as though go-msgio now implements the message length limit
(currently 8MB), so the logic in secio reader can be simplified.
This is my first go code. I could be wildly wrong about many things.
I tried to run
make test
and got failures, but there are no tests for this module, it seems, so I don't know if these are failures that I've caused.