Methods Summary |
---|
public synchronized void | addResource(ResourceSpec spec, ResourceHandle h)add a resource with status busy and not enlisted
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE,"Pool: resource added: " + spec + "," + h);
}
// all resources in this pool have the same resource spec
ResourceState state = new ResourceState();
resources.add(h);
h.setResourceState(state);
state.setEnlisted(false);
setResourceStateToBusy(h);
|
public synchronized void | cancelResizerTask()
if (_logger.isLoggable( Level.FINE ) ) {
_logger.finest("Cancelling resizer");
}
if (resizerTask != null ) {
resizerTask.cancel();
}
resizerTask = null;
if (timer != null){
timer.purge();
}
|
private void | clearAllConnectionLeakTasks()Clear all connection leak tracing tasks in case of connection leak
tracing being turned off
synchronized(connectionLeakLock){
Iterator<ResourceHandle> iter = connectionLeakTimerTaskHashMap.keySet().iterator();
while(iter.hasNext()){
ResourceHandle resourceHandle = iter.next();
ConnectionLeakTask connectionLeakTask = connectionLeakTimerTaskHashMap.get(resourceHandle);
connectionLeakTask.cancel();
}
if(timer != null)
timer.purge();
connectionLeakThreadStackHashMap.clear();
connectionLeakTimerTaskHashMap.clear();
}
|
private void | createResourceAndAddToPool(ResourceAllocator alloc)
ResourceHandle resourceHandle = createSingleResource(alloc);
//addResource() will also increment numResourcesInPool
addResource(resourceSpec, resourceHandle);
// addResource() does not add the resource to the free pool!!!
// so we need to do that.
setResourceStateToFree(resourceHandle);
free.add(resourceHandle);
if ( monitoringEnabled ) {
poolCounters.incrementNumConnCreated();
}
|
private synchronized void | createResources(ResourceAllocator alloc, int size)
for (int i = 0; i < size; i++) {
createResourceAndAddToPool(alloc);
}
|
protected ResourceHandle | createSingleResource(ResourceAllocator resourceAllocator)Method to be used to create resource, instead of calling ResourceAllocator.createResource().
This method handles the connection creation retrial in case of failure
ResourceHandle resourceHandle = null;
int count = 0;
while(true){
try{
count++;
resourceHandle = resourceAllocator.createResource();
if(validation || validateAtmostEveryIdleSecs)
resourceHandle.setLastValidated(System.currentTimeMillis());
break;
}catch(Exception ex){
_logger.log(Level.FINE, "Connection creation failed for " + count + " time. It will be retried, "
+ "if connection creation retrial is enabled.", ex);
if(!connectionCreationRetry_ || count >= connectionCreationRetryAttempts_)
throw new PoolingException(ex);
try {
Thread.sleep(conCreationRetryInterval_);
} catch (InterruptedException ie) {
//ignore this exception
}
}
}
return resourceHandle;
|
protected ResourceHandle | createSingleResourceAndAdjustPool(ResourceAllocator alloc, ResourceSpec spec)This method will be called from the getUnenlistedResource method if
we detect a failAllConnection flag.
Here we simply create a new resource and replace a free resource in
the pool by this resource and then give it out.
This replacement is required since the steadypoolsize might equal
maxpoolsize and in that case if we were not to remove a resource
from the pool, our resource would be above maxPoolSize
if ( free.size() != 0 ) {
//resources.size() could be 0 if we were to run into
//trouble while createResources(0 was called in
//doFailAllConnectionsProcessing
ResourceHandle rHandle = free.get(0);
resources.remove( rHandle );
free.remove( rHandle );
}
ResourceHandle result = createSingleResource(alloc);
addResource( spec, result );
alloc.fillInResourceObjects( result );
if ( monitoringEnabled ) {
poolCounters.incrementNumConnCreated();
}
return result;
|
protected void | destroyResource(ResourceHandle resourceHandle)
try {
resourceHandle.getResourceAllocator().destroyResource(resourceHandle);
} catch (Exception ex) {
_logger.log(Level.WARNING,"poolmgr.destroy_resource_failed");
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE,"poolmgr.destroy_resource_failed",ex);
}
} finally {
//if connection leak tracing is running on connection being
//destroyed due to error, then stop it
if(resourceHandle.getResourceState().isBusy())
stopConnectionLeakTracing(resourceHandle);
if (monitoringEnabled) {
poolCounters.incrementNumConnDestroyed();
if (resourceHandle.getResourceState().isBusy()){
//Destroying a Connection due to error
poolCounters.decrementNumConnUsed(true);
} else {
//Destroying a free Connection
poolCounters.decrementNumConnFree();
}
}
}
|
public void | disableMonitoring()
monitoringEnabled = false;
|
private void | doFailAllConnectionsProcessing()
logFine("doFailAllConnectionsProcessing entered");
cancelResizerTask();
if ( monitoringEnabled ) {
poolCounters.incrementNumConnFailedValidation(resources.size());
}
emptyPool();
try {
createResources(allocator, steadyPoolSize);
} catch(PoolingException pe) {
//Ignore and hope the resizer does its stuff
logFine( "in doFailAllConnectionsProcessing couldn't create steady resources");
}
scheduleResizerTask();
logFine("doFailAllConnectionsProcessing done - created new resources");
|
public synchronized void | dumpPoolStatus()This method can be used for debugging purposes
_logger.log(Level.INFO, "Name of pool :" + name);
_logger.log(Level.INFO, "Free connections :" + free.size());
_logger.log(Level.INFO, "Total connections :" + resources.size());
_logger.log(Level.INFO, "Pool's matching is :" + matchConnections);
_logger.log(Level.INFO, "Free Table is :" + free);
_logger.log(Level.INFO, "Resource Table is :" + resources);
|
public synchronized void | emptyFreeConnectionsInPool()
if (_logger.isLoggable(Level.FINE)) {
_logger.fine( "Emptying free connections in pool : " + name );
}
for (Object aFree : free) {
ResourceHandle h = (ResourceHandle) aFree;
resources.remove(h);
destroyResource(h);
}
free.clear();
|
public synchronized void | emptyPool()
logFine("EmptyPool: Name = " + name);
Iterator iter = resources.iterator();
while(iter.hasNext()) {
ResourceHandle h = (ResourceHandle) iter.next();
destroyResource(h);
}
free.clear();
resources.clear();
|
private synchronized void | enforceDelistment(ResourceHandle h)Remove the resource from book-keeping
J2EETransaction txn = (J2EETransaction)Switch.getSwitch().getTransactionManager().getTransaction();
if(txn != null){
Set set = txn.getResources(name);
if(set != null)
set.remove(h);
}
|
protected synchronized void | freeResource(ResourceHandle resourceHandle)
// Put it back to the free collection.
free.add(resourceHandle);
//update the monitoring data
if(monitoringEnabled){
poolCounters.decrementNumConnUsed(false);
}
if (maxConnectionUsage_ > 0) {
performMaxConnectionUsageOperation(resourceHandle);
}
//for both the cases of free.add and maxConUsageOperation, a free resource is added.
// Hence notify waiting threads
notifyWaitingThreads();
|
protected synchronized void | freeUnenlistedResource(ResourceHandle h)
freeResource(h);
|
public long | getCurrentConnRequestWaitTime()
return poolCounters.currConnectionRequestWait;
|
public long | getMaxConnRequestWaitTime()
return poolCounters.maxConnectionRequestWait;
|
public long | getMaxNumConnFree()
return poolCounters.maxNumConnFree;
|
public long | getMaxNumConnUsed()Return the maximum number of connections ever used in
this pool
return poolCounters.maxNumConnUsed;
|
public int | getMaxPoolSize()
return maxPoolSize;
|
public long | getMinConnRequestWaitTime()
if(poolCounters.minConnectionRequestWait != Long.MAX_VALUE) {
return poolCounters.minConnectionRequestWait;
} else {
return 0;
}
|
public long | getMinNumConnFree()
if (poolCounters.minNumConnFree != Long.MAX_VALUE) {
return poolCounters.minNumConnFree;
} else {
return 0;
}
|
public long | getMinNumConnUsed()
if (poolCounters.minNumConnUsed != Long.MAX_VALUE) {
return poolCounters.minNumConnUsed;
} else {
return 0;
}
|
public long | getNumConnAcquired()
return poolCounters.numConnAcquired;
|
public long | getNumConnCreated()
return poolCounters.numConnCreated;
|
public long | getNumConnDestroyed()
return poolCounters.numConnDestroyed;
|
public long | getNumConnFailedValidation()Return the number of connections that have failed validation
return poolCounters.numConnFailedValidation;
|
public synchronized long | getNumConnFree()Return the number of free connections in the pool
return poolCounters.currNumConnFree;
|
public synchronized long | getNumConnInUse()Return the number of connections in use
return poolCounters.currNumConnUsed;
|
public long | getNumConnNotSuccessfullyMatched()
return poolCounters.numConnNotSuccessfullyMatched;
|
public long | getNumConnReleased()
return poolCounters.numConnReleased;
|
public long | getNumConnSuccessfullyMatched()
return poolCounters.numConnSuccessfullyMatched;
|
public long | getNumConnTimedOut()Return the number of threads that have time out after
waiting to obtain a connection from the pool.
return poolCounters.numConnTimedOut;
|
public long | getNumPotentialConnLeak()
return poolCounters.numPotentialConnLeak;
|
public int | getNumThreadWaiting()Return the number of threads that are waiting
to obtain a connection from the pool
return waitQueue.size();
|
public com.sun.enterprise.resource.AbstractResourcePool$PoolCounters | getPoolCounters()
return this.poolCounters;
|
public java.lang.String | getPoolName()query the name of this pool. Required by monitoring
return name;
|
public ResourceHandle | getResource(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)returns resource from the pool.
//Note: this method should not be synchronized or the
// startTime would be incorrect for threads waiting to enter
/*
* Here are all the comments for the method put togethar for
* easy reference.
* 1.
// - Try to get a free resource. Note: internalGetResource()
// will create a new resource if none is free and the max has
// not been reached.
// - If can't get one, get on the wait queue.
// - Repeat this until maxWaitTime expires.
// - If maxWaitTime == 0, repeat indefinitely.
2.
//the doFailAllConnectionsProcessing method would already
//have been invoked by now.
//We simply go ahead and create a new resource here
//from the allocator that we have and adjust the resources
//list accordingly so as to not exceed the maxPoolSize ever
//(i.e if steadyPoolSize == maxPoolSize )
///Also since we are creating the resource out of the allocator
//that we came into this method with, we need not worry about
//matching
*/
ResourceHandle result = null;
long startTime = 0;
long elapsedWaitTime = 0;
long remainingWaitTime = 0;
Object waitMonitor = new Object();
if (maxWaitTime > 0) {
startTime = System.currentTimeMillis();
}
while (true) {
//See comment #1 above
result = internalGetResource(spec, alloc, tran);
if (result != null) {
// got one, return it
if (monitoringEnabled) {
poolCounters.incrementNumConnAcquired();
elapsedWaitTime = System.currentTimeMillis() - startTime;
poolCounters.setWaitTime(elapsedWaitTime);
}
//got one - seems we are not doing validation or matching
//return it
break;
} else {
// did not get a resource.
if (maxWaitTime > 0) {
elapsedWaitTime = System.currentTimeMillis() - startTime;
if (elapsedWaitTime < maxWaitTime) {
// time has not expired, determine remaining wait time.
remainingWaitTime = maxWaitTime - elapsedWaitTime;
} else {
// wait time has expired
if (monitoringEnabled) {
poolCounters.incrementNumConnTimedOut();
}
String msg = localStrings.getStringWithDefault(
"poolmgr.no.available.resource",
"No available resource. Wait-time expired.");
throw new PoolingException(msg);
}
}
synchronized (waitMonitor) {
synchronized (waitQueue) {
waitQueue.addLast(waitMonitor);
}
try {
if (_logger.isLoggable( Level.FINE) ) {
_logger.log(Level.FINE,"Resource Pool: getting on wait queue");
}
//numConnWaited++;
waitMonitor.wait(remainingWaitTime);
} catch (InterruptedException ex) {
//Could be system shutdown.
break;
}
//try to remove in case that the monitor has timed
// out. We dont expect the queue to grow to great numbers
// so the overhead for removing inexistant objects is low.
synchronized( waitQueue ) {
waitQueue.remove(waitMonitor);
}
}
}
}
alloc.fillInResourceObjects(result);
return result;
|
protected synchronized ResourceHandle | getResourceFromPool(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)return resource in free list. If none is found, try to scale up the pool/purge pool and
return a new resource. returns null if the pool new resources cannot be created.
// the order of serving a resource request
// 1. free and enlisted in the same transaction
// 2. free and unenlisted
// Do NOT give out a connection that is
// free and enlisted in a different transaction
ResourceHandle result = null;
Iterator iter = free.iterator();
while (iter.hasNext()) {
ResourceHandle h = (ResourceHandle) iter.next();
if (h.hasConnectionErrorOccurred()) {
iter.remove();
continue;
}
// This check does not seem to be needed.
// TODO: Evaluate and remove this check
//h.isAssociated can only be true for
//AssocWithThreadResourcePool
if ( h.isAssociated() ) {
//Don't touch it then
continue;
}
if (matchConnection(h, alloc)) {
result = h;
break;
}
}
if (result != null) {
// set correct state
setResourceStateToBusy(result);
free.remove(result);
} else {
result = resizePoolAndGetNewResource(alloc);
}
return result;
|
private ResourceState | getResourceState(ResourceHandle h)
return h.getResourceState();
|
public int | getSteadyPoolSize()
return steadyPoolSize;
|
public long | getTotalConnectionRequestWaitTime()
return poolCounters.totalConnectionRequestWait;
|
protected ResourceHandle | getUnenlistedResource(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)To provide an unenlisted, valid, matched resource from pool.
ResourceHandle resource ;
while((resource=getResourceFromPool(spec, alloc, tran))!=null){
boolean isValid = isConnectionValid(resource, alloc);
if (resource.hasConnectionErrorOccurred() || !isValid) {
synchronized (this) {
if (failAllConnections) {
resource = createSingleResourceAndAdjustPool(alloc, spec);
//no need to match since the resource is created with the allocator of caller.
break;
} else {
resources.remove(resource);
destroyResource(resource);
//resource is invalid, continue iteration.
continue;
}
}
}
// got a matched, valid resource
break;
}
return resource;
|
private void | increaseSteadyPoolSize(int newSteadyPoolSize)
cancelResizerTask();
for (int i = resources.size(); i < newSteadyPoolSize; i++) {
createResourceAndAddToPool(allocator);
}
scheduleResizerTask();
|
private void | incrementNumConnFailedValidation()
if (monitoringEnabled) {
poolCounters.incrementNumConnFailedValidation(1);
}
|
protected synchronized void | initPool(ResourceSpec resourceSpec, ResourceAllocator allocator)
if (poolInitialized) {
return;
}
this.resourceSpec = resourceSpec;
this.allocator = allocator;
createResources(this.allocator, steadyPoolSize);
// if the idle time out is 0, then don't schedule the resizer task
if (idletime > 0) {
scheduleResizerTask();
}
poolInitialized = true;
|
protected ResourceHandle | internalGetResource(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)
if (!poolInitialized) {
initPool(spec, alloc);
}
ResourceHandle result = null;
result = prefetch( spec, alloc, tran );
if ( result != null ) {
return result;
}
try {
//comment-1: sharing is possible only if caller is marked
//shareable, so abort right here if that's not the case
if (tran != null && alloc.shareableWithinComponent() ) {
J2EETransaction j2eetran = (J2EETransaction) tran;
// case 1. look for free and enlisted in same tx
Set set = j2eetran.getResources(name);
if (set != null) {
Iterator iter = set.iterator();
while (iter.hasNext()) {
ResourceHandle h = (ResourceHandle) iter.next();
if (h.hasConnectionErrorOccurred()) {
iter.remove();
continue;
}
ResourceState state = h.getResourceState();
/*
* One can share a resource only for the following conditions:
* 1. The caller resource is shareable (look at the outermost
* if marked comment-1
* 2. The resource enlisted inside the transaction is shareable
* 3. We are dealing with XA resources OR
* We are deling with a non-XA resource that's not in use
* Note that sharing a non-xa resource that's in use involves
* associating physical connections.
* 4. The credentials of the resources match
*/
if (h.getResourceAllocator().shareableWithinComponent()) {
if (spec.isXA() || isNonXAResourceAndFree(j2eetran, h)) {
if (matchConnections) {
if (!alloc.matchConnection(h)) {
if (monitoringEnabled) {
poolCounters.incrementNumConnNotSuccessfullyMatched();
}
continue;
}
if (h.hasConnectionErrorOccurred()) {
if (failAllConnections) {
//if failAllConnections has happened, we flushed the
//pool, so we don't have to do iter.remove else we
//will get a ConncurrentModificationException
result = null;
break;
}
iter.remove();
continue;
}
if (monitoringEnabled) {
poolCounters.incrementNumConnSuccessfullyMatched();
}
}
if (state.isFree())
setResourceStateToBusy(h);
result = h;
break;
}
}
}
}
}
} catch(ClassCastException e) {
_logger.log(Level.FINE, "Pool: getResource : " +
"transaction is not J2EETransaction but a " + tran.getClass().getName() , e);
}
// We didnt get a connections that is already enlisted in a transaction.
if (result == null) {
result = getUnenlistedResource(spec, alloc, tran);
//Only getting of an unenlisted resource results in
//an increment of the connection used stat
if (result != null){
if(maxConnectionUsage_ > 0){
result.incrementUsageCount();
}
if(monitoringEnabled) {
poolCounters.incrementNumConnUsed();
}
}
}
return result;
|
private boolean | isConnectionValid(ResourceHandle h, ResourceAllocator alloc)Check whether the connection is valid
boolean connectionValid = true;
if (validation || validateAtmostEveryIdleSecs) {
long validationPeriod;
//validation period is idle timeout if validateAtmostEveryIdleSecs is set to true
//else it is validateAtmostPeriodInMilliSeconds_
if (validation)
validationPeriod = validateAtmostPeriodInMilliSeconds_;
else
validationPeriod = idletime;
boolean validationRequired = true;
long currentTime = h.getLastValidated();
if (validationPeriod > 0) {
currentTime = System.currentTimeMillis();
long timeSinceValidation = currentTime - h.getLastValidated();
if (timeSinceValidation < validationPeriod)
validationRequired = false;
}
if (validationRequired) {
if (!alloc.isConnectionValid(h)) {
connectionValid = false;
incrementNumConnFailedValidation();
} else {
h.setLastValidated(currentTime);
}
}
}
return connectionValid;
|
private boolean | isLocalResourceEligibleForReuse(ResourceHandle h)Check whether the local resource can be put back to pool
If true, unenlist the resource
boolean result = false;
if((!isLocalResourceInTransaction(h))){
try{
enforceDelistment(h);
}catch(SystemException se){
_logger.log(Level.FINE,"Exception while delisting the local resource forcibily from transaction",se);
return result;
}
h.getResourceState().setEnlisted(false);
result = true;
}
return result;
|
private boolean | isLocalResourceInTransaction(ResourceHandle h)Check whether the local resource in question is the one participating in transaction.
boolean result = true;
try{
J2EETransaction txn = (J2EETransaction)Switch.getSwitch().getTransactionManager().getTransaction();
if(txn != null)
result = isNonXAResourceInTransaction(txn,h);
}catch(SystemException e){
_logger.log(Level.FINE,"Exception while checking whether the resource is nonxa " +
"and is enlisted in transaction : ",e);
}
return result;
|
public boolean | isMonitoringEnabled()
return monitoringEnabled;
|
private boolean | isNonXAResource(ResourceHandle resource)Check whether the resource is non-xa
return !resource.getResourceSpec().isXA() ;
|
private boolean | isNonXAResourceAndFree(J2EETransaction tran, ResourceHandle resource)Check whether the resource is non-xa, free and is enlisted in transaction.
return resource.getResourceState().isFree() && isNonXAResource(resource) && isNonXAResourceInTransaction(tran, resource);
|
private boolean | isNonXAResourceInTransaction(J2EETransaction tran, ResourceHandle resource)Check whether the non-xa resource is enlisted in transaction.
return resource.equals(tran.getNonXAResource());
|
protected boolean | isResourceUnused(ResourceHandle h)
return getResourceState(h).isFree();
|
protected boolean | isSelfManaged()
return selfManaged_;
|
private void | killExtraResources(int numToKill)
cancelResizerTask();
Iterator iter = free.iterator();
for( int i = 0; iter.hasNext() && i < numToKill ; i++ ) {
ResourceHandle h = (ResourceHandle) iter.next();
resources.remove(h);
destroyResource( h );
iter.remove();
}
scheduleResizerTask();
|
private void | logFine(java.lang.String msg)
if ( _logger.isLoggable( Level.FINE) ) {
_logger.fine( msg );
}
|
protected boolean | matchConnection(ResourceHandle resource, ResourceAllocator alloc)check whether the connection retrieved from the pool matches with the request.
boolean matched = true;
if (matchConnections) {
matched = alloc.matchConnection(resource);
if (monitoringEnabled) {
if (matched) {
poolCounters.incrementNumConnSuccessfullyMatched();
} else {
poolCounters.incrementNumConnNotSuccessfullyMatched();
}
}
}
return matched;
|
protected void | notifyWaitingThreads()
// notify the first thread in the waitqueue
Object waitMonitor = null;
synchronized (waitQueue) {
if (waitQueue.size() > 0) {
waitMonitor = waitQueue.removeFirst();
}
}
if (waitMonitor != null) {
synchronized (waitMonitor) {
waitMonitor.notify();
}
}
|
protected void | performMaxConnectionUsageOperation(ResourceHandle handle)If the resource is used for maxConnectionUsage times, destroy and create one
if (handle.getUsageCount() >= maxConnectionUsage_) {
resources.remove(handle);
free.remove(handle);
destroyResource(handle);
_logger.log(Level.INFO, "resource_pool.remove_max_used_conn", handle.getUsageCount());
//compensate with a new resource only when the pool-size is less than steady-pool-size
if(resources.size() < steadyPoolSize){
try {
createResourceAndAddToPool(handle.getResourceAllocator());
} catch (Exception e) {
_logger.log(Level.WARNING, "resource_pool.failed_creating_resource", e);
}
}
}
|
private void | potentialConnectionLeakFound(ResourceHandle resourceHandle)Logs the potential connection leaks
synchronized(connectionLeakLock){
if(connectionLeakThreadStackHashMap.containsKey(resourceHandle)){
StackTraceElement[] threadStack = connectionLeakThreadStackHashMap.remove(resourceHandle);
printConnectionLeakTrace(threadStack);
connectionLeakTimerTaskHashMap.remove(resourceHandle);
if(connectionLeakReclaim_)
freeResource(resourceHandle);
if(monitoringEnabled)
poolCounters.incrementNumPotentialConnLeak();
}
}
|
protected abstract ResourceHandle | prefetch(ResourceSpec spec, ResourceAllocator alloc, javax.transaction.Transaction tran)
|
private void | printConnectionLeakTrace(java.lang.StackTraceElement[] threadStackTrace)Prints the stack trace of thread leaking connection to server logs
StringBuffer stackTrace = new StringBuffer();
String msg = localStrings.getStringWithDefault(
"potential.connection.leak.msg",
"A potential connection leak detected for connection pool " + name +
". The stack trace of the thread is provided below : ",
new Object[]{name});
stackTrace.append(msg + "\n");
for(int i=2; i < threadStackTrace.length; i++)
stackTrace.append(threadStackTrace[i].toString() + "\n");
if(monitoringEnabled){
msg = localStrings.getStringWithDefault("monitoring.statistics", "Monitoring Statistics :");
stackTrace.append("\n" + msg + "\n");
stackTrace.append(poolCounters.toString());
}
_logger.log(Level.WARNING, stackTrace.toString(), "ConnectionPoolName=" + name);
|
private int | purgeResources(int quantity)Try to purge resources by size <= quantity
//Must be called from the thread holding the lock to this pool.
int freeResourcesCount = free.size();
int resourcesCount = (freeResourcesCount>=quantity) ?
quantity : freeResourcesCount;
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE, "Purging resources of size : " + resourcesCount);
}
for(int i=resourcesCount-1; i>=0;i--){
ResourceHandle resource = free.remove(i);
resources.remove(resource);
destroyResource(resource);
}
return resourcesCount;
|
public synchronized void | reconfigPoolProperties(ConnectorConnectionPool poolResource)Reconfigure the Pool's properties. The reconfigConnectorConnectionPool
method in the ConnectorRuntime will use this method (through PoolManager)
if it needs to just change pool properties and not recreate the pool
int _idleTime = Integer.parseInt(poolResource.getIdleTimeoutInSeconds())
* 1000;
if(poolInitialized){
if (_idleTime != idletime && _idleTime != 0) {
scheduleResizerTask();
}
if (_idleTime == 0) {
//resizerTask.cancel();
cancelResizerTask();
}
}
idletime = _idleTime;
resizeQuantity = Integer.parseInt(poolResource.getPoolResizeQuantity());
maxWaitTime = Integer.parseInt(poolResource.getMaxWaitTimeInMillis());
//Make sure it's not negative.
if (maxWaitTime < 0) {
maxWaitTime = 0;
}
validation = poolResource.isIsConnectionValidationRequired();
failAllConnections = poolResource.isFailAllConnections();
boolean oldConnectionLeakTracing_ = connectionLeakTracing_;
setAdvancedPoolConfiguration(poolResource);
//in case of connection leak tracing being turned off clear
//all connection leak tracing tasks
if (!connectionLeakTracing_ && oldConnectionLeakTracing_ && poolInitialized) {
clearAllConnectionLeakTasks();
}
//Self managed quantities. These are ignored if self management
//is on
if (!isSelfManaged()) {
int _maxPoolSize = Integer.parseInt(poolResource.getMaxPoolSize());
if (_maxPoolSize < steadyPoolSize) {
//should not happen, admin must throw exception when this condition happens.
//as a precaution set max pool size to steady pool size
maxPoolSize = steadyPoolSize;
} else {
maxPoolSize = _maxPoolSize;
}
int _steadyPoolSize = Integer.parseInt(poolResource.getSteadyPoolSize());
int oldSteadyPoolSize = steadyPoolSize;
if (_steadyPoolSize > maxPoolSize) {
//should not happen, admin must throw exception when this condition happens.
//as a precaution set steady pool size to max pool size
steadyPoolSize = maxPoolSize;
} else {
steadyPoolSize = _steadyPoolSize;
}
if(poolInitialized){
//In this case we need to kill extra connections in the pool
//For the case where the value is increased, we need not
//do anything
//num resources to kill is decided by the resources in the pool.
//if we have less than current maxPoolSize resources, we need to
//kill less.
int toKill = resources.size() - maxPoolSize;
if(toKill >0)
killExtraResources(toKill);
}
if (oldSteadyPoolSize != steadyPoolSize) {
if(poolInitialized){
if(oldSteadyPoolSize < steadyPoolSize)
increaseSteadyPoolSize(_steadyPoolSize);
} else if(monitoringEnabled){
poolCounters.setNumConnFree(steadyPoolSize);
}
}
}
|
private void | removeInvalidAndIdleResources()
//Find all ManagedConnections that are free/not-in-use
Set freeManagedConnections = new HashSet();
ResourceState state;
int size = free.size();
// let's cache the current time since precision is not required here.
long currentTime = System.currentTimeMillis();
for (Iterator iter = free.iterator(); iter.hasNext();) {
ResourceHandle element = (ResourceHandle) iter.next();
state = getResourceState(element);
//remove all idle-time lapsed resources.
if (currentTime - state.getTimestamp() > idletime) {
resources.remove(element);
destroyResource(element);
iter.remove();
} else {
freeManagedConnections.add(element.getResource());
}
}
removeInvalidResources(freeManagedConnections);
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "Pool: " + name + " -- Idle resources freed: " + (size - freeManagedConnections.size()));
_logger.log(Level.FINE, "Pool: " + name + " -- Invalid resources removed: " + (freeManagedConnections.size() - free.size()));
}
|
private void | removeInvalidResources(java.util.Set freeManagedConnections)Removes invalid resource handles in the pool while resizing the pool.
Uses the Connector 1.5 spec 6.5.3.4 optional RA feature to obtain
invalid ManagedConnections
try {
_logger.log(Level.FINE, "Sending to RA a set of free connections " +
"of size : " + freeManagedConnections.size());
//get Invalid ManagedConnections from the resource-adapter
Set invalidManagedConnections =
this.allocator.getInvalidConnections(freeManagedConnections);
//Find the appropriate ResourceHandle for a returned invalid
//ManagedConnection and destroy the Resourcehandle and references to
//it in resources and free list.
if (invalidManagedConnections != null) {
_logger.log(Level.FINE, "Received from RA invalid connections : "+
invalidManagedConnections.size());
for (Iterator iter = invalidManagedConnections.iterator();
iter.hasNext();) {
ManagedConnection invalidManagedConnection =
(ManagedConnection) iter.next();
for (Iterator freeResourcesIter = free.iterator();
freeResourcesIter.hasNext();) {
ResourceHandle handle =
(ResourceHandle) freeResourcesIter.next();
if (invalidManagedConnection.equals
(handle.getResource())) {
resources.remove(handle);
destroyResource(handle);
freeResourcesIter.remove();
incrementNumConnFailedValidation();
}
}
}
} else {
_logger.log(Level.FINE, "RA does not support " +
"ValidatingManagedConnectionFactory");
}
} catch (ResourceException re) {
_logger.log(Level.FINE, "ResourceException while trying to " +
"get invalid connections from MCF", re);
} catch (Exception e) {
_logger.log(Level.FINE, "Exception while trying " +
"to get invalid connections from MCF", e);
}
|
public synchronized void | resizePool(boolean forced)
//Following will be the resizers behavior
// a) If the wait queue is NOT empty, don't do anything.
// b) It should try to scale down the pool by "pool-resize" value
// c) First, Remove all invalid and idle resources, as a result one of the following may happen
// i) equivalent to "pool-reize" quantity of resources are removed
// ii) less than "pool-reize" quantity of resources are removed
// remove more resources to match pool-resize quantity, atmost to scale down till steady-pool-size
// iii) more than "pool-resize" quantity of resources are removed
// (1) if pool-size is less than steady-pool-size, bring it back to steady-pool-size.
// (2) if pool-size is greater than steady-pool-size, don't do anything.
synchronized (waitQueue) {
if (waitQueue.size() > 0) {
return;
}
}
int poolSize = resources.size();
//remove invalid and idle resource(s)
removeInvalidAndIdleResources();
int noOfResourcesRemoved = poolSize - resources.size();
if (resizeQuantity > 0 && forced) {
int moreResourcesToRemove = resizeQuantity - noOfResourcesRemoved;
moreResourcesToRemove = (moreResourcesToRemove <= resources.size() - steadyPoolSize) ? moreResourcesToRemove : 0;
ResourceHandle h;
if (moreResourcesToRemove > 0) {
Iterator iter = free.iterator();
while (iter.hasNext() && moreResourcesToRemove > 0) {
h = (ResourceHandle) iter.next();
resources.remove(h);
destroyResource(h);
iter.remove();
moreResourcesToRemove--;
}
}
}
// Now make sure that the steady pool size is met.
// eliminated block sync
if (resources.size() < steadyPoolSize) {
// Create resources to match the steady pool size
// changed to use resources.size() instead of counter
for (int i = resources.size(); i < steadyPoolSize; i++) {
try {
createResourceAndAddToPool(allocator);
} catch (PoolingException ex) {
_logger.log(Level.WARNING,
"resource_pool.resize_pool_error", ex.getMessage());
}
}
}
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "Pool: " + name + " -- Resource held: " + resources.size());
}
|
private ResourceHandle | resizePoolAndGetNewResource(ResourceAllocator alloc)Scale-up the pool to serve the new request.
If pool is at max-pool-size and free resources are found, purge unmatched
resources, create new connections and serve the request.
//Must be called from the thread holding the lock to this pool.
ResourceHandle result = null ;
int numOfConnsToCreate = 0;
if (resources.size() < steadyPoolSize) {
// May be all invalid resources are destroyed as
// a result no free resource found and no. of resources is less than steady-pool-size
numOfConnsToCreate = steadyPoolSize - resources.size();
} else if (resources.size() + resizeQuantity <= maxPoolSize) {
//Create and add resources of quantity "resizeQuantity"
numOfConnsToCreate = resizeQuantity;
} else if (resources.size() < maxPoolSize) {
// This else if "test condition" is not needed. Just to be safe.
// still few more connections (less than "resizeQuantity" and to reach the count of maxPoolSize)
// can be added
numOfConnsToCreate = maxPoolSize - resources.size();
}
if (numOfConnsToCreate > 0) {
createResources(alloc, numOfConnsToCreate);
int newResourcesIndex = free.size() - numOfConnsToCreate;
result = free.remove(newResourcesIndex);
setResourceStateToBusy(result);
}else if(free.size() > 0){
//pool cannot create more connections as it is at max-pool-size.
//If there are free resources at max-pool-size, then none of the free resources
//has matched this allocator's request (credential). Hence purge free resources
//of size <=resizeQuantity
purgeResources(resizeQuantity);
result = resizePoolAndGetNewResource(alloc);
}
return result;
|
public void | resourceClosed(ResourceHandle h)this method is called to indicate that the resource is
not used by a bean anymore
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE,"Pool: resourceClosed: " + h);
}
ResourceState state = getResourceState(h);
if(state == null){
throw new IllegalStateException("State is null");
}
if(!state.isBusy()){
throw new IllegalStateException("state.isBusy() : false");
}
setResourceStateToFree(h); // mark as not busy
state.touchTimestamp();
if (state.isUnenlisted() || (isNonXAResource(h) && isLocalResourceEligibleForReuse(h))) {
freeUnenlistedResource(h);
}
if (monitoringEnabled){
poolCounters.incrementNumConnReleased();
}
_logger.log(Level.FINE,"Pool: resourceFreed: " + h);
|
public void | resourceEnlisted(javax.transaction.Transaction tran, ResourceHandle resource)this method is called when a resource is enlisted in
transation tran
try {
J2EETransaction j2eetran = (J2EETransaction) tran;
Set set = j2eetran.getResources(name);
if (set == null) {
set = new HashSet();
j2eetran.setResources(set, name);
}
set.add(resource);
} catch(ClassCastException e) {
_logger.log(Level.FINE, "Pool: resourceEnlisted:" +
"transaction is not J2EETransaction but a " + tran.getClass().getName() , e);
}
ResourceState state = getResourceState(resource);
state.setEnlisted(true);
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE,"Pool: resourceEnlisted: " + resource);
}
|
public synchronized void | resourceErrorOccurred(ResourceHandle h)
if(_logger.isLoggable(Level.FINE)){
_logger.fine("Pool: resourceErrorOccurred: " + h);
}
if ( failAllConnections ) {
doFailAllConnectionsProcessing();
return;
}
ResourceState state = getResourceState(h);
//GJCINT - commenting out below
/**
* The reason is that normally connection error is expected
* to occur only when the connection is in use by the application.
* When there is connection validation involved, the connection
* can be checked for validity "before" it is passed to the
* application i.e. when the resource is still free. Since,
* the connection error can occur when the resource
* is free, the following is being commented out.
*/
/*
if (state == null ||
state.isBusy() == false) {
throw new IllegalStateException();
}
*/
if (state == null) {
throw new IllegalStateException();
}
// changed order of commands
//Commenting resources.remove() out since we will call an iter.remove()
//in the getUnenlistedResource method in the if check after
//matchManagedConnections or in the internalGetResource method
//If we were to call remove directly here there is always the danger
//of a ConcurrentModificationExceptionbeing thrown when we return
//
//In case of this method being called asynchronously, since
//the resource has been marked as "errorOccured", it will get
//removed in the next iteration of getUnenlistedResource
//or internalGetResource
resources.remove(h);
destroyResource(h);
|
private void | scheduleResizerTask()Schedules the resizer timer task. If a task is currently scheduled,
it would be canceled and a new one is scheduled.
if (resizerTask != null) {
//cancel the current task
resizerTask.cancel();
resizerTask = null;
}
resizerTask = new Resizer();
if (timer == null){
timer = Switch.getSwitch().getTimer();
}
timer.scheduleAtFixedRate(resizerTask, idletime, idletime);
if (_logger.isLoggable( Level.FINEST ) ) {
_logger.finest("schduled resizer task");
}
|
private void | setAdvancedPoolConfiguration(ConnectorConnectionPool poolResource)sets advanced pool properties
used during pool configuration (initialization) and re-configuration
matchConnections = poolResource.matchConnections();
//Commented from 9.1 as it is not used
/*
lazyConnectionAssoc_ = poolResource.isLazyConnectionAssoc();
lazyConnectionEnlist_ = poolResource.isLazyConnectionEnlist();
associateWithThread_ = poolResource.isAssociateWithThread();
*/
maxConnectionUsage_ = Integer.parseInt(poolResource.getMaxConnectionUsage());
connectionCreationRetryAttempts_ = Integer.parseInt
(poolResource.getConCreationRetryAttempts());
//Converting seconds to milliseconds as TimerTask will take input in milliseconds
conCreationRetryInterval_ =
Integer.parseInt(poolResource.getConCreationRetryInterval()) * 1000;
connectionCreationRetry_ = connectionCreationRetryAttempts_ > 0;
validateAtmostPeriodInMilliSeconds_ =
Integer.parseInt(poolResource.getValidateAtmostOncePeriod()) * 1000;
connectionLeakReclaim_ = poolResource.isConnectionReclaim();
connectionLeakTimeoutInMilliSeconds_ = Integer.parseInt(
poolResource.getConnectionLeakTracingTimeout()) * 1000;
connectionLeakTracing_ = connectionLeakTimeoutInMilliSeconds_ > 0;
|
public void | setMaxPoolSize(int size)
if ( size < resources.size() ) {
synchronized( this ) {
int toKill = resources.size() - size;
if ( toKill > 0 ) {
try {
killExtraResources( toKill );
} catch( Exception re ) {
//ignore for now
if (_logger.isLoggable(Level.FINE) ) {
_logger.fine( "setMaxPoolSize:: killExtraResources " +
"throws exception: " + re.getMessage() );
}
}
}
}
}
maxPoolSize = size;
|
public void | setMonitoringEnabledHigh()
logFine("Enabling monitoring to level : HIGH");
int numConnFree = (this.poolInitialized) ? this.free.size() : this.steadyPoolSize;
if ( poolCounters == null ){
poolCounters = new HighPoolCounters(numConnFree);
}
poolCounters.reset(numConnFree);
monitoringEnabled = true;
|
public void | setMonitoringEnabledLow()
logFine("Enabling monitoring to level : LOW");
if ( poolCounters == null ){
poolCounters = new LowPoolCounters(0);
}
poolCounters.reset(0);
monitoringEnabled = true;
|
private void | setPoolConfiguration()
Context ic = Switch.getSwitch().getNamingManager().getInitialContext();
ConnectorConnectionPool poolResource;
try {
String jndiNameOfPool = ConnectorAdminServiceUtils.
getReservePrefixedJNDINameForPool(name);
poolResource = (ConnectorConnectionPool) ic.lookup(jndiNameOfPool);
} catch (NamingException ex) {
throw new PoolingException(ex);
}
idletime = Integer.parseInt(poolResource.getIdleTimeoutInSeconds()) * 1000;
maxPoolSize = Integer.parseInt(poolResource.getMaxPoolSize());
steadyPoolSize = Integer.parseInt(poolResource.getSteadyPoolSize());
if (maxPoolSize < steadyPoolSize) {
maxPoolSize = steadyPoolSize;
}
resizeQuantity = Integer.parseInt(poolResource.getPoolResizeQuantity());
maxWaitTime = Integer.parseInt(poolResource.getMaxWaitTimeInMillis());
//Make sure it's not negative.
if (maxWaitTime < 0) {
maxWaitTime = 0;
}
failAllConnections = poolResource.isFailAllConnections();
validation = poolResource.isIsConnectionValidationRequired();
validateAtmostEveryIdleSecs = poolResource.isValidateAtmostEveryIdleSecs();
setAdvancedPoolConfiguration(poolResource);
|
protected void | setResourceStateToBusy(ResourceHandle resourceHandle)marks resource as busy. This method should be used instead of directly calling
resoureHandle.getResourceState().setBusy(true)
OR
getResourceState(resourceHandle).setBusy(true)
as this method handles starting of connection leak tracing
If connection leak tracing is enabled, takes care of starting
connection leak tracing
getResourceState(resourceHandle).setBusy(true);
if(connectionLeakTracing_)
startConnectionLeakTracing(resourceHandle);
|
protected void | setResourceStateToFree(ResourceHandle resourceHandle)marks resource as free. This method should be used instead of directly calling
resoureHandle.getResourceState().setBusy(false)
OR
getResourceState(resourceHandle).setBusy(false)
as this method handles stopping of connection leak tracing
If connection leak tracing is enabled, takes care of stopping
connection leak tracing
getResourceState(resourceHandle).setBusy(false);
if(connectionLeakTracing_)
stopConnectionLeakTracing(resourceHandle);
|
public void | setSelfManaged(boolean selfManaged)
logFine( "Setting selfManaged to : " +selfManaged+" in pool : "+name );
selfManaged_ = selfManaged;
|
public void | setSteadyPoolSize(int size)
steadyPoolSize = size;
|
private void | startConnectionLeakTracing(ResourceHandle resourceHandle)starts connection leak tracing
synchronized(connectionLeakLock){
if(!connectionLeakThreadStackHashMap.containsKey(resourceHandle)){
connectionLeakThreadStackHashMap.put(resourceHandle, Thread.currentThread().getStackTrace());
ConnectionLeakTask connectionLeakTask = new ConnectionLeakTask(resourceHandle);
connectionLeakTimerTaskHashMap.put(resourceHandle, connectionLeakTask);
if(timer == null)
timer = Switch.getSwitch().getTimer();
timer.schedule(connectionLeakTask, connectionLeakTimeoutInMilliSeconds_);
}
}
|
private void | stopConnectionLeakTracing(ResourceHandle resourceHandle)stops connection leak tracing
synchronized(connectionLeakLock){
if(connectionLeakThreadStackHashMap.containsKey(resourceHandle)){
connectionLeakThreadStackHashMap.remove(resourceHandle);
ConnectionLeakTask connectionLeakTask = connectionLeakTimerTaskHashMap.remove(resourceHandle);
connectionLeakTask.cancel();
timer.purge();
}
}
|
public void | switchOnMatching()Switch on matching of connections in the pool.
matchConnections = true;
|
public java.lang.String | toString()
StringBuffer sb = new StringBuffer("Pool [");
sb.append(name);
sb.append("] PoolSize=");
sb.append(resources.size());
sb.append(" FreeResources=");
sb.append(free.size());
sb.append(" QueueSize=");
sb.append(waitQueue.size());
sb.append(" matching=");
sb.append( (matchConnections ? "on" : "off") );
sb.append(" validation=");
sb.append( (validation ? "on" : "off") );
return sb.toString();
|
public synchronized void | transactionCompleted(javax.transaction.Transaction tran, int status)this method is called when transaction tran is completed
try {
J2EETransaction j2eetran = (J2EETransaction) tran;
Set set = j2eetran.getResources(name);
if (set == null) return;
Iterator iter = set.iterator();
while (iter.hasNext()) {
ResourceHandle resource = (ResourceHandle) iter.next();
ResourceState state = getResourceState(resource);
state.setEnlisted(false);
// Application might not have closed the connection.
if ( isResourceUnused(resource) ){
freeResource(resource);
}
iter.remove();
if (_logger.isLoggable( Level.FINE ) ) {
_logger.log(Level.FINE,"Pool: transactionCompleted: " + resource);
}
}
} catch (ClassCastException e) {
_logger.log(Level.FINE, "Pool: transactionCompleted: " +
"transaction is not J2EETransaction but a " + tran.getClass().getName() , e);
}
|