Skip to content

Commit 3e695e7

Browse files
committed
Fixed issue with connection being stuck on awaitUninterruptibly() as per fizzed#1
Fixed blocking issue at channel write. Related issue RestComm/smpp-extensions#28
1 parent 48aac99 commit 3e695e7

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

src/main/java/com/cloudhopper/smpp/impl/DefaultSmppClient.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,19 +297,23 @@ protected Channel createConnectedChannel(String host, int port, long connectTime
297297
// a socket address used to "bind" to the remote system
298298
InetSocketAddress socketAddr = new InetSocketAddress(host, port);
299299

300-
// set the timeout
301-
this.clientBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, (int)connectTimeoutMillis);
300+
// set the timeout
301+
this.clientBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, (int)connectTimeoutMillis);
302302

303303
// attempt to connect to the remote system
304304
ChannelFuture connectFuture = this.clientBootstrap.connect(socketAddr);
305305

306-
// wait until the connection is made successfully
307-
// boolean timeout = !connectFuture.await(connectTimeoutMillis);
308-
// BAD: using .await(timeout)
309-
// see http://netty.io/3.9/api/org/jboss/netty/channel/ChannelFuture.html
306+
/* It turns out that under certain unknown circumstances the connect waits forever: https://github.com/twitter/cloudhopper-smpp/issues/117
307+
* That's why the future is canceled 1 second after the specified timeout.
308+
* This is a workaround and hopefully not needed after the switch to netty 4.
309+
*/
310310
logger.debug("Waiting for client connection to {}", socketAddr);
311-
connectFuture.awaitUninterruptibly();
312-
//assert connectFuture.isDone();
311+
if (!connectFuture.await(connectTimeoutMillis + 1000)) {
312+
logger.error("connectFuture did not finish in expected time! Try to cancel the connectFuture");
313+
boolean isCanceled = connectFuture.cancel();
314+
logger.error("connectFuture: isCanceled {} isDone {} isSuccess {}", isCanceled, connectFuture.isDone(), connectFuture.isSuccess());
315+
throw new SmppChannelConnectTimeoutException("Could not connect to the server within timeout");
316+
}
313317

314318
if (connectFuture.isCancelled()) {
315319
logger.warn("Client connection cancelled.");

src/main/java/com/cloudhopper/smpp/impl/DefaultSmppSession.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,18 @@ public WindowFuture<Integer,PduRequest,PduResponse> sendRequestPdu(PduRequest pd
510510
// write the pdu out & wait timeout amount of time
511511
ChannelFuture channelFuture = this.channel.writeAndFlush(buffer);
512512
if (configuration.getWriteTimeout() > 0){
513-
channelFuture.await(configuration.getWriteTimeout());
513+
if(!channelFuture.await(configuration.getWriteTimeout()))
514+
throw new SmppChannelException(channelFuture.cause() != null ? channelFuture.cause().getMessage()
515+
: "ChannelFuture failed without cause.", channelFuture.cause());
514516
} else {
515517
channelFuture.await();
516518
}
517519

518520
// check if the write was a success
519521
if (!channelFuture.isSuccess()) {
520522
// the write failed, make sure to throw an exception
521-
if (channelFuture.cause() != null) throw new SmppChannelException(channelFuture.cause().getMessage(), channelFuture.cause());
522-
else throw new SmppChannelException("ChannelFuture failed without cause.");
523+
throw new SmppChannelException(channelFuture.cause() != null ? channelFuture.getCause().getMessage()
524+
: "ChannelFuture failed without cause.", channelFuture.cause());
523525
}
524526

525527
this.countSendRequestPdu(pdu);
@@ -562,15 +564,18 @@ public void sendResponsePdu(PduResponse pdu) throws RecoverablePduException, Unr
562564
// write the pdu out & wait timeout amount of time
563565
ChannelFuture channelFuture = this.channel.writeAndFlush(buffer);
564566
if(configuration.getWriteTimeout() > 0){
565-
channelFuture.await(configuration.getWriteTimeout());
567+
if(!channelFuture.await(configuration.getWriteTimeout()))
568+
throw new SmppChannelException(channelFuture.cause() != null ? channelFuture.cause().getMessage()
569+
: "ChannelFuture failed without cause.", channelFuture.cause());
566570
} else {
567571
channelFuture.await();
568572
}
569573

570574
// check if the write was a success
571575
if (!channelFuture.isSuccess()) {
572576
// the write failed, make sure to throw an exception
573-
throw new SmppChannelException(channelFuture.cause().getMessage(), channelFuture.cause());
577+
throw new SmppChannelException(channelFuture.cause() != null ? channelFuture.cause().getMessage()
578+
: "ChannelFuture failed without cause.", channelFuture.cause());
574579
}
575580
}
576581

0 commit comments

Comments
 (0)