Skip to content

Commit

Permalink
Adding workaround for the case when a connect gets stuck forever
Browse files Browse the repository at this point in the history
  • Loading branch information
l1101100 committed Mar 8, 2016
1 parent fb82730 commit ac9be21
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions src/main/java/com/cloudhopper/smpp/impl/DefaultSmppClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -286,25 +286,31 @@ protected Channel createConnectedChannel(String localAddress, String host, int p
// attempt to connect to the remote system
ChannelFuture connectFuture = this.clientBootstrap.connect(socketAddr, socketLocalAddr);

// wait until the connection is made successfully
// boolean timeout = !connectFuture.await(connectTimeoutMillis);
// BAD: using .await(timeout)
// see http://netty.io/3.9/api/org/jboss/netty/channel/ChannelFuture.html
connectFuture.awaitUninterruptibly();
//assert connectFuture.isDone();
// Wait until the connection is made successfully.
// According to the netty documentation it is bad to use .await(timeout). Instead
// b.setOption("connectTimeoutMillis", 10000);
// should be used. See http://netty.io/3.9/api/org/jboss/netty/channel/ChannelFuture.html
// It turns out that under certain unknown circumstances the connect waits forever: https://github.com/twitter/cloudhopper-smpp/issues/117
// That's why the future is canceled 1 second after the specified timeout.
// This is a workaround and hopefully not needed after the switch to netty 4.
if (!connectFuture.await(connectTimeoutMillis + 1000)) {
logger.error("connectFuture did not finish in expected time! Try to cancel the connectFuture");
boolean isCanceled = connectFuture.cancel();
logger.error("connectFuture: isCanceled {} isDone {} isSuccess {}", isCanceled, connectFuture.isDone(), connectFuture.isSuccess());
throw new SmppChannelConnectTimeoutException("Could not connect to the server within timeout");
}

if (connectFuture.isCancelled()) {
throw new InterruptedException("connectFuture cancelled by user");
} else if (!connectFuture.isSuccess()) {
if (connectFuture.getCause() instanceof org.jboss.netty.channel.ConnectTimeoutException) {
throw new SmppChannelConnectTimeoutException("Unable to connect from local address [" + localAddress + "] to host [" + host + "] and port [" + port + "] within " + connectTimeoutMillis + " ms", connectFuture.getCause());
throw new SmppChannelConnectTimeoutException("Unable to connect from local address [" + localAddress + "] to host [" + host + "] and port [" + port + "] within " + connectTimeoutMillis + " ms", connectFuture.getCause());
} else {
throw new SmppChannelConnectException("Unable to connect from local address [" + localAddress + "] to host [" + host + "] and port [" + port + "]: " + connectFuture.getCause().getMessage(), connectFuture.getCause());
throw new SmppChannelConnectException("Unable to connect from local address [" + localAddress + "] to host [" + host + "] and port [" + port + "]: " + connectFuture.getCause().getMessage(), connectFuture.getCause());
}
}

// if we get here, then we were able to connect and get a channel
return connectFuture.getChannel();
}

}

0 comments on commit ac9be21

Please sign in to comment.