-
Notifications
You must be signed in to change notification settings - Fork 582
Support underflow handling without thread sleep #701
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
Support underflow handling without thread sleep #701
Conversation
UPD It was realized that actually both PRs provide chunks handling without losses. But in case of #702 |
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.
Nice contribution, thanks! Do you think it would be possible to get rid of the isUnderflowHandlingEnabled
AtomicBoolean, keep the information in the frame builder, and expose with a package-protected method? The state could reset the flag with another package-protected method. This would avoid to use an atomic class (we don't need the guarantees it provides as this is all mono-threaded).
if (!isUnderflowHandlingEnabled.get()) { | ||
cipherIn.clear(); | ||
cipherIn.flip(); | ||
} | ||
|
||
cipherIn.flip(); | ||
plainIn.clear(); | ||
plainIn.flip(); |
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.
Can you elaborate on the need of these operations?
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.
cipherIn
should aggregate chunks of bytes on each read. So we should not clear it before each chunk reading.
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 in my implementation continueReading
returns false when there is no data for next chunk. So there is no infinite loop around while(continueReading())
while data is not present in buffer. NIO thread can check selector state before trying to get bytes.
} | ||
cipherBuffer.flip(); | ||
break; | ||
underflowHandling = true; |
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.
OK, removing some reading logic and putting it in the class that was already doing, nice.
isUnderflowHandlingEnabled was converted to private attribute of SslEngineFrameBuilder |
@YuryAndr thank you for contributing. We will back port after testing but you are welcome to build this client from source and try it out on your actual workload one more time ;) |
@YuryAndr 5.13.1-SNAPSHOT is available if you want to give it a try. I'll release 5.13.1 if it works for you. |
@acogoluegnes Thank you! It was verified over our setup. Also it was found that PR had fixed another related issue. It was noticed that error in
Because in case of 5.13.0 there is no It was also verified that there are no such memory issues on 5.13.1-SNAPSHOT. |
@acogoluegnes Could you please also provide patch for |
We generally do not release patches for older minor series, in particular six series behind. @YuryAndr if you are willing to do all the backporting and testing work for |
So yeah, in addition to backporting to |
Next PR provides cherry picked commits for |
OK, I'll see what I can to release a 5.7.x, but it won't be before several weeks. |
Proposed Changes
Purpose of PR is to fix bug -#700
According to https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html we should perform read next bytes of message when
SSLEngineResult
indicatesBUFFER_UNDERFLOW
state.In versions before
5.*.*
it was fixed using retries with Thread.sleep() https://github.com/rabbitmq/rabbitmq-java-client/blob/87aae532705490fa429afe34326a0ebbdd83e1d3/src/main/java/com/rabbitmq/client/impl/nio/NioHelper.javaBut versions
5.*.*
don't include this fix. Also It is not good idea to use Thread.sleep() on nio thred.Current PR provides fetching chunks of bytes using standard NIO flow.
SocketChannelFrameHandlerState
providesisUnderflowHandlingEnabled
attribute to track current state.