Skip to content

Switch to NIO #195

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

Merged
merged 44 commits into from
Oct 5, 2016
Merged

Switch to NIO #195

merged 44 commits into from
Oct 5, 2016

Conversation

acogoluegnes
Copy link
Contributor

Fixes #11

The current limit may be arbitrary right now (depends on the hardware
and the scenario).

Write as much as possible in the ByteBuffer before clearing it.

Fixes #11
Limit also written frames to the (snapshot) size when iteration starts (instead of
unqueuing during writing).

Fixes #11
@michaelklishin michaelklishin self-assigned this Sep 12, 2016
Use NIO by default (except in SSLTests).

Fixes #11
Fixes #11
And set number of NIO threads a parameter.

Fixes #11
Allows to properly handle the first send header request.

Fixes #11
 Conflicts:
	src/main/java/com/rabbitmq/client/impl/ForgivingExceptionHandler.java
	src/main/java/com/rabbitmq/client/impl/SocketFrameHandler.java
First draft.

Fixes #11
 Conflicts:
	src/main/java/com/rabbitmq/client/impl/recovery/AutorecoveringConnection.java
Using ByteBuffer-based streams, to avoid duplicating
the frame parsing/write logic.

Fixes #11
Clean some unused code, handle connection and TLS handshake failure,
add configuration hook for SocketChannel, create 'use*' methods
to activate NIO or blocking IO.

Fixes #11
@acogoluegnes acogoluegnes changed the title DO NOT MERGE Switch to NIO Switch to NIO Sep 26, 2016
@michaelklishin
Copy link
Contributor

This fails CI and no longer merges cleanly.

Copy link
Contributor

@michaelklishin michaelklishin left a comment

Choose a reason for hiding this comment

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

With this PR I have CPU load hovering around 600% when running mvn verify. At the end tests begin to fail with java.lang.OutOfMemoryError: unable to create new native thread. So my guess is that there is a thread instance leak.

The ExecutorService wasn't closed properly in the base test
class, there were thus many threads in park state when running
the test suite. This could lead to resource exhaustion, especially
on MacOS.

Fixes #11
On MacOS, SocketChannel.read() can return EOF when the SocketChannel
is closed. On Linux, it would throw an exception. This could lead
to spinning threads on MacOS, because the NIO loop was never closed.

Fixes #11
The default is to use blocking IO.

Fixes #11
@michaelklishin
Copy link
Contributor

With the recent EOF handling fix, the CPU/Heap/Threads charts in Visual VM over the course of a test suite run now look nearly identical with the default profile vs. use-nio. This is looking good for inclusion as an opt-in feature for 4.0.0.

static int read(ReadableByteChannel channel, ByteBuffer buffer) throws IOException {
int read = channel.read(buffer);
if(read < 0) {
throw new IOException("Channel has reached EOF");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is confusing. The users will think it has to do with RabbitMQ channels. Please use "Connection has reached EOF" or simply "I/O thread: reached EOF".

public class NioParams {

/** size of the byte buffer used for inbound data */
private int readByteBufferSize = 8192;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd bump this and the write buffer here to 32K, it sounds quite reasonable (default TCP buffer size on Linux and OS X is around 100K, for instance).

@michaelklishin
Copy link
Contributor

I observe a couple of test failures in TLS with NIO enabled:

17:25:51.472 [main] INFO  c.r.client.test.BrokerTestCase - Test finished: NioTlsUnverifiedConnection.connectionGetConsume
Tests run: 8, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.392 sec <<< FAILURE! - in com.rabbitmq.client.test.ssl.SSLTests
sSL(com.rabbitmq.client.test.ssl.VerifiedConnection)  Time elapsed: 0.232 sec  <<< FAILURE!
java.lang.AssertionError: Couldn't open TLS connection after 3 attemps
    at com.rabbitmq.client.test.ssl.VerifiedConnection.openConnection(VerifiedConnection.java:99)

sSL(com.rabbitmq.client.test.ssl.VerifiedConnection)  Time elapsed: 0.232 sec  <<< FAILURE!
java.lang.AssertionError: Couldn't open TLS connection after 3 attemps
    at com.rabbitmq.client.test.ssl.VerifiedConnection.openConnection(VerifiedConnection.java:99)


Results :

Failed tests:
com.rabbitmq.client.test.ssl.VerifiedConnection.sSL(com.rabbitmq.client.test.ssl.VerifiedConnection)
  Run 1: VerifiedConnection>BrokerTestCase.setUp:71->openConnection:99 Couldn't open TLS connection after 3 attemps
  Run 2: VerifiedConnection>BrokerTestCase.tearDown:82->openConnection:99 Couldn't open TLS connection after 3 attemps

(on OS X)

And change EOF message, to make it clearer.

Fixes #11
@acogoluegnes
Copy link
Contributor Author

The TLS handshake failures are likely to happen with Erlang 19.x. It's been fixed in 19.1.1. These failures are transient, with blocking IO and NIO.

@michaelklishin
Copy link
Contributor

Yes, that was it. The suite passes with flying colors on 19.1.1.

@michaelklishin michaelklishin merged commit 65367b5 into master Oct 5, 2016
@acogoluegnes acogoluegnes deleted the rabbitmq-java-client-11 branch March 21, 2019 08:24
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.

2 participants