You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2004/11/01 18:34:15 UTC
svn commit: rev 56257 - in geronimo/trunk/modules: assembly/src/plan connector/src/java/org/apache/geronimo/connector/deployment connector/src/java/org/apache/geronimo/connector/outbound connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig connector/src/schema connector/src/test/org/apache/geronimo/connector/deployment connector/src/test/org/apache/geronimo/connector/outbound
Author: djencks
Date: Mon Nov 1 09:34:13 2004
New Revision: 56257
Added:
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolIdleReleaserTimer.java
Modified:
geronimo/trunk/modules/assembly/src/plan/j2ee-deployer-plan.xml
geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolingAttributes.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoPool.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/PartitionedPool.java
geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/SinglePool.java
geronimo/trunk/modules/connector/src/schema/geronimo-connector_1_5.xsd
geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_0ConfigBuilderTest.java
geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java
geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java
geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/PoolDequeTest.java
Log:
GERONIMO-412. Implement minSize and idleTimeout for connection pools, and make maxSize, minSize, blockingTimeoutMilliseconds, and idleTimeoutMinutes read-write at runtime. Set default values from module builder configuration and make plan values optional. No significant testing yet.
Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-deployer-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-deployer-plan.xml (original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-deployer-plan.xml Mon Nov 1 09:34:13 2004
@@ -109,7 +109,12 @@
<gbean name="geronimo.deployer:role=ClientEJBReferenceBuilder,config=org/apache/geronimo/J2EEDeployer" class="org.openejb.deployment.RemoteEJBReferenceBuilder"/>
- <gbean name="geronimo.deployer:role=ModuleBuilder,type=Connector,config=org/apache/geronimo/J2EEDeployer" class="org.apache.geronimo.connector.deployment.ConnectorModuleBuilder"/>
+ <gbean name="geronimo.deployer:role=ModuleBuilder,type=Connector,config=org/apache/geronimo/J2EEDeployer" class="org.apache.geronimo.connector.deployment.ConnectorModuleBuilder">
+ <attribute name="defaultMaxSize" type="int">10</attribute>
+ <attribute name="defaultMinSize" type="int">0</attribute>
+ <attribute name="defaultBlockingTimeoutMilliseconds" type="int">5000</attribute>
+ <attribute name="defaultIdleTimeoutMinutes" type="int">15</attribute>
+ </gbean>
<gbean name="geronimo.deployer:role=ModuleBuilder,type=AppClient,config=org/apache/geronimo/J2EEDeployer" class="org.apache.geronimo.client.builder.AppClientModuleBuilder">
<attribute name="transactionContextManagerObjectName" type="javax.management.ObjectName">geronimo.client:type=TransactionContextManager</attribute>
Modified: geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml
==============================================================================
--- geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml (original)
+++ geronimo/trunk/modules/assembly/src/plan/j2ee-server-plan.xml Mon Nov 1 09:34:13 2004
@@ -268,7 +268,12 @@
<gbean name="geronimo.deployer:role=ClientEJBReferenceBuilder,config=org/apache/geronimo/Server" class="org.openejb.deployment.RemoteEJBReferenceBuilder"/>
- <gbean name="geronimo.deployer:role=ModuleBuilder,type=Connector,config=org/apache/geronimo/Server" class="org.apache.geronimo.connector.deployment.ConnectorModuleBuilder"/>
+ <gbean name="geronimo.deployer:role=ModuleBuilder,type=Connector,config=org/apache/geronimo/Server" class="org.apache.geronimo.connector.deployment.ConnectorModuleBuilder">
+ <attribute name="defaultMaxSize" type="int">10</attribute>
+ <attribute name="defaultMinSize" type="int">0</attribute>
+ <attribute name="defaultBlockingTimeoutMilliseconds" type="int">5000</attribute>
+ <attribute name="defaultIdleTimeoutMinutes" type="int">15</attribute>
+ </gbean>
<gbean name="geronimo.deployer:role=ModuleBuilder,type=AppClient,config=org/apache/geronimo/Server" class="org.apache.geronimo.client.builder.AppClientModuleBuilder">
<attribute name="transactionContextManagerObjectName" type="javax.management.ObjectName">geronimo.client:type=TransactionContextManager</attribute>
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/deployment/ConnectorModuleBuilder.java Mon Nov 1 09:34:13 2004
@@ -80,6 +80,8 @@
import org.apache.geronimo.xbeans.geronimo.GerDependencyType;
import org.apache.geronimo.xbeans.geronimo.GerGbeanType;
import org.apache.geronimo.xbeans.geronimo.GerResourceadapterType;
+import org.apache.geronimo.xbeans.geronimo.GerSinglepoolType;
+import org.apache.geronimo.xbeans.geronimo.GerPartitionedpoolType;
import org.apache.geronimo.xbeans.j2ee.ActivationspecType;
import org.apache.geronimo.xbeans.j2ee.AdminobjectType;
import org.apache.geronimo.xbeans.j2ee.ConfigPropertyType;
@@ -104,9 +106,17 @@
private static final String BASE_REALM_BRIDGE_NAME = "geronimo.security:service=RealmBridge,name=";
private static final String BASE_PASSWORD_CREDENTIAL_LOGIN_MODULE_NAME = "geronimo.security:service=Realm,type=PasswordCredential,name=";
+ private final int defaultMaxSize;
+ private final int defaultMinSize;
+ private final int defaultBlockingTimeoutMilliseconds;
+ private final int defaultIdleTimeoutMinutes;
private final Kernel kernel;
- public ConnectorModuleBuilder(Kernel kernel) {
+ public ConnectorModuleBuilder(int defaultMaxSize, int defaultMinSize, int defaultBlockingTimeoutMilliseconds, int defaultIdleTimeoutMinutes, Kernel kernel) {
+ this.defaultMaxSize = defaultMaxSize;
+ this.defaultMinSize = defaultMinSize;
+ this.defaultBlockingTimeoutMilliseconds = defaultBlockingTimeoutMilliseconds;
+ this.defaultIdleTimeoutMinutes = defaultIdleTimeoutMinutes;
this.kernel = kernel;
}
@@ -438,7 +448,7 @@
}
- }
+ }
//
// admin objects (think message queuse and topics)
//
@@ -451,35 +461,35 @@
}
// add configured admin objects
for (int i = 0; i < geronimoConnector.getAdminobjectArray().length; i++) {
- GerAdminobjectType gerAdminObject = geronimoConnector.getAdminobjectArray()[i];
+ GerAdminobjectType gerAdminObject = geronimoConnector.getAdminobjectArray()[i];
+
+ String adminObjectInterface = gerAdminObject.getAdminobjectInterface().getStringValue();
+ AdminobjectType adminObject = (AdminobjectType) adminObjectInterfaceMap.get(adminObjectInterface);
+ if (adminObject == null) {
+ throw new DeploymentException("No admin object declared for interface: " + adminObjectInterface);
+ }
+
+ for (int j = 0; j < gerAdminObject.getAdminobjectInstanceArray().length; j++) {
+ GerAdminobjectInstanceType gerAdminObjectInstance = gerAdminObject.getAdminobjectInstanceArray()[j];
+
+ // create the adminObjectGBean
+ GBeanInfoBuilder adminObjectInfoFactory = new GBeanInfoBuilder("org.apache.geronimo.connector.AdminObjectWrapper", cl);
+ ConfigProperty[] configProperties = getConfigProperties(adminObject.getConfigPropertyArray(), gerAdminObjectInstance.getConfigPropertySettingArray());
+ GBeanMBean adminObjectGBean = setUpDynamicGBean(adminObjectInfoFactory, configProperties, cl);
- String adminObjectInterface = gerAdminObject.getAdminobjectInterface().getStringValue();
- AdminobjectType adminObject = (AdminobjectType) adminObjectInterfaceMap.get(adminObjectInterface);
- if (adminObject == null) {
- throw new DeploymentException("No admin object declared for interface: " + adminObjectInterface);
- }
-
- for (int j = 0; j < gerAdminObject.getAdminobjectInstanceArray().length; j++) {
- GerAdminobjectInstanceType gerAdminObjectInstance = gerAdminObject.getAdminobjectInstanceArray()[j];
-
- // create the adminObjectGBean
- GBeanInfoBuilder adminObjectInfoFactory = new GBeanInfoBuilder("org.apache.geronimo.connector.AdminObjectWrapper", cl);
- ConfigProperty[] configProperties = getConfigProperties(adminObject.getConfigPropertyArray(), gerAdminObjectInstance.getConfigPropertySettingArray());
- GBeanMBean adminObjectGBean = setUpDynamicGBean(adminObjectInfoFactory, configProperties, cl);
-
- // set the standard properties
- try {
- adminObjectGBean.setAttribute("adminObjectInterface", cl.loadClass(adminObjectInterface));
- adminObjectGBean.setAttribute("adminObjectClass", cl.loadClass(adminObject.getAdminobjectClass().getStringValue()));
- } catch (Exception e) {
- throw new DeploymentException("Could not initialize AdminObject", e);
- }
-
- // add it
- ObjectName adminObjectObjectName = NameFactory.getResourceComponentName(null, null, null, null, gerAdminObjectInstance.getMessageDestinationName(), NameFactory.JCA_ADMIN_OBJECT, moduleJ2eeContext);
- earContext.addGBean(adminObjectObjectName, adminObjectGBean);
- }
- }
+ // set the standard properties
+ try {
+ adminObjectGBean.setAttribute("adminObjectInterface", cl.loadClass(adminObjectInterface));
+ adminObjectGBean.setAttribute("adminObjectClass", cl.loadClass(adminObject.getAdminobjectClass().getStringValue()));
+ } catch (Exception e) {
+ throw new DeploymentException("Could not initialize AdminObject", e);
+ }
+
+ // add it
+ ObjectName adminObjectObjectName = NameFactory.getResourceComponentName(null, null, null, null, gerAdminObjectInstance.getMessageDestinationName(), NameFactory.JCA_ADMIN_OBJECT, moduleJ2eeContext);
+ earContext.addGBean(adminObjectObjectName, adminObjectGBean);
+ }
+ }
}
private Map getActivationSpecInfoMap(MessagelistenerType[] messagelistenerArray, ClassLoader cl) throws DeploymentException {
@@ -512,9 +522,9 @@
}
GBeanInfo gbeanInfo = infoFactory.getBeanInfo();
- Class activationSpecClass = null;
try {
- activationSpecClass = cl.loadClass(activationSpecClassName);
+ //make sure the class is available, but we don't use it.
+ cl.loadClass(activationSpecClassName);
} catch (ClassNotFoundException e) {
throw new DeploymentException("Could not load ActivationSpec class", e);
}
@@ -659,24 +669,29 @@
throw new DeploymentException("Unexpected transaction support element");
}
PoolingSupport pooling = null;
- //TODO configure this
-// int idleTimeoutMinutes = 15;
if (connectionManager.getSinglePool() != null) {
- pooling = new SinglePool(connectionManager.getSinglePool().getMaxSize(),
- connectionManager.getSinglePool().getBlockingTimeoutMilliseconds(),
-// idleTimeoutMinutes,
- connectionManager.getSinglePool().getMatchOne() != null,
- connectionManager.getSinglePool().getMatchAll() != null,
- connectionManager.getSinglePool().getSelectOneAssumeMatch() != null);
+ GerSinglepoolType pool = connectionManager.getSinglePool();
+
+ pooling = new SinglePool(
+ pool.isSetMaxSize() ? pool.getMaxSize() : defaultMaxSize,
+ pool.isSetMinSize() ? pool.getMinSize() : defaultMinSize,
+ pool.isSetBlockingTimeoutMilliseconds() ? pool.getBlockingTimeoutMilliseconds() : defaultBlockingTimeoutMilliseconds,
+ pool.isSetIdleTimeoutMinutes() ? pool.getIdleTimeoutMinutes() : defaultIdleTimeoutMinutes,
+ pool.getMatchOne() != null,
+ pool.getMatchAll() != null,
+ pool.getSelectOneAssumeMatch() != null);
} else if (connectionManager.getPartitionedPool() != null) {
- pooling = new PartitionedPool(connectionManager.getPartitionedPool().getPartitionByConnectionrequestinfo() != null,
- connectionManager.getPartitionedPool().getPartitionBySubject() != null,
- connectionManager.getPartitionedPool().getMaxSize(),
- connectionManager.getPartitionedPool().getBlockingTimeoutMilliseconds(),
-// idleTimeoutMinutes,
- connectionManager.getPartitionedPool().getMatchOne() != null,
- connectionManager.getPartitionedPool().getMatchAll() != null,
- connectionManager.getPartitionedPool().getSelectOneAssumeMatch() != null);
+ GerPartitionedpoolType pool = connectionManager.getPartitionedPool();
+ pooling = new PartitionedPool(
+ pool.isSetMaxSize() ? pool.getMaxSize() : defaultMaxSize,
+ pool.isSetMinSize() ? pool.getMinSize() : defaultMinSize,
+ pool.isSetBlockingTimeoutMilliseconds() ? pool.getBlockingTimeoutMilliseconds() : defaultBlockingTimeoutMilliseconds,
+ pool.isSetIdleTimeoutMinutes() ? pool.getIdleTimeoutMinutes() : defaultIdleTimeoutMinutes,
+ pool.getMatchOne() != null,
+ pool.getMatchAll() != null,
+ pool.getSelectOneAssumeMatch() != null,
+ pool.isSetPartitionByConnectionrequestinfo(),
+ pool.isSetPartitionBySubject());
} else if (connectionManager.getNoPool() != null) {
pooling = new NoPool();
} else {
@@ -836,12 +851,19 @@
public static final GBeanInfo GBEAN_INFO;
static {
- GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(ConnectorModuleBuilder.class);
- infoFactory.addAttribute("kernel", Kernel.class, false);
- infoFactory.addInterface(ModuleBuilder.class);
- infoFactory.addInterface(ResourceReferenceBuilder.class);
- infoFactory.setConstructor(new String[] {"kernel"});
- GBEAN_INFO = infoFactory.getBeanInfo();
+ GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder(ConnectorModuleBuilder.class);
+ infoBuilder.addAttribute("defaultMaxSize", int.class, true);
+ infoBuilder.addAttribute("defaultMinSize", int.class, true);
+ infoBuilder.addAttribute("defaultBlockingTimeoutMilliseconds", int.class, true);
+ infoBuilder.addAttribute("defaultIdleTimeoutMinutes", int.class, true);
+
+ infoBuilder.addAttribute("kernel", Kernel.class, false);
+
+ infoBuilder.addInterface(ModuleBuilder.class);
+ infoBuilder.addInterface(ResourceReferenceBuilder.class);
+
+ infoBuilder.setConstructor(new String[]{"defaultMaxSize", "defaultMinSize", "defaultBlockingTimeoutMilliseconds", "defaultIdleTimeoutMinutes", "kernel"});
+ GBEAN_INFO = infoBuilder.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java Mon Nov 1 09:34:13 2004
@@ -26,6 +26,7 @@
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.transaction.manager.NamedXAResource;
+import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
/**
* @version $Rev$ $Date$
@@ -98,6 +99,18 @@
return getPooling().getPartitionMaxSize();
}
+ public void setPartitionMaxSize(int maxSize) throws InterruptedException {
+ getPooling().setPartitionMaxSize(maxSize);
+ }
+
+ public int getPartitionMinSize() {
+ return getPooling().getPartitionMinSize();
+ }
+
+ public void setPartitionMinSize(int minSize) {
+ getPooling().setPartitionMinSize(minSize);
+ }
+
public int getIdleConnectionCount() {
return getPooling().getIdleConnectionCount();
}
@@ -106,6 +119,21 @@
return getPooling().getConnectionCount();
}
+ public int getBlockingTimeoutMilliseconds() {
+ return getPooling().getBlockingTimeoutMilliseconds();
+ }
+
+ public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) {
+ getPooling().setBlockingTimeoutMilliseconds(timeoutMilliseconds);
+ }
+
+ public int getIdleTimeoutMinutes() {
+ return getPooling().getIdleTimeoutMinutes();
+ }
+
+ public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+ getPooling().setIdleTimeoutMinutes(idleTimeoutMinutes);
+ }
private ConnectionInterceptor getStack() {
return interceptors.getStack();
@@ -115,26 +143,30 @@
return interceptors.getRecoveryStack();
}
- private PoolingAttributes getPooling() {
+ //public for persistence of pooling attributes (max, min size, blocking/idle timeouts)
+ public PoolingSupport getPooling() {
return interceptors.getPoolingAttributes();
}
public interface Interceptors {
ConnectionInterceptor getStack();
+
ConnectionInterceptor getRecoveryStack();
- PoolingAttributes getPoolingAttributes();
+
+ PoolingSupport getPoolingAttributes();
}
protected static final GBeanInfo GBEAN_INFO;
static {
- GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(AbstractConnectionManager.class);
+ GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder(AbstractConnectionManager.class);
- infoFactory.addInterface(ConnectionManagerFactory.class);
- infoFactory.addInterface(PoolingAttributes.class);
+ infoBuilder.addInterface(ConnectionManagerFactory.class);
+ //these attributes are persisted via the pooling state.
+ infoBuilder.addInterface(PoolingAttributes.class);
- GBEAN_INFO = infoFactory.getBeanInfo();
+ GBEAN_INFO = infoBuilder.getBeanInfo();
}
}
Added: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java Mon Nov 1 09:34:13 2004
@@ -0,0 +1,281 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.connector.outbound;
+
+import java.util.TimerTask;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Timer;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.ResourceException;
+import javax.security.auth.Subject;
+
+import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
+import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @version $Rev: $ $Date: $
+ */
+public abstract class AbstractSinglePoolConnectionInterceptor implements ConnectionInterceptor, PoolingAttributes {
+ protected static Log log = LogFactory.getLog(SinglePoolConnectionInterceptor.class.getName());
+ protected final ConnectionInterceptor next;
+ private final ReadWriteLock resizeLock = new WriterPreferenceReadWriteLock();
+ protected FIFOSemaphore permits;
+ protected int blockingTimeoutMilliseconds;
+ protected int connectionCount = 0;
+ private long idleTimeoutMilliseconds;
+ private IdleReleaser idleReleaser;
+ protected Timer timer = PoolIdleReleaserTimer.getTimer();
+ protected int minSize = 0;
+ protected int shrinkLater = 0;
+
+ public AbstractSinglePoolConnectionInterceptor(final ConnectionInterceptor next,
+ int maxSize,
+ int minSize,
+ int blockingTimeoutMilliseconds,
+ int idleTimeoutMinutes) {
+ this.next = next;
+ this.minSize = minSize;
+ this.blockingTimeoutMilliseconds = blockingTimeoutMilliseconds;
+ setIdleTimeoutMinutes(idleTimeoutMinutes);
+ permits = new FIFOSemaphore(maxSize);
+ }
+
+ public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
+ if (connectionInfo.getManagedConnectionInfo().getManagedConnection() != null) {
+ return;
+ }
+ try {
+ resizeLock.readLock().acquire();
+ try {
+ if (permits.attempt(blockingTimeoutMilliseconds)) {
+ internalGetConnection(connectionInfo);
+ } else {
+ throw new ResourceException("No ManagedConnections available "
+ + "within configured blocking timeout ( "
+ + blockingTimeoutMilliseconds
+ + " [ms] )");
+
+ }
+ } finally {
+ resizeLock.readLock().release();
+ }
+
+ } catch (InterruptedException ie) {
+ throw new ResourceException("Interrupted while requesting permit!");
+ } // end of try-catch
+ }
+
+ protected abstract void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException;
+
+ public void returnConnection(ConnectionInfo connectionInfo,
+ ConnectionReturnAction connectionReturnAction) {
+ if (log.isTraceEnabled()) {
+ log.trace("returning connection" + connectionInfo.getConnectionHandle());
+ }
+ try {
+ resizeLock.readLock().acquire();
+ } catch (InterruptedException e) {
+ //TODO figure out something better to do here!!!
+ throw new RuntimeException("Interrupted before returning connection! Pool is now in an invalid state!");
+ }
+ try {
+ ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
+ if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE && mci.hasConnectionHandles()) {
+ return;
+ }
+
+ boolean wasInPool = internalReturn(connectionInfo, connectionReturnAction);
+
+ if (!wasInPool) {
+ permits.release();
+ }
+ } finally {
+ resizeLock.readLock().release();
+ }
+ }
+
+ protected abstract boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction);
+
+ public int getPartitionCount() {
+ return 1;
+ }
+
+ public abstract int getPartitionMaxSize();
+
+ public void setPartitionMaxSize(int maxSize) throws InterruptedException {
+ if (maxSize <= 0) {
+ throw new IllegalArgumentException("Max size must be positive, not " + maxSize);
+ }
+ if (maxSize != getPartitionMaxSize()) {
+ resizeLock.writeLock().acquire();
+ try {
+ //example: old maxsize 40, permits 20, connection count 20
+ //new maxSize 10
+ //shrinkLater is 10
+ //shrinkNow is 20
+ //2nd example: old maxsize 30, permits 10, connection count 10
+ //new maxSize 40
+ //shrinkLater and shrinkNow are 0.
+ int checkedOut = (int) permits.permits();
+ shrinkLater = checkedOut - maxSize;
+ if (shrinkLater < 0) {
+ shrinkLater = 0;
+ }
+ int shrinkNow = checkedOut + connectionCount - maxSize - shrinkLater;
+ if (shrinkNow < 0) {
+ shrinkNow = 0;
+ }
+
+ permits = new FIFOSemaphore(maxSize);
+ //1st example: acquire 10 (all)
+ //2nd example: acquire 10 (same as in old semaphore)
+ for (int i = 0; i < checkedOut - shrinkLater; i++) {
+ permits.acquire();
+ }
+ //1st example: copy 0 (none)
+ //2nd example: copy 10 (all)
+ transferConnections(maxSize, shrinkNow);
+ } finally {
+ resizeLock.writeLock().release();
+ }
+ }
+ }
+
+ protected abstract void transferConnections(int maxSize, int shrinkNow);
+
+ public abstract int getIdleConnectionCount();
+
+ public int getConnectionCount() {
+ return connectionCount;
+ }
+
+ public int getPartitionMinSize() {
+ return minSize;
+ }
+
+ public void setPartitionMinSize(int minSize) {
+ this.minSize = minSize;
+ }
+
+ public int getBlockingTimeoutMilliseconds() {
+ return blockingTimeoutMilliseconds;
+ }
+
+ public void setBlockingTimeoutMilliseconds(int blockingTimeoutMilliseconds) {
+ if (blockingTimeoutMilliseconds < 0) {
+ throw new IllegalArgumentException("blockingTimeoutMilliseconds must be positive or 0, not " + blockingTimeoutMilliseconds);
+ }
+ if (blockingTimeoutMilliseconds == 0) {
+ this.blockingTimeoutMilliseconds = Integer.MAX_VALUE;
+ } else {
+ this.blockingTimeoutMilliseconds = blockingTimeoutMilliseconds;
+ }
+ }
+
+ public int getIdleTimeoutMinutes() {
+ return (int) idleTimeoutMilliseconds / (1000 * 60);
+ }
+
+ public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+ if (idleTimeoutMinutes < 0) {
+ throw new IllegalArgumentException("idleTimeoutMinutes must be positive or 0, not " + idleTimeoutMinutes);
+ }
+ if (idleReleaser != null) {
+ idleReleaser.cancel();
+ }
+ if (idleTimeoutMinutes > 0) {
+ this.idleTimeoutMilliseconds = idleTimeoutMinutes * 60 * 1000;
+ idleReleaser = new IdleReleaser();
+ timer.schedule(idleReleaser, this.idleTimeoutMilliseconds, this.idleTimeoutMilliseconds);
+ }
+ }
+
+ protected abstract void getExpiredManagedConnectionInfos(long threshold, ArrayList killList);
+
+ protected abstract boolean addToPool(ManagedConnectionInfo mci);
+
+ private class IdleReleaser extends TimerTask {
+
+ public void run() {
+ try {
+ resizeLock.readLock().acquire();
+ } catch (InterruptedException e) {
+ return;
+ }
+ try {
+ long threshold = System.currentTimeMillis() - idleTimeoutMilliseconds;
+ ArrayList killList = new ArrayList(getPartitionMaxSize());
+ getExpiredManagedConnectionInfos(threshold, killList);
+ for (Iterator i = killList.iterator(); i.hasNext();) {
+ ManagedConnectionInfo managedConnectionInfo = (ManagedConnectionInfo) i.next();
+ ConnectionInfo killInfo = new ConnectionInfo(managedConnectionInfo);
+ internalReturn(killInfo, ConnectionReturnAction.DESTROY);
+ }
+ permits.release(killList.size());
+ } finally {
+ resizeLock.readLock().release();
+ }
+ }
+
+ }
+
+ protected class FillTask extends TimerTask {
+ private final ManagedConnectionFactory managedConnectionFactory;
+ private final Subject subject;
+ private final ConnectionRequestInfo cri;
+
+ public FillTask(ConnectionInfo connectionInfo) {
+ managedConnectionFactory = connectionInfo.getManagedConnectionInfo().getManagedConnectionFactory();
+ subject = connectionInfo.getManagedConnectionInfo().getSubject();
+ cri = connectionInfo.getManagedConnectionInfo().getConnectionRequestInfo();
+ }
+
+ public void run() {
+ try {
+ resizeLock.readLock().acquire();
+ } catch (InterruptedException e) {
+ return;
+ }
+ try {
+ while (connectionCount < minSize) {
+ ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, cri);
+ mci.setSubject(subject);
+ ConnectionInfo ci = new ConnectionInfo(mci);
+ try {
+ next.getConnection(ci);
+ } catch (ResourceException e) {
+ return;
+ }
+ boolean added = false;
+ added = addToPool(mci);
+ if (!added) {
+ internalReturn(ci, ConnectionReturnAction.DESTROY);
+ return;
+ }
+ }
+ } finally {
+ resizeLock.readLock().release();
+ }
+ }
+
+ }
+}
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/GenericConnectionManager.java Mon Nov 1 09:34:13 2004
@@ -52,7 +52,7 @@
private final ConnectionInterceptor stack;
private final ConnectionInterceptor recoveryStack;
- private final PoolingAttributes poolingSupport;
+ private final PoolingSupport poolingSupport;
/**
* Order of constructed interceptors:
@@ -110,7 +110,7 @@
return recoveryStack;
}
- public PoolingAttributes getPoolingAttributes() {
+ public PoolingSupport getPoolingAttributes() {
return poolingSupport;
}
}
@@ -119,19 +119,19 @@
public static final GBeanInfo GBEAN_INFO;
static {
- GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(GenericConnectionManager.class, AbstractConnectionManager.GBEAN_INFO);
+ GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder(GenericConnectionManager.class, AbstractConnectionManager.GBEAN_INFO);
- infoFactory.addAttribute("name", String.class, true);
- infoFactory.addAttribute("transactionSupport", TransactionSupport.class, true);
- infoFactory.addAttribute("pooling", PoolingSupport.class, true);
+ infoBuilder.addAttribute("name", String.class, true);
+ infoBuilder.addAttribute("transactionSupport", TransactionSupport.class, true);
+ infoBuilder.addAttribute("pooling", PoolingSupport.class, true);
- infoFactory.addAttribute("objectName", String.class, false);
+ infoBuilder.addAttribute("objectName", String.class, false);
- infoFactory.addReference("ConnectionTracker", ConnectionTracker.class);
- infoFactory.addReference("RealmBridge", RealmBridge.class);
- infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
+ infoBuilder.addReference("ConnectionTracker", ConnectionTracker.class);
+ infoBuilder.addReference("RealmBridge", RealmBridge.class);
+ infoBuilder.addReference("TransactionContextManager", TransactionContextManager.class);
- infoFactory.setConstructor(new String[]{
+ infoBuilder.setConstructor(new String[]{
"transactionSupport",
"pooling",
"objectName",
@@ -139,7 +139,7 @@
"ConnectionTracker",
"TransactionContextManager"});
- GBEAN_INFO = infoFactory.getBeanInfo();
+ GBEAN_INFO = infoBuilder.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java Mon Nov 1 09:34:13 2004
@@ -94,6 +94,26 @@
return singlePoolFactory.getPartitionMaxSize();
}
+ public void setPartitionMaxSize(int maxSize) throws InterruptedException {
+ singlePoolFactory.setPartitionMaxSize(maxSize);
+ for (Iterator iterator = pools.entrySet().iterator(); iterator.hasNext();) {
+ PoolingAttributes poolingAttributes = (PoolingAttributes) ((Map.Entry) iterator.next()).getValue();
+ poolingAttributes.setPartitionMaxSize(maxSize);
+ }
+ }
+
+ public int getPartitionMinSize() {
+ return singlePoolFactory.getPartitionMinSize();
+ }
+
+ public void setPartitionMinSize(int minSize) {
+ singlePoolFactory.setPartitionMinSize(minSize);
+ for (Iterator iterator = pools.entrySet().iterator(); iterator.hasNext();) {
+ PoolingAttributes poolingAttributes = (PoolingAttributes) ((Map.Entry) iterator.next()).getValue();
+ poolingAttributes.setPartitionMinSize(minSize);
+ }
+ }
+
public int getIdleConnectionCount() {
int count = 0;
for (Iterator iterator = pools.entrySet().iterator(); iterator.hasNext();) {
@@ -110,6 +130,30 @@
count += poolingAttributes.getConnectionCount();
}
return count;
+ }
+
+ public int getBlockingTimeoutMilliseconds() {
+ return singlePoolFactory.getBlockingTimeoutMilliseconds();
+ }
+
+ public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) {
+ singlePoolFactory.setBlockingTimeoutMilliseconds(timeoutMilliseconds);
+ for (Iterator iterator = pools.entrySet().iterator(); iterator.hasNext();) {
+ PoolingAttributes poolingAttributes = (PoolingAttributes) ((Map.Entry) iterator.next()).getValue();
+ poolingAttributes.setBlockingTimeoutMilliseconds(timeoutMilliseconds);
+ }
+ }
+
+ public int getIdleTimeoutMinutes() {
+ return singlePoolFactory.getIdleTimeoutMinutes();
+ }
+
+ public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+ singlePoolFactory.setIdleTimeoutMinutes(idleTimeoutMinutes);
+ for (Iterator iterator = pools.entrySet().iterator(); iterator.hasNext();) {
+ PoolingAttributes poolingAttributes = (PoolingAttributes) ((Map.Entry) iterator.next()).getValue();
+ poolingAttributes.setIdleTimeoutMinutes(idleTimeoutMinutes);
+ }
}
static class SubjectCRIKey {
Added: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolIdleReleaserTimer.java
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolIdleReleaserTimer.java Mon Nov 1 09:34:13 2004
@@ -0,0 +1,31 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.connector.outbound;
+
+import java.util.Timer;
+
+/**
+ * @version $Rev: $ $Date: $
+ */
+public class PoolIdleReleaserTimer {
+
+ private static final Timer timer = new Timer(true);
+
+ public static Timer getTimer() {
+ return timer;
+ }
+}
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolingAttributes.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolingAttributes.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/PoolingAttributes.java Mon Nov 1 09:34:13 2004
@@ -23,9 +23,23 @@
public interface PoolingAttributes {
int getPartitionCount();
- int getPartitionMaxSize();
+ int getConnectionCount();
int getIdleConnectionCount();
- int getConnectionCount();
+ int getPartitionMaxSize();
+
+ void setPartitionMaxSize(int maxSize) throws InterruptedException;
+
+ int getPartitionMinSize();
+
+ void setPartitionMinSize(int minSize);
+
+ int getBlockingTimeoutMilliseconds();
+
+ void setBlockingTimeoutMilliseconds(int timeoutMilliseconds);
+
+ int getIdleTimeoutMinutes();
+
+ void setIdleTimeoutMinutes(int idleTimeoutMinutes);
}
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java Mon Nov 1 09:34:13 2004
@@ -17,15 +17,11 @@
package org.apache.geronimo.connector.outbound;
+import java.util.ArrayList;
import java.util.Collections;
-
import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
-import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
/**
* SinglePoolConnectionInterceptor chooses a single connection from the pool. If selectOneAssumeMatch
* is true, it simply returns the selected connection.
@@ -36,184 +32,175 @@
* selected connection does match before returning it: if not it throws an exception.
*
* @version $Rev$ $Date$
- *
*/
-public class SinglePoolConnectionInterceptor implements ConnectionInterceptor, PoolingAttributes {
-
- private static Log log = LogFactory.getLog(SinglePoolConnectionInterceptor.class.getName());
+public class SinglePoolConnectionInterceptor extends AbstractSinglePoolConnectionInterceptor {
- private final ConnectionInterceptor next;
-
- private FIFOSemaphore permits;
+ private boolean selectOneAssumeMatch;
private PoolDeque pool;
- private int blockingTimeout;
- private boolean selectOneAssumeMatch;
- private int connectionCount = 0;
-
- public SinglePoolConnectionInterceptor(
- final ConnectionInterceptor next,
- int maxSize,
- int blockingTimeout,
- boolean selectOneAssumeMatch) {
- this.next = next;
- this.blockingTimeout = blockingTimeout;
- permits = new FIFOSemaphore(maxSize);
+ public SinglePoolConnectionInterceptor(final ConnectionInterceptor next,
+ int maxSize,
+ int minSize,
+ int blockingTimeoutMilliseconds,
+ int idleTimeoutMinutes,
+ boolean selectOneAssumeMatch) {
+ super(next, maxSize, minSize, blockingTimeoutMilliseconds, idleTimeoutMinutes);
pool = new PoolDeque(maxSize);
this.selectOneAssumeMatch = selectOneAssumeMatch;
}
- public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
- ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
- if (mci.getManagedConnection() != null) {
- return;
- }
- try {
- if (permits.attempt(blockingTimeout)) {
- ManagedConnectionInfo newMCI = null;
- synchronized (pool) {
- if (pool.isEmpty()) {
- next.getConnection(connectionInfo);
- connectionCount++;
- if (log.isTraceEnabled()) {
- log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
- }
- return;
- } else {
- newMCI = pool.removeLast();
- }
- if (selectOneAssumeMatch) {
- connectionInfo.setManagedConnectionInfo(newMCI);
- if (log.isTraceEnabled()) {
- log.trace("Returning pooled connection without checking matching " + connectionInfo.getManagedConnectionInfo());
- }
- return;
- }
- try {
- ManagedConnection matchedMC =
-// newMCI.getManagedConnection();
- newMCI
- .getManagedConnectionFactory()
- .matchManagedConnections(
- Collections.singleton(
- newMCI.getManagedConnection()),
- mci.getSubject(),
- mci.getConnectionRequestInfo());
- if (matchedMC != null) {
- connectionInfo.setManagedConnectionInfo(newMCI);
- if (log.isTraceEnabled()) {
- log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
- }
- return;
- } else {
- //matching failed.
- ConnectionInfo returnCI = new ConnectionInfo();
- returnCI.setManagedConnectionInfo(newMCI);
- returnConnection(
- returnCI,
- ConnectionReturnAction.RETURN_HANDLE);
- throw new ResourceException("The pooling strategy does not match the MatchManagedConnections implementation. Please investigate and reconfigure this pool");
- }
- } catch (ResourceException e) {
- //something is wrong: destroy connection, rethrow, release permit
- ConnectionInfo returnCI = new ConnectionInfo();
- returnCI.setManagedConnectionInfo(newMCI);
- returnConnection(
- returnCI,
- ConnectionReturnAction.DESTROY);
- throw e;
- } // end of try-catch
+ protected void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException {
+ synchronized (pool) {
+ ManagedConnectionInfo newMCI = null;
+ if (pool.isEmpty()) {
+ next.getConnection(connectionInfo);
+ connectionCount++;
+ if (log.isTraceEnabled()) {
+ log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
}
+ return;
} else {
- throw new ResourceException(
- "No ManagedConnections available "
- + "within configured blocking timeout ( "
- + blockingTimeout
- + " [ms] )");
-
- } // end of else
-
- } catch (InterruptedException ie) {
- throw new ResourceException("Interrupted while requesting permit!");
- } // end of try-catch
- }
-
- public void returnConnection(
- ConnectionInfo connectionInfo,
- ConnectionReturnAction connectionReturnAction) {
- if (log.isTraceEnabled()) {
- log.trace("returning connection" + connectionInfo.getConnectionHandle());
- }
- boolean wasInPool = false;
- ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
- if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
- synchronized (pool) {
- wasInPool = pool.remove(mci);
+ newMCI = pool.removeLast();
+ }
+ if (connectionCount < minSize) {
+ timer.schedule(new FillTask(connectionInfo), 10);
}
- } else {
- if (mci.hasConnectionHandles()) {
+ if (selectOneAssumeMatch) {
+ connectionInfo.setManagedConnectionInfo(newMCI);
+ if (log.isTraceEnabled()) {
+ log.trace("Returning pooled connection without checking matching " + connectionInfo.getManagedConnectionInfo());
+ }
return;
}
- } // end of else
+ try {
+ ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
+ ManagedConnection matchedMC =
+ newMCI
+ .getManagedConnectionFactory()
+ .matchManagedConnections(Collections.singleton(newMCI.getManagedConnection()),
+ mci.getSubject(),
+ mci.getConnectionRequestInfo());
+ if (matchedMC != null) {
+ connectionInfo.setManagedConnectionInfo(newMCI);
+ if (log.isTraceEnabled()) {
+ log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
+ }
+ return;
+ } else {
+ //matching failed.
+ ConnectionInfo returnCI = new ConnectionInfo();
+ returnCI.setManagedConnectionInfo(newMCI);
+ returnConnection(returnCI,
+ ConnectionReturnAction.RETURN_HANDLE);
+ throw new ResourceException("The pooling strategy does not match the MatchManagedConnections implementation. Please investigate and reconfigure this pool");
+ }
+ } catch (ResourceException e) {
+ //something is wrong: destroy connection, rethrow, release permit
+ ConnectionInfo returnCI = new ConnectionInfo();
+ returnCI.setManagedConnectionInfo(newMCI);
+ returnConnection(returnCI,
+ ConnectionReturnAction.DESTROY);
+ throw e;
+ }
+ }
+ }
+ protected boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
+ ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
ManagedConnection mc = mci.getManagedConnection();
try {
mc.cleanup();
} catch (ResourceException e) {
connectionReturnAction = ConnectionReturnAction.DESTROY;
}
-
- if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
- next.returnConnection(connectionInfo, connectionReturnAction);
- connectionCount--;
- } else {
- synchronized (pool) {
+ boolean wasInPool = false;
+ synchronized (pool) {
+ if (shrinkLater > 0) {
+ //nothing can get in the pool while shrinkLater > 0, so wasInPool is false here.
+ connectionReturnAction = ConnectionReturnAction.DESTROY;
+ shrinkLater--;
+ } else if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE) {
mci.setLastUsed(System.currentTimeMillis());
- pool.addLast(mci);
+ pool.add(mci);
+ return wasInPool;
+ } else {
+ wasInPool = pool.remove(mci);
}
-
- } // end of else
-
- if (!wasInPool) {
- permits.release();
}
- }
-
- public int getPartitionCount() {
- return 1;
+ //we must destroy connection.
+ next.returnConnection(connectionInfo, connectionReturnAction);
+ connectionCount--;
+ return wasInPool;
}
public int getPartitionMaxSize() {
return pool.capacity();
}
+ protected void transferConnections(int maxSize, int shrinkNow) {
+ //1st example: copy 0 (none)
+ //2nd example: copy 10 (all)
+ PoolDeque oldPool = pool;
+ pool = new PoolDeque(maxSize);
+ //since we have replaced pool already, pool.remove will be very fast:-)
+ for (int i = 0; i < shrinkNow; i++) {
+ ConnectionInfo killInfo = new ConnectionInfo(oldPool.peek(i));
+ internalReturn(killInfo, ConnectionReturnAction.DESTROY);
+ }
+ for (int i = shrinkNow; i < connectionCount; i++) {
+ pool.add(oldPool.peek(i));
+ }
+ }
+
public int getIdleConnectionCount() {
return pool.currentSize();
}
- public int getConnectionCount() {
- return connectionCount;
+
+ protected void getExpiredManagedConnectionInfos(long threshold, ArrayList killList) {
+ synchronized (pool) {
+ for (int i = 0; i < pool.currentSize(); i++) {
+ ManagedConnectionInfo mci = pool.peek(i);
+ if (mci.getLastUsed() < threshold) {
+ killList.add(mci);
+ }
+ }
+ }
}
+ protected boolean addToPool(ManagedConnectionInfo mci) {
+ boolean added;
+ synchronized (pool) {
+ connectionCount++;
+ added = getPartitionMaxSize() > getIdleConnectionCount();
+ if (added) {
+ pool.add(mci);
+ }
+ }
+ return added;
+ }
+
+
static class PoolDeque {
private final ManagedConnectionInfo[] deque;
- private int first = 0;
+ private final int first = 0;
private int last = -1;
public PoolDeque(int size) {
deque = new ManagedConnectionInfo[size];
}
+ //internal
public boolean isEmpty() {
return first > last;
}
-
- public void addLast(ManagedConnectionInfo mci) {
+ //internal
+ public void add(ManagedConnectionInfo mci) {
if (last == deque.length - 1) {
throw new IllegalStateException("deque is full");
}
@@ -221,14 +208,15 @@
deque[++last] = mci;
}
- public ManagedConnectionInfo peekLast() {
- if (isEmpty()) {
- throw new IllegalStateException("deque is empty");
+ //internal
+ public ManagedConnectionInfo peek(int i) {
+ if (i < first || i > last) {
+ throw new IllegalStateException("index is out of current range");
}
-
- return deque[last];
+ return deque[i];
}
+ //internal
public ManagedConnectionInfo removeLast() {
if (isEmpty()) {
throw new IllegalStateException("deque is empty");
@@ -237,6 +225,7 @@
return deque[last--];
}
+ //internal
public boolean remove(ManagedConnectionInfo mci) {
for (int i = first; i <= last; i++) {
if (deque[i] == mci) {
@@ -251,13 +240,15 @@
return false;
}
+ //internal
public int capacity() {
return deque.length;
}
+ //internal
public int currentSize() {
return last - first + 1;
}
}
-} // SinglePoolConnectionInterceptor
+}
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java Mon Nov 1 09:34:13 2004
@@ -17,18 +17,14 @@
package org.apache.geronimo.connector.outbound;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-
import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;
-import EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
/**
* This pool is the most spec-compliant pool. It can be used by itself with no partitioning.
* It is apt to be the slowest pool.
@@ -38,112 +34,136 @@
*
* @version $Rev$ $Date$
*/
-public class SinglePoolMatchAllConnectionInterceptor implements ConnectionInterceptor, PoolingAttributes {
+public class SinglePoolMatchAllConnectionInterceptor extends AbstractSinglePoolConnectionInterceptor {
+// implements ConnectionInterceptor, PoolingAttributes {
+
+// private static Log log = LogFactory.getLog(SinglePoolMatchAllConnectionInterceptor.class.getName());
- private static Log log = LogFactory.getLog(SinglePoolMatchAllConnectionInterceptor.class.getName());
+// private final ConnectionInterceptor next;
- private final ConnectionInterceptor next;
+// private Timer timer = PoolIdleReleaserTimer.getTimer();
- private FIFOSemaphore permits;
+// private FIFOSemaphore permits;
private HashMap pool;
private int maxSize;
- private int blockingTimeout;
- private int actualConnections = 0;
+// private int blockingTimeoutMilliseconds;
+
+// private long idleTimeoutMilliseconds;
+
+// private int connectionCount = 0;
+
+// private int minSize = 0;
- public SinglePoolMatchAllConnectionInterceptor(
- final ConnectionInterceptor next,
- int maxSize,
- int blockingTimeout) {
- this.next = next;
+// private IdleReleaser idleReleaser;
+// private int shrinkLater = 0;
+
+ public SinglePoolMatchAllConnectionInterceptor(final ConnectionInterceptor next,
+ int maxSize,
+ int minSize,
+ int blockingTimeoutMilliseconds,
+ int idleTimeoutMinutes) {
+
+ super(next, maxSize, minSize, blockingTimeoutMilliseconds, idleTimeoutMinutes);
+// this.next = next;
this.maxSize = maxSize;
- this.blockingTimeout = blockingTimeout;
- permits = new FIFOSemaphore(maxSize);
+// this.blockingTimeoutMilliseconds = blockingTimeoutMilliseconds;
+// permits = new FIFOSemaphore(maxSize);
pool = new HashMap(maxSize);
+// setIdleTimeoutMinutes(idleTimeoutMinutes);
}
- public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
- ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
- if (mci.getManagedConnection() != null) {
- return;
- }
- ManagedConnectionFactory managedConnectionFactory = mci.getManagedConnectionFactory();
- try {
- if (permits.attempt(blockingTimeout)) {
- synchronized (pool) {
- try {
- if (!pool.isEmpty()) {
- ManagedConnection matchedMC =
- managedConnectionFactory
- .matchManagedConnections(
- pool.keySet(),
- mci.getSubject(),
- mci.getConnectionRequestInfo());
- if (matchedMC != null) {
- connectionInfo.setManagedConnectionInfo((ManagedConnectionInfo) pool.get(matchedMC));
- pool.remove(matchedMC);
- if (log.isTraceEnabled()) {
- log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
- }
- return;
- }
- //matching failed or pool is empty
- //if pool is at maximum size, pick a cx to kill
- if (actualConnections == maxSize) {
- Iterator iterator = pool.entrySet().iterator();
- ManagedConnectionInfo kill = (ManagedConnectionInfo) ((Map.Entry) iterator.next()).getValue();
- iterator.remove();
- ConnectionInfo killInfo = new ConnectionInfo(kill);
- returnConnection(killInfo, ConnectionReturnAction.DESTROY);
- }
- next.getConnection(connectionInfo);
- actualConnections++;
- if (log.isTraceEnabled()) {
- log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
- }
- return;
+// public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
+// if (connectionInfo.getManagedConnectionInfo().getManagedConnection() != null) {
+// return;
+// }
+// try {
+// if (permits.attempt(blockingTimeoutMilliseconds)) {
+// internalGetConnection(connectionInfo);
+// } else {
+// throw new ResourceException("No ManagedConnections available "
+// + "within configured blocking timeout ( "
+// + blockingTimeoutMilliseconds
+// + " [ms] )");
+//
+// } // end of else
+//
+// } catch (InterruptedException ie) {
+// throw new ResourceException("Interrupted while requesting permit!");
+// } // end of try-catch
+// }
+
+ protected void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException {
+ synchronized (pool) {
+ try {
+ if (!pool.isEmpty()) {
+ ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
+ ManagedConnectionFactory managedConnectionFactory = mci.getManagedConnectionFactory();
+ ManagedConnection matchedMC =
+ managedConnectionFactory
+ .matchManagedConnections(pool.keySet(),
+ mci.getSubject(),
+ mci.getConnectionRequestInfo());
+ if (matchedMC != null) {
+ connectionInfo.setManagedConnectionInfo((ManagedConnectionInfo) pool.get(matchedMC));
+ pool.remove(matchedMC);
+ if (log.isTraceEnabled()) {
+ log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
+ }
+ if (connectionCount < minSize) {
+ timer.schedule(new FillTask(connectionInfo), 10);
}
- } catch (ResourceException e) {
- //something is wrong: rethrow, release permit
- permits.release();
- throw e;
+ return;
}
}
- } else {
- throw new ResourceException(
- "No ManagedConnections available "
- + "within configured blocking timeout ( "
- + blockingTimeout
- + " [ms] )");
-
- } // end of else
-
- } catch (InterruptedException ie) {
- throw new ResourceException("Interrupted while requesting permit!");
- } // end of try-catch
- }
-
- public void returnConnection(
- ConnectionInfo connectionInfo,
- ConnectionReturnAction connectionReturnAction) {
- if (log.isTraceEnabled()) {
- log.trace("returning connection" + connectionInfo.getConnectionHandle());
- }
- boolean wasInPool = false;
- ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
- if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
- synchronized (pool) {
- wasInPool = (pool.remove(mci.getManagedConnection()) != null);
- }
- } else {
- if (mci.hasConnectionHandles()) {
- return;
+ //matching failed or pool is empty
+ //if pool is at maximum size, pick a cx to kill
+ if (connectionCount == maxSize) {
+ Iterator iterator = pool.entrySet().iterator();
+ ManagedConnectionInfo kill = (ManagedConnectionInfo) ((Map.Entry) iterator.next()).getValue();
+ iterator.remove();
+ ConnectionInfo killInfo = new ConnectionInfo(kill);
+ internalReturn(killInfo, ConnectionReturnAction.DESTROY);
+ }
+ next.getConnection(connectionInfo);
+ connectionCount++;
+ if (log.isTraceEnabled()) {
+ log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
+ }
+ if (connectionCount < minSize) {
+ timer.schedule(new FillTask(connectionInfo), 10);
+ }
+
+ } catch (ResourceException e) {
+ //something is wrong: rethrow, release permit
+ permits.release();
+ throw e;
}
- } // end of else
+ }
+ }
+// public void returnConnection(ConnectionInfo connectionInfo,
+// ConnectionReturnAction connectionReturnAction) {
+// if (log.isTraceEnabled()) {
+// log.trace("returning connection" + connectionInfo.getConnectionHandle());
+// }
+// ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
+// if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE && mci.hasConnectionHandles()) {
+// return;
+// }
+//
+// boolean wasInPool = internalReturn(connectionInfo, connectionReturnAction);
+//
+// if (!wasInPool) {
+// permits.release();
+// }
+// }
+
+ protected boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
+ ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
ManagedConnection mc = mci.getManagedConnection();
try {
mc.cleanup();
@@ -151,24 +171,30 @@
connectionReturnAction = ConnectionReturnAction.DESTROY;
}
- if (connectionReturnAction == ConnectionReturnAction.DESTROY) {
- actualConnections--;
- next.returnConnection(connectionInfo, connectionReturnAction);
- } else {
- synchronized (pool) {
+ boolean wasInPool = false;
+ synchronized (pool) {
+ if (shrinkLater > 0) {
+ //nothing can get in the pool while shrinkLater > 0, so wasInPool is false here.
+ connectionReturnAction = ConnectionReturnAction.DESTROY;
+ shrinkLater--;
+ } else if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE) {
mci.setLastUsed(System.currentTimeMillis());
pool.put(mci.getManagedConnection(), mci);
+ return wasInPool;
+ } else {
+ wasInPool = pool.remove(mci.getManagedConnection()) != null;
}
}
- if (!wasInPool) {
- permits.release();
- }
+ //we must destroy connection.
+ next.returnConnection(connectionInfo, connectionReturnAction);
+ connectionCount--;
+ return wasInPool;
}
//PoolingAttributes implementation
- public int getPartitionCount() {
- return 1;
- }
+// public int getPartitionCount() {
+// return 1;
+// }
public int getPartitionMaxSize() {
return maxSize;
@@ -178,7 +204,136 @@
return pool.size();
}
- public int getConnectionCount() {
- return actualConnections;
+ protected void transferConnections(int maxSize, int shrinkNow) {
+ //1st example: copy 0 (none)
+ //2nd example: copy 10 (all)
+ HashMap oldPool = pool;
+ pool = new HashMap(maxSize);
+ //since we have replaced pool already, pool.remove will be very fast:-)
+ assert oldPool.size() == connectionCount;
+ Iterator it = oldPool.entrySet().iterator();
+ for (int i = 0; i < shrinkNow; i++) {
+ ConnectionInfo killInfo = new ConnectionInfo((ManagedConnectionInfo) ((Map.Entry)it.next()).getValue());
+ internalReturn(killInfo, ConnectionReturnAction.DESTROY);
+ }
+ for (; it.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) it.next();
+ pool.put(entry.getKey(), entry.getValue());
+ }
+
}
+
+ protected void getExpiredManagedConnectionInfos(long threshold, ArrayList killList) {
+ synchronized (pool) {
+ for (Iterator iterator = pool.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ ManagedConnectionInfo mci = (ManagedConnectionInfo) entry.getValue();
+ if (mci.getLastUsed() < threshold) {
+ killList.add(mci);
+ }
+ }
+ }
+
+ }
+
+ protected boolean addToPool(ManagedConnectionInfo mci) {
+ boolean added;
+ synchronized (pool) {
+ connectionCount++;
+ added = getPartitionMaxSize() > getIdleConnectionCount();
+ if (added) {
+ pool.put(mci.getManagedConnection(), mci);
+ }
+ }
+ return added;
+ }
+
+// public int getConnectionCount() {
+// return connectionCount;
+// }
+
+// public int getBlockingTimeoutMilliseconds() {
+// return blockingTimeoutMilliseconds;
+// }
+//
+// public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) {
+// this.blockingTimeoutMilliseconds = timeoutMilliseconds;
+// }
+
+// public int getIdleTimeoutMinutes() {
+// return (int) idleTimeoutMilliseconds / (1000 * 60);
+// }
+
+// public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+// this.idleTimeoutMilliseconds = idleTimeoutMinutes * 60 * 1000;
+// if (idleReleaser != null) {
+// idleReleaser.cancel();
+// }
+// idleReleaser = new IdleReleaser();
+// timer.schedule(idleReleaser, this.idleTimeoutMilliseconds, this.idleTimeoutMilliseconds);
+// }
+
+
+// private class IdleReleaser extends TimerTask {
+//
+// public void run() {
+// long threshold = System.currentTimeMillis() - idleTimeoutMilliseconds;
+// ManagedConnectionInfo[] killList = new ManagedConnectionInfo[pool.size()];
+// int j = 0;
+// synchronized (pool) {
+// for (Iterator iterator = pool.entrySet().iterator(); iterator.hasNext();) {
+// Map.Entry entry = (Map.Entry) iterator.next();
+// ManagedConnectionInfo mci = (ManagedConnectionInfo) entry.getValue();
+// if (mci.getLastUsed() < threshold) {
+// killList[j] = mci;
+// j++;
+// }
+// }
+// }
+// for (int i = 0; i < j; i++) {
+// ManagedConnectionInfo managedConnectionInfo = killList[i];
+// ConnectionInfo killInfo = new ConnectionInfo(managedConnectionInfo);
+// internalReturn(killInfo, ConnectionReturnAction.DESTROY);
+// }
+// permits.release(j);
+// }
+// }
+//
+// private class FillTask extends TimerTask {
+// private final ManagedConnectionFactory managedConnectionFactory;
+// private final Subject subject;
+// private final ConnectionRequestInfo cri;
+//
+// public FillTask(ConnectionInfo connectionInfo) {
+// managedConnectionFactory = connectionInfo.getManagedConnectionInfo().getManagedConnectionFactory();
+// subject = connectionInfo.getManagedConnectionInfo().getSubject();
+// cri = connectionInfo.getManagedConnectionInfo().getConnectionRequestInfo();
+// }
+//
+// public void run() {
+// while (connectionCount < minSize) {
+// ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, cri);
+// mci.setSubject(subject);
+// ConnectionInfo ci = new ConnectionInfo(mci);
+// try {
+// next.getConnection(ci);
+// } catch (ResourceException e) {
+// return;
+// }
+// boolean added = false;
+// synchronized (pool) {
+// connectionCount++;
+// added = maxSize > pool.size();
+// if (added) {
+// pool.put(mci.getManagedConnection(), mci);
+// }
+// }
+// if (!added) {
+// internalReturn(ci, ConnectionReturnAction.DESTROY);
+// return;
+// }
+// }
+// }
+// }
+
}
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoPool.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoPool.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/NoPool.java Mon Nov 1 09:34:13 2004
@@ -34,15 +34,43 @@
return 0;
}
+ public int getIdleConnectionCount() {
+ return 0;
+ }
+
+ public int getConnectionCount() {
+ return 0;
+ }
+
public int getPartitionMaxSize() {
return 0;
}
- public int getIdleConnectionCount() {
+ public void setPartitionMaxSize(int maxSize) {
+
+ }
+
+ public int getPartitionMinSize() {
return 0;
}
- public int getConnectionCount() {
+ public void setPartitionMinSize(int minSize) {
+
+ }
+
+ public int getBlockingTimeoutMilliseconds() {
+ return 0;
+ }
+
+ public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) {
+
+ }
+
+ public int getIdleTimeoutMinutes() {
return 0;
+ }
+
+ public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+
}
}
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/PartitionedPool.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/PartitionedPool.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/PartitionedPool.java Mon Nov 1 09:34:13 2004
@@ -36,8 +36,8 @@
private PoolingAttributes poolingAttributes;
- public PartitionedPool(boolean partitionByConnectionRequestInfo, boolean partitionBySubject, int maxSize, int blockingTimeoutMilliseconds, boolean matchOne, boolean matchAll, boolean selectOneAssumeMatch) {
- singlePool = new SinglePool(maxSize, blockingTimeoutMilliseconds, matchOne, matchAll, selectOneAssumeMatch);
+ public PartitionedPool(int maxSize, int minSize, int blockingTimeoutMilliseconds, int idleTimeoutMinutes, boolean matchOne, boolean matchAll, boolean selectOneAssumeMatch, boolean partitionByConnectionRequestInfo, boolean partitionBySubject) {
+ singlePool = new SinglePool(maxSize, minSize, blockingTimeoutMilliseconds, idleTimeoutMinutes, matchOne, matchAll, selectOneAssumeMatch);
this.partitionByConnectionRequestInfo = partitionByConnectionRequestInfo;
this.partitionBySubject = partitionBySubject;
}
@@ -67,11 +67,19 @@
}
public int getBlockingTimeoutMilliseconds() {
- return singlePool.getBlockingTimeoutMilliseconds();
+ return poolingAttributes.getBlockingTimeoutMilliseconds();
}
public void setBlockingTimeoutMilliseconds(int blockingTimeoutMilliseconds) {
- singlePool.setBlockingTimeoutMilliseconds(blockingTimeoutMilliseconds);
+ poolingAttributes.setBlockingTimeoutMilliseconds(blockingTimeoutMilliseconds);
+ }
+
+ public int getIdleTimeoutMinutes() {
+ return poolingAttributes.getIdleTimeoutMinutes();
+ }
+
+ public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+ poolingAttributes.setIdleTimeoutMinutes(idleTimeoutMinutes);
}
public boolean isMatchOne() {
@@ -114,6 +122,18 @@
public int getPartitionMaxSize() {
return poolingAttributes.getPartitionMaxSize();
+ }
+
+ public void setPartitionMaxSize(int maxSize) throws InterruptedException {
+ poolingAttributes.setPartitionMaxSize(maxSize);
+ }
+
+ public int getPartitionMinSize() {
+ return poolingAttributes.getPartitionMinSize();
+ }
+
+ public void setPartitionMinSize(int minSize) {
+ poolingAttributes.setPartitionMinSize(minSize);
}
public int getIdleConnectionCount() {
Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/SinglePool.java
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/SinglePool.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/connectionmanagerconfig/SinglePool.java Mon Nov 1 09:34:13 2004
@@ -23,23 +23,24 @@
import org.apache.geronimo.connector.outbound.PoolingAttributes;
/**
- *
- *
* @version $Rev$ $Date$
- *
- * */
+ */
public class SinglePool implements PoolingSupport {
private int maxSize;
+ private int minSize;
private int blockingTimeoutMilliseconds;
+ private int idleTimeoutMinutes;
private boolean matchOne;
private boolean matchAll;
private boolean selectOneAssumeMatch;
private PoolingAttributes pool;
- public SinglePool(int maxSize, int blockingTimeoutMilliseconds, boolean matchOne, boolean matchAll, boolean selectOneAssumeMatch) {
+ public SinglePool(int maxSize, int minSize, int blockingTimeoutMilliseconds, int idleTimeoutMinutes, boolean matchOne, boolean matchAll, boolean selectOneAssumeMatch) {
this.maxSize = maxSize;
+ this.minSize = minSize;
this.blockingTimeoutMilliseconds = blockingTimeoutMilliseconds;
+ this.idleTimeoutMinutes = idleTimeoutMinutes;
this.matchOne = matchOne;
this.matchAll = matchAll;
this.selectOneAssumeMatch = selectOneAssumeMatch;
@@ -53,12 +54,34 @@
this.maxSize = maxSize;
}
+ public int getMinSize() {
+ return minSize;
+ }
+
+ public void setMinSize(int minSize) {
+ this.minSize = minSize;
+ }
+
public int getBlockingTimeoutMilliseconds() {
return blockingTimeoutMilliseconds;
}
public void setBlockingTimeoutMilliseconds(int blockingTimeoutMilliseconds) {
this.blockingTimeoutMilliseconds = blockingTimeoutMilliseconds;
+ if (pool != null) {
+ pool.setBlockingTimeoutMilliseconds(blockingTimeoutMilliseconds);
+ }
+ }
+
+ public int getIdleTimeoutMinutes() {
+ return idleTimeoutMinutes;
+ }
+
+ public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
+ this.idleTimeoutMinutes = idleTimeoutMinutes;
+ if (pool != null) {
+ pool.setIdleTimeoutMinutes(idleTimeoutMinutes);
+ }
}
public boolean isMatchOne() {
@@ -87,18 +110,20 @@
public ConnectionInterceptor addPoolingInterceptors(ConnectionInterceptor tail) {
if (isMatchAll()) {
- SinglePoolMatchAllConnectionInterceptor pool = new SinglePoolMatchAllConnectionInterceptor(
- tail,
+ SinglePoolMatchAllConnectionInterceptor pool = new SinglePoolMatchAllConnectionInterceptor(tail,
getMaxSize(),
- getBlockingTimeoutMilliseconds());
+ getMinSize(),
+ getBlockingTimeoutMilliseconds(),
+ getIdleTimeoutMinutes());
this.pool = pool;
return pool;
} else {
- SinglePoolConnectionInterceptor pool = new SinglePoolConnectionInterceptor(
- tail,
+ SinglePoolConnectionInterceptor pool = new SinglePoolConnectionInterceptor(tail,
getMaxSize(),
+ getMinSize(),
getBlockingTimeoutMilliseconds(),
+ getIdleTimeoutMinutes(),
isSelectOneAssumeMatch());
this.pool = pool;
return pool;
@@ -110,14 +135,32 @@
}
public int getPartitionMaxSize() {
- return pool == null? maxSize: pool.getPartitionMaxSize();
+ return maxSize;
+ }
+
+ public void setPartitionMaxSize(int maxSize) throws InterruptedException {
+ if (pool != null) {
+ pool.setPartitionMaxSize(maxSize);
+ }
+ this.maxSize = maxSize;
+ }
+
+ public int getPartitionMinSize() {
+ return minSize;
+ }
+
+ public void setPartitionMinSize(int minSize) {
+ if (pool != null) {
+ pool.setPartitionMinSize(minSize);
+ }
+ this.minSize = minSize;
}
public int getIdleConnectionCount() {
- return pool.getIdleConnectionCount();
+ return pool == null ? 0 : pool.getIdleConnectionCount();
}
public int getConnectionCount() {
- return pool.getConnectionCount();
+ return pool == null ? 0 : pool.getConnectionCount();
}
}
Modified: geronimo/trunk/modules/connector/src/schema/geronimo-connector_1_5.xsd
==============================================================================
--- geronimo/trunk/modules/connector/src/schema/geronimo-connector_1_5.xsd (original)
+++ geronimo/trunk/modules/connector/src/schema/geronimo-connector_1_5.xsd Mon Nov 1 09:34:13 2004
@@ -287,8 +287,10 @@
<xsd:complexType name="singlepool-Type">
<xsd:sequence>
- <xsd:element name="max-size" type="xsd:int"/>
- <xsd:element name="blocking-timeout-milliseconds" type="xsd:int"/>
+ <xsd:element name="max-size" type="xsd:int" minOccurs="0"/>
+ <xsd:element name="min-size" type="xsd:int" minOccurs="0"/>
+ <xsd:element name="blocking-timeout-milliseconds" type="xsd:int" minOccurs="0"/>
+ <xsd:element name="idle-timeout-minutes" type="xsd:int" minOccurs="0"/>
<xsd:choice>
<xsd:element name="match-one"/>
<xsd:element name="match-all"/>
Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_0ConfigBuilderTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_0ConfigBuilderTest.java (original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_0ConfigBuilderTest.java Mon Nov 1 09:34:13 2004
@@ -176,7 +176,7 @@
ObjectName connectionTrackerName = new ObjectName("geronimo.connector:service=ConnectionTracker");
Kernel kernel = new Kernel("testServer");
- ConnectorModuleBuilder moduleBuilder = new ConnectorModuleBuilder(kernel);
+ ConnectorModuleBuilder moduleBuilder = new ConnectorModuleBuilder(10, 0, 5000, 15, kernel);
File rarFile = action.getRARFile();
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
@@ -230,7 +230,7 @@
JarFile rarFile = null;
try {
rarFile = DeploymentUtil.createJarFile(new File(basedir, "target/test-ear-noger.ear"));
- EARConfigBuilder configBuilder = new EARConfigBuilder(j2eeServer, null, connectionTrackerName, null, null, null, null, null, null, new ConnectorModuleBuilder(kernel), null, null, kernel);
+ EARConfigBuilder configBuilder = new EARConfigBuilder(j2eeServer, null, connectionTrackerName, null, null, null, null, null, null, new ConnectorModuleBuilder(10, 0, 5000, 15, kernel), null, null, kernel);
File tempDir = null;
try {
tempDir = DeploymentUtil.createTempDir();
Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java (original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java Mon Nov 1 09:34:13 2004
@@ -121,7 +121,7 @@
ObjectName connectionTrackerName = new ObjectName("geronimo.connector:service=ConnectionTracker");
Kernel kernel = new Kernel("testServer");
- ConnectorModuleBuilder moduleBuilder = new ConnectorModuleBuilder(kernel);
+ ConnectorModuleBuilder moduleBuilder = new ConnectorModuleBuilder(10, 0, 5000, 15, kernel);
File rarFile = action.getRARFile();
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java (original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionManagerTestUtils.java Mon Nov 1 09:34:13 2004
@@ -53,7 +53,9 @@
protected boolean useThreadCaching = false;
protected boolean useTransactions = true;
protected int maxSize = 10;
+ protected int minSize = 0;
protected int blockingTimeout = 100;
+ protected int idleTimeoutMinutes = 15;
protected boolean useConnectionRequestInfo = false;
protected boolean useSubject = true;
private boolean matchOne = true;
@@ -75,7 +77,7 @@
protected Subject subject;
protected UserTransactionImpl userTransaction;
protected TransactionSupport transactionSupport = new XATransactions(useTransactionCaching, useThreadCaching);
- protected PoolingSupport poolingSupport = new PartitionedPool(useConnectionRequestInfo, useSubject, maxSize, blockingTimeout, matchOne, matchAll, selectOneNoMatch);
+ protected PoolingSupport poolingSupport = new PartitionedPool(maxSize, minSize, blockingTimeout, idleTimeoutMinutes, matchOne, matchAll, selectOneNoMatch, useConnectionRequestInfo, useSubject);
protected DefaultInterceptor mockComponent = new DefaultInterceptor() {
public Object invoke(InstanceContext newInstanceContext) throws Throwable {
Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/PoolDequeTest.java
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/PoolDequeTest.java (original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/PoolDequeTest.java Mon Nov 1 09:34:13 2004
@@ -40,7 +40,7 @@
public void testFill() throws Exception {
SinglePoolConnectionInterceptor.PoolDeque pool = new SinglePoolConnectionInterceptor.PoolDeque(MAX_SIZE);
for (int i = 0; i < MAX_SIZE; i++) {
- pool.addLast(new ManagedConnectionInfo(null, null));
+ pool.add(new ManagedConnectionInfo(null, null));
}
}
@@ -50,11 +50,11 @@
ManagedConnectionInfo[] mcis = new ManagedConnectionInfo[MAX_SIZE];
for (int i = 0; i < MAX_SIZE; i++) {
mcis[i] = new ManagedConnectionInfo(null, null);
- pool.addLast(mcis[i]);
+ pool.add(mcis[i]);
}
for (int i = MAX_SIZE - 1; i >= 0; i--) {
- assertTrue("Expected to get corresponding MCI from pool", mcis[i] == pool.peekLast());
+ assertTrue("Expected to get corresponding MCI from pool", mcis[i] == pool.peek(i));
assertTrue("Expected to get corresponding MCI from pool", mcis[i] == pool.removeLast());
}
assertTrue("Expected pool to be empty!", pool.isEmpty());
@@ -65,7 +65,7 @@
ManagedConnectionInfo[] mcis = new ManagedConnectionInfo[MAX_SIZE];
for (int i = 0; i < MAX_SIZE; i++) {
mcis[i] = new ManagedConnectionInfo(null, null);
- pool.addLast(mcis[i]);
+ pool.add(mcis[i]);
}
for (int i = 0; i < MAX_SIZE; i++) {