Please have a look at my original question: Optimizing code using semaphore to control Netty channel pool Optimizing code using semaphore to control Netty channel pool
Please have a look at my original question: Optimizing code using semaphore to control Netty channel pool
Please have a look at my original question: Optimizing code using semaphore to control Netty channel pool
Optimizing code using semaphore to control Netty channel pool - Part 2
Please have a look at my original question: Optimizing code using semaphore to control Netty channel pool
I have made some changes as pointed out by @rolfl The new code is as follows. Is this better? Can i remove the synchronization blocks with some other methodology?
public enum Client{
INSTANCE(Config.getServerIp(),Config.getServerPort());
private static final Logger s_logger = Logger.getLogger(Client.class);
private final String host;
private final int port;
private boolean[] used = null;
private Semaphore available = null;
private Channel[] channels = null;
private final Bootstrap b;
private Client(String host, int port){
this.host = host;
this.port = port;
used = new boolean[Config.getMaxConnections()];
available = new Semaphore(Config.getMaxConnections());
channels = new Channel[Config.getMaxConnections()];
EventLoopGroup workerGroup = new NioEventLoopGroup();
final ChannelInitializer<SocketChannel> channelInitializer = new BasicNioClientChannelInitializer();
b = new Bootstrap();
b.group(workerGroup)
.channel(NioSocketChannel.class)
.handler(channelInitializer)
.option(ChannelOption.SO_KEEPALIVE, true);
}
public int sendMessage(final String message) throws Exception{
final String messageToSend = message + "\r\n";
int responseCode = 200;
available.acquire();
try {
Channel ch;
boolean activeChannel;
int i;
synchronized (this) {
ch = null;
activeChannel = false;
for (i = 0; i < Config.getMaxConnections(); i++) {
if (!used[i]) {
used[i] = true;
ch = channels[i];
break;
}
}
if (i == Config.getMaxConnections()) {
//Should never happen
throw new Exception("No unsused connections.");
}
try {
activeChannel = ch != null ? ch.isActive() : false;
if (!activeChannel) {
if (ch != null) {
ch.close();
}
ChannelFuture cf = b.connect(host, port);
boolean connect = cf.await(Config.getMaxWaitInMillisToConnect());
if (!connect) {
throw new Exception("Unable to try connection to Server in " + Config.getMaxWaitInMillisToConnect() + "ms");
}
ch = cf.channel();
channels[i] = ch;
activeChannel = ch.isActive();
}
} catch (Exception e) {
responseCode = 404;
s_logger.log(Level.FATAL, "***** Could not Connect to Server ****");
s_logger.log(Level.FATAL, e);
e.printStackTrace();
}
}
try {
if (activeChannel) {
System.out.println("Sending to Server using Channel: " + i + " data: " + message);
ChannelFuture future = ch.writeAndFlush(messageToSend);
} else {
throw new Exception("Unable to connect to Server.");
}
} catch (Exception e) {
responseCode = 404;
s_logger.log(Level.FATAL, "***** Could not Connect to Server ****");
s_logger.log(Level.FATAL, e);
e.printStackTrace();
}
synchronized (this) {
for (int j = 0; j < Config.getMaxConnections(); j++) {
if (ch == channels[j]) {
if (used[j]) {
used[j] = false;
break;
}
}
}
}
} finally {
available.release();
}
return responseCode;
}
}