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

Throw ClientNotActiveException instead of generic HazelcastException #13525

Merged
merged 1 commit into from Sep 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -19,6 +19,7 @@
import com.hazelcast.client.AuthenticationException;
import com.hazelcast.client.ClientExtension;
import com.hazelcast.client.ClientTypes;
import com.hazelcast.client.HazelcastClientNotActiveException;
import com.hazelcast.client.HazelcastClientOfflineException;
import com.hazelcast.client.config.ClientNetworkConfig;
import com.hazelcast.client.config.SocketOptions;
Expand Down Expand Up @@ -377,6 +378,9 @@ private Connection getConnection(Address target, boolean asOwner, boolean acquir
}

private void checkAllowed(Address target, boolean asOwner, boolean acquiresResources) throws IOException {
if (!alive) {
Copy link
Contributor

Choose a reason for hiding this comment

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

HazelcastClientNotActiveException does not extend HazelcastException. This is a behaviour change then. Is it possible some user was catching a HazelcastException?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

HazelcastException is retryable in client invocation system. When hazelcast exception is thrown from here, invocation system catches that throws as ClientNotActiveException to user.
https://github.com/hazelcast/hazelcast/blob/master/hazelcast-client/src/main/java/com/hazelcast/client/spi/impl/ClientInvocation.java#L209
But there is an unncessary wrapping there. It results as a ClientNotActiveException which has HazelcastException("client is shutting down") as cause.

There are a couple, usages of connection manager directly like txns which should handle HazelcastException themselves. In that case, we also convert it to ClientNotActiveException

So in almost all of the cases, user get ClientNotActiveException. Even if there were edge cases that user gets HazelcastException before, I would like to consider them as bug and fix it, rather then thinking this as behaviour change.
How does that sound ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I can admit I'm a bit lost here. It's your call. I'm just thinking if this could affect some user code like:

try {
  // use hazelcast
} catch (HazelcastException expected) {
  // all is good, I expected this!
}

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 also my worry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well as mentioned above, if we are not throwing ClientNotActiveException where we supposed to throw it is a bug.
And depending on when the clients shutdown we could be throwing ClientNotActiveException or HazelcastException. That means, user should already prepared for ClientNotActiveException. This fix is to correct one more place that we are throwing HazelcastException instead of ClientNotActiveException.

That is why, I see no problem with backward compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible (or cause any side affects) if IllegalStateException (base class of HazelcastClientNotActiveException) derive from HazelcastException instead of RuntimeException?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IllegalStateException can't derive from HazelcastException, because it is from java.lang library. It is not our class.

throw new HazelcastClientNotActiveException("ConnectionManager is not active!");
}
if (asOwner) {
//opening an owner connection is always allowed
return;
Expand Down Expand Up @@ -435,9 +439,6 @@ private AuthenticationFuture triggerConnect(Address target, boolean asOwner) {
if (!asOwner) {
connectionStrategy.beforeOpenConnection(target);
}
if (!alive) {
throw new HazelcastException("ConnectionManager is not active!");
}

AuthenticationFuture future = new AuthenticationFuture();
AuthenticationFuture oldFuture = connectionsInProgress.putIfAbsent(target, future);
Expand Down Expand Up @@ -561,9 +562,6 @@ private void bindSocketToPort(Socket socket) throws IOException {
}

protected ClientConnection createSocketConnection(final Address address) throws IOException {
if (!alive) {
throw new HazelcastException("ConnectionManager is not active!");
}
SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
Expand Down
Expand Up @@ -153,7 +153,7 @@ public void testRequestShouldFailOnShutdown() {
}

@Test(expected = HazelcastClientNotActiveException.class)
public void testExceptionAfterClientShutdown() throws Exception {
public void testExceptionAfterClientShutdown() {
hazelcastFactory.newHazelcastInstance();
ClientConfig clientConfig = new ClientConfig();
HazelcastInstance client = hazelcastFactory.newHazelcastClient(clientConfig);
Expand All @@ -166,6 +166,18 @@ public void testExceptionAfterClientShutdown() throws Exception {
test.get("key");
}

@Test(expected = HazelcastClientNotActiveException.class)
public void testExceptionAfterClientShutdown_fromClientConnectionManager() {
hazelcastFactory.newHazelcastInstance();
ClientConfig clientConfig = new ClientConfig();
HazelcastInstance client = hazelcastFactory.newHazelcastClient(clientConfig);

IMap<Object, Object> test = client.getMap("test");
test.put("key", "value");
client.shutdown();
test.size();
}

@Test
public void testShutdownClient_whenThereIsNoCluster() {
ClientConfig clientConfig = new ClientConfig();
Expand Down