Below is the code snippet that I developed for ConnectionPool. Kindly let me know if there are any problems or shortcomings with the below code. I've deployed it to our test environment and was able to see that its not creating more the allowed MAX_CONN_CAPACITY
and the objects are being re-used (I checked this by logging the ODServerHolder
's hashcode into the log file). I would just like to know what other developers think.
getOndemandConnection()
and releaseOndemandConnection()
are the methods that will be called by other classes using this pool.
public final class ServerConnPool {
private ServerConnPool(){
//making sure no one else initializes this class. though all field are defined static, just to make sure
//its not instantiated ...
}
private static WSLogger logger =
new WSLogger(ServerConnPool.class);
private static String strContextRoot = "EAFService";
private static int MAX_CONN_CAPACITY = 5;
private static LinkedBlockingDeque<ODServerHolder> odServerConnectionPool ;
static ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(1);
// FOR PERFORMANCE CAN CHANGE LATER TO NUMBER OF AVAILABLE CPUS..
private static AtomicInteger ATOMIC_POOL_COUNTER = new AtomicInteger(0);
static {
try {
MAX_CONN_CAPACITY = 5;
odServerConnectionPool = new LinkedBlockingDeque<ODServerHolder>(MAX_CONN_CAPACITY);
} catch (Exception e) {
logger.error(e.getMessage());
throw new RuntimeException(e.getLocalizedMessage());
}
for (int i = 0; i < MAX_CONN_CAPACITY; i++) {
ODServerHolder OdServerHolder =null;
try {
OdServerHolder = initServerHolder();
} catch (ODException e) {
logger.error(e.getMessage()); }
odServerConnectionPool.add(OdServerHolder);
}
}
public static ODServerHolder getOnDemandConnection(String credential,String credentialType) throws Exception
{
return getConnection(credential, credentialType);
}
/**
*
* @param credential
* @param credentialType
* @return
* @throws Exception
*/
private static ODServerHolder getConnection(String credential,String credentialType) throws Exception{
try {
// String strFullPath = ODUtils.iniFile.getFullFileName().substring(0,ODUtils.iniFile.getFullFileName().lastIndexOf(File.separator)+ 1);
ODServerHolder odHolder = odServerConnectionPool.take();
ODServer odServerConn= odHolder.getODServer();
if(odServerConn == null){
odServerConn = initializeODServer();
odHolder.setODServer(odServerConn);
}
if(!odServerConn.isInitialized()) { // || odServerConn.isServerTimedOut()){
odServerConn.initialize(strContextRoot);
odHolder.setODServer(odServerConn);
}
return odHolder;
} catch (Exception ex) {
logger.error("Error during OD connection: " + ex.getMessage());
throw ex;
}
}
/**
* release back ODServerConnection to the Pool.
* @param odHolder
*/
public static void releaseODServerConnection(ODServerHolder odHolder){
try {
odHolder.getODServer().keepServerAlive();
odServerConnectionPool.put(odHolder);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* method to initialize ODServer connection.
* @param odServerConn
* @throws ODException
*/
private static ODServer initializeODServer() throws ODException{
ODServer odServerConn = new ODServer();
odServerConn.initialize(strContextRoot);
odServerConn.keepServerAlive();
return odServerConn;
}
private static ODServerHolder initServerHolder() throws ODException {
ODServer server = null;
int id = ATOMIC_POOL_COUNTER.incrementAndGet();
ODServerHolder sHolder = new ODServerHolder(server,id);
return sHolder;
}
private static class ODServerConnectionCleanerThread implements Runnable {
private ODServerConnectionCleanerThread(){
}
@Override
public void run() {
try {
logger.info("current ODServer Connection pool capacity is : "+ odServerConnectionPool.size());
for (ODServerHolder odHolder : odServerConnectionPool) {
ODServer odConn = odHolder.odServerConn;
int id = odHolder.getId();
if(odConn!= null)
logger.info("Server Number : "+id+" odServer hashCode: " +
""+odConn.hashCode() + " is Server Timed out : "+
odConn.isServerTimedOut()+" is it Initialized? : "+ odConn.isInitialized());
}
} catch (Exception e) {
e.printStackTrace();
logger.error("ODServerConnectionCleanerThread : Problem in running " +
"the schduler this time.. will continue again.. ");
}
}
}
}