use of javax.resource.spi.RetryableUnavailableException in project Payara by payara.
the class ConnectionPool method getResource.
/**
* returns resource from the pool.
*
* @return a free pooled resource object matching the ResourceSpec
* @throws PoolingException - if any error occurrs
* - or the pool has reached its max size and the
* max-connection-wait-time-in-millis has expired.
*/
public ResourceHandle getResource(ResourceSpec spec, ResourceAllocator alloc, Transaction txn) throws PoolingException, RetryableUnavailableException {
// 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 together 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 = System.currentTimeMillis();
long elapsedWaitTime;
long remainingWaitTime = 0;
while (true) {
if (gateway.allowed()) {
// See comment #1 above
JavaEETransaction jtx = ((JavaEETransaction) txn);
Set resourcesSet = null;
if (jtx != null) {
resourcesSet = jtx.getResources(poolInfo);
}
// already obtained in the current transaction.
if (!blocked || (resourcesSet != null && resourcesSet.size() > 0)) {
try {
result = internalGetResource(spec, alloc, txn);
} finally {
gateway.acquiredResource();
}
}
}
if (result != null) {
// got one, return it
if (poolLifeCycleListener != null) {
poolLifeCycleListener.connectionAcquired(result.getId());
elapsedWaitTime = System.currentTimeMillis() - startTime;
poolLifeCycleListener.connectionRequestServed(elapsedWaitTime);
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "Resource Pool: elapsed time " + "(ms) to get connection for [" + spec + "] : " + elapsedWaitTime);
}
}
// 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 {
if (!blocked) {
// wait time has expired
if (poolLifeCycleListener != null) {
poolLifeCycleListener.connectionTimedOut();
}
String msg = localStrings.getStringWithDefault("poolmgr.no.available.resource", "No available resource. Wait-time expired.");
throw new PoolingException(msg);
}
}
}
if (!blocked) {
// add to wait-queue
Object waitMonitor = new Object();
if (poolLifeCycleListener != null) {
poolLifeCycleListener.connectionRequestQueued();
}
synchronized (waitMonitor) {
waitQueue.addToQueue(waitMonitor);
try {
logFine("Resource Pool: getting on wait queue");
waitMonitor.wait(remainingWaitTime);
} catch (InterruptedException ex) {
// Could be system shutdown.
break;
}
// so the overhead for removing inexistant objects is low.
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "removing wait monitor from queue: " + waitMonitor);
}
if (waitQueue.removeFromQueue(waitMonitor)) {
if (poolLifeCycleListener != null) {
poolLifeCycleListener.connectionRequestDequeued();
}
}
}
} else {
// add to reconfig-wait-queue
Object reconfigWaitMonitor = new Object();
synchronized (reconfigWaitMonitor) {
reconfigWaitQueue.addToQueue(reconfigWaitMonitor);
try {
if (reconfigWaitTime > 0) {
if (_logger.isLoggable(Level.FINEST)) {
_logger.finest("[DRC] getting into reconfig wait queue for time [" + reconfigWaitTime + "]");
}
reconfigWaitMonitor.wait(reconfigWaitTime);
}
} catch (InterruptedException ex) {
// Could be system shutdown.
break;
}
// so the overhead for removing inexistent objects is low.
if (_logger.isLoggable(Level.FINEST)) {
_logger.log(Level.FINEST, "[DRC] removing wait monitor from reconfig-wait-queue: " + reconfigWaitMonitor);
}
reconfigWaitQueue.removeFromQueue(reconfigWaitMonitor);
if (_logger.isLoggable(Level.FINEST)) {
_logger.log(Level.FINEST, "[DRC] throwing Retryable-Unavailable-Exception");
}
RetryableUnavailableException rue = new RetryableUnavailableException("Pool Reconfigured, " + "Connection Factory can retry the lookup");
rue.setErrorCode(BadConnectionEventListener.POOL_RECONFIGURED_ERROR_CODE);
throw rue;
}
}
}
}
alloc.fillInResourceObjects(result);
return result;
}
use of javax.resource.spi.RetryableUnavailableException in project Payara by payara.
the class PoolManagerImpl method getResource.
// invoked by DataSource objects to obtain a connection
public Object getResource(ResourceSpec spec, ResourceAllocator alloc, ClientSecurityInfo info) throws PoolingException, RetryableUnavailableException {
Transaction tran = null;
boolean transactional = alloc.isTransactional();
if (transactional) {
tran = getResourceManager(spec).getTransaction();
}
ResourceHandle handle = getResourceFromPool(spec, alloc, info, tran);
if (!handle.supportsLazyAssociation()) {
spec.setLazyAssociatable(false);
}
if (spec.isLazyAssociatable() && spec.getConnectionToAssociate() != null) {
// we need to associate a new connection with it
try {
Object connection = spec.getConnectionToAssociate();
ManagedConnection dmc = (ManagedConnection) handle.getResource();
dmc.associateConnection(connection);
} catch (ResourceException e) {
putbackDirectToPool(handle, spec.getPoolInfo());
PoolingException pe = new PoolingException(e.getMessage());
pe.initCause(e);
throw pe;
}
}
// we cannot either
if (!handle.supportsLazyEnlistment()) {
spec.setLazyEnlistable(false);
}
handle.setResourceSpec(spec);
try {
if (handle.getResourceState().isUnenlisted()) {
// The spec being used here is the spec with the updated
// lazy enlistment info
// Here's the real place where we care about the correct
// resource manager (which in turn depends upon the ResourceSpec)
// and that's because if lazy enlistment needs to be done
// we need to get the LazyEnlistableResourceManager
getResourceManager(spec).enlistResource(handle);
}
} catch (Exception e) {
// In the rare cases where enlistResource throws exception, we
// should throw the resource away
putbackBadResourceToPool(handle);
_logger.log(Level.WARNING, "poolmgr.err_enlisting_res_in_getconn", spec.getPoolInfo());
logFine("rm.enlistResource threw Exception. Evicting resource from pool");
// and rethrow the exception
throw new PoolingException(e);
}
return handle.getUserConnection();
}
Aggregations