-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Release ping/pong command buffer #283
Conversation
static ByteBuf newPing() { | ||
return RecyclableDuplicateByteBuf.create(cmdPing).retain(); | ||
public static ByteBuf newPing() { | ||
ByteBuf pingCmdBuf = RecyclableDuplicateByteBuf.create(cmdPing).retain(); |
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.
But shouldn't already the pingCmdBuf
be released when it gets written on the channel? That release should then be propagated to the cmdBuf
buffer.
Another option here would be to make the cmdPing
buffer to be unpooled, given that anyway we're going to have 1 single instance of 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.
Thats what I was wondering. With one static instance of cmdPing, why do we need pooled buffer. Can we just "return cmdPing"?
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 cannot be just return cmdPing
because the buffer has a read pointer, once you write on the channel, the read pointer will be moved and the buffer will look empty next time.
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.
So, we still need to create a duplicate of the original cmdPing
, though if the cmdPing
itself is not pooled, the refcounting will be disabled there
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.
yes, it's better to unpool cmdPing
and keep one ByteBuf
for ping/pong as they are static.
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 might be multiple threads sending the ping on different connections. The ByteBuf itself is not thread safe, so that's why you need a duplicate buffer object (referencing the same bytes).
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.
doh. of course.
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.
return RecyclableDuplicateByteBuf.create(cmdPing)
seems to work as well. With the old logic, it's ref count is initialized to 1 when we get it from recycler"RecyclableDuplicateByteBuf buf = RECYCLER.get();". The additional retain() is causing netty not to release it since it's ref count is not 0 after decrementing by 1?
Does it mean we have a leak? I don't see anything reported by leak detector though.
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.
Not a real leak, just a recycler leak. It means that objects are getting GCed instead of being reused in the recycler.
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 have updated it to remove the retain().
cee70dd
to
384fe4d
Compare
@saandrews I think we still need to make the buffer unpooled, the |
I see. I have moved the buffer to unpooled as well. |
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.
👍
Motivation
cmdPing and cmdPong are static ByteBuf which ideally does not required to be ref counted. We are wrapping it with another byteBuf which is released by netty. However, the original cmd buffer ref count increases to int max and server throws the following exception. This causes clients to close connection and reconnect and this cycle repeats until broker restart:
Modifications
Release the command buffer before returning.
Result
Command buffer will not reach int max ref count and fail ping request.