You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2010/03/18 19:09:27 UTC
svn commit: r924925 [1/2] - in /openejb/trunk/openejb3:
assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/
assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomca...
Author: dblevins
Date: Thu Mar 18 18:09:27 2010
New Revision: 924925
URL: http://svn.apache.org/viewvc?rev=924925&view=rev
Log:
More options for OPENEJB-1235
New "Flush" ability. Fixes to MaxAge and IdleTimeout. Many more tests. Weaved configuration through the system.
Added:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java (with props)
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PassthroughFactory.java (with props)
openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/LocalClientRunner.java (with props)
openejb/trunk/openejb3/container/openejb-junit/src/main/java/org/apache/openejb/junit/Transaction.java (with props)
Modified:
openejb/trunk/openejb3/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml
openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
openejb/trunk/openejb3/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/InjectionProcessor.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionType.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java
openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml
openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
openejb/trunk/openejb3/container/openejb-core/src/main/resources/default.openejb.conf
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/ConfigureServiceTest.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PoolTest.java
openejb/trunk/openejb3/container/openejb-osgi/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
Modified: openejb/trunk/openejb3/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml (original)
+++ openejb/trunk/openejb3/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml Thu Mar 18 18:09:27 2010
@@ -87,17 +87,20 @@
id="Default Stateless Container"
service="Container"
types="STATELESS"
- constructor="id, securityService, TimeOut, PoolMin, PoolSize, StrictPooling"
- class-name="org.apache.openejb.core.stateless.StatelessContainer">
+ factory-name="create"
+ class-name="org.apache.openejb.core.stateless.StatelessContainerFactory">
# Specifies the time an invokation should wait for an instance
- # of the pool to become available. This measured by default in
- # milliseconds, but other time units can be specified, such as
- # nanoseconds, microsecons, seconds or minutes. After the timeout
- # is reached, if an instance in the pool cannot be obtained, the
- # method invocation will fail.
+ # of the pool to become available.
+ #
+ # After the timeout is reached, if an instance in the pool cannot
+ # be obtained, the method invocation will fail.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
- TimeOut = 0 milliseconds
+ AccessTimeout = 0 milliseconds
# Specifies the minimum number of bean instances that should be
# in the pool for each bean. Pools are prefilled to the minimum
@@ -107,28 +110,72 @@
PoolMin 0
- # Specifies the size of the bean pools for this
- # stateless SessionBean container. If StrictPooling is not
- # used, instances will still be created beyond this number if
- # there is demand, but they will not be returned to the pool
- # and instead will be immediately destroyed.
+ # Specifies the size of the bean pools for this stateless
+ # SessionBean container. If StrictPooling is not used, instances
+ # will still be created beyond this number if there is demand, but
+ # they will not be returned to the pool and instead will be
+ # immediately destroyed.
PoolSize 10
# StrictPooling tells the container what to do when the pool
- # reaches it's maximum size and there are incoming requests
- # that need instances.
+ # reaches it's maximum size and there are incoming requests that
+ # need instances.
#
- # With strict pooling, requests will have to wait for instances
- # to become available. The pool size will never grow beyond the
- # the set PoolSize value.
+ # With strict pooling, requests will have to wait for instances to
+ # become available. The pool size will never grow beyond the the
+ # set PoolSize value. The maximum amount of time a request should
+ # wait is specified via the AccessTimeout setting.
#
# Without strict pooling, the container will create temporary
# instances to meet demand. The instances will last for just one
# method invocation and then are removed.
+ #
+ # Setting StrictPooling to false and PoolSize to 0 will result in
+ # no pooling. Instead instances will be created on demand and live
+ # for exactly one method call before being removed.
StrictPooling true
+ # Specifies the maximum time that an instance should live before
+ # it should be retired and removed from use. This will happen
+ # gracefully. Useful for situations where bean instances are
+ # designed to hold potentially expensive resources such as memory
+ # or file handles and need to be periodically cleared out.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ MaxAge = 0 hours
+
+ # Specifies the maximum time that an instance should be allowed to
+ # sit idly in the pool without use before it should be retired and
+ # removed.
+ #
+ # Note that all instances in the pool, excluding the minimum, are
+ # eligible for garbage collection by the virtual machine as per
+ # the rules of java.lang.ref.WeakReference, so the use of an
+ # IdleTimeout is not required to conserve JVM-managed memory or
+ # shrink the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ IdleTimeout = 0 minutes
+
+ # The frequency in which the container will sweep the pool and
+ # evict expired instances. Eviction is how the IdleTimeout,
+ # MaxAge, and pool "flush" functionality is enforced. Higher
+ # intervals are better. Expired instances in use while the pool
+ # is swept will still be evicted upon return to the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ PollInterval = 5 minutes
</ServiceProvider>
Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml Thu Mar 18 18:09:27 2010
@@ -87,17 +87,20 @@
id="Default Stateless Container"
service="Container"
types="STATELESS"
- constructor="id, securityService, TimeOut, PoolMin, PoolSize, StrictPooling"
- class-name="org.apache.openejb.core.stateless.StatelessContainer">
+ factory-name="create"
+ class-name="org.apache.openejb.core.stateless.StatelessContainerFactory">
# Specifies the time an invokation should wait for an instance
- # of the pool to become available. This measured by default in
- # milliseconds, but other time units can be specified, such as
- # nanoseconds, microsecons, seconds or minutes. After the timeout
- # is reached, if an instance in the pool cannot be obtained, the
- # method invocation will fail.
+ # of the pool to become available.
+ #
+ # After the timeout is reached, if an instance in the pool cannot
+ # be obtained, the method invocation will fail.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
- TimeOut = 0 milliseconds
+ AccessTimeout = 0 milliseconds
# Specifies the minimum number of bean instances that should be
# in the pool for each bean. Pools are prefilled to the minimum
@@ -107,28 +110,72 @@
PoolMin 0
- # Specifies the size of the bean pools for this
- # stateless SessionBean container. If StrictPooling is not
- # used, instances will still be created beyond this number if
- # there is demand, but they will not be returned to the pool
- # and instead will be immediately destroyed.
+ # Specifies the size of the bean pools for this stateless
+ # SessionBean container. If StrictPooling is not used, instances
+ # will still be created beyond this number if there is demand, but
+ # they will not be returned to the pool and instead will be
+ # immediately destroyed.
PoolSize 10
# StrictPooling tells the container what to do when the pool
- # reaches it's maximum size and there are incoming requests
- # that need instances.
+ # reaches it's maximum size and there are incoming requests that
+ # need instances.
#
- # With strict pooling, requests will have to wait for instances
- # to become available. The pool size will never grow beyond the
- # the set PoolSize value.
+ # With strict pooling, requests will have to wait for instances to
+ # become available. The pool size will never grow beyond the the
+ # set PoolSize value. The maximum amount of time a request should
+ # wait is specified via the AccessTimeout setting.
#
# Without strict pooling, the container will create temporary
# instances to meet demand. The instances will last for just one
# method invocation and then are removed.
+ #
+ # Setting StrictPooling to false and PoolSize to 0 will result in
+ # no pooling. Instead instances will be created on demand and live
+ # for exactly one method call before being removed.
StrictPooling true
+ # Specifies the maximum time that an instance should live before
+ # it should be retired and removed from use. This will happen
+ # gracefully. Useful for situations where bean instances are
+ # designed to hold potentially expensive resources such as memory
+ # or file handles and need to be periodically cleared out.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ MaxAge = 0 hours
+
+ # Specifies the maximum time that an instance should be allowed to
+ # sit idly in the pool without use before it should be retired and
+ # removed.
+ #
+ # Note that all instances in the pool, excluding the minimum, are
+ # eligible for garbage collection by the virtual machine as per
+ # the rules of java.lang.ref.WeakReference, so the use of an
+ # IdleTimeout is not required to conserve JVM-managed memory or
+ # shrink the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ IdleTimeout = 0 minutes
+
+ # The frequency in which the container will sweep the pool and
+ # evict expired instances. Eviction is how the IdleTimeout,
+ # MaxAge, and pool "flush" functionality is enforced. Higher
+ # intervals are better. Expired instances in use while the pool
+ # is swept will still be evicted upon return to the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ PollInterval = 5 minutes
</ServiceProvider>
Modified: openejb/trunk/openejb3/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml (original)
+++ openejb/trunk/openejb3/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml Thu Mar 18 18:09:27 2010
@@ -87,17 +87,20 @@
id="Default Stateless Container"
service="Container"
types="STATELESS"
- constructor="id, securityService, TimeOut, PoolMin, PoolSize, StrictPooling"
- class-name="org.apache.openejb.core.stateless.StatelessContainer">
+ factory-name="create"
+ class-name="org.apache.openejb.core.stateless.StatelessContainerFactory">
# Specifies the time an invokation should wait for an instance
- # of the pool to become available. This measured by default in
- # milliseconds, but other time units can be specified, such as
- # nanoseconds, microsecons, seconds or minutes. After the timeout
- # is reached, if an instance in the pool cannot be obtained, the
- # method invocation will fail.
+ # of the pool to become available.
+ #
+ # After the timeout is reached, if an instance in the pool cannot
+ # be obtained, the method invocation will fail.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
- TimeOut = 0 milliseconds
+ AccessTimeout = 0 milliseconds
# Specifies the minimum number of bean instances that should be
# in the pool for each bean. Pools are prefilled to the minimum
@@ -107,28 +110,72 @@
PoolMin 0
- # Specifies the size of the bean pools for this
- # stateless SessionBean container. If StrictPooling is not
- # used, instances will still be created beyond this number if
- # there is demand, but they will not be returned to the pool
- # and instead will be immediately destroyed.
+ # Specifies the size of the bean pools for this stateless
+ # SessionBean container. If StrictPooling is not used, instances
+ # will still be created beyond this number if there is demand, but
+ # they will not be returned to the pool and instead will be
+ # immediately destroyed.
PoolSize 10
# StrictPooling tells the container what to do when the pool
- # reaches it's maximum size and there are incoming requests
- # that need instances.
+ # reaches it's maximum size and there are incoming requests that
+ # need instances.
#
- # With strict pooling, requests will have to wait for instances
- # to become available. The pool size will never grow beyond the
- # the set PoolSize value.
+ # With strict pooling, requests will have to wait for instances to
+ # become available. The pool size will never grow beyond the the
+ # set PoolSize value. The maximum amount of time a request should
+ # wait is specified via the AccessTimeout setting.
#
# Without strict pooling, the container will create temporary
# instances to meet demand. The instances will last for just one
# method invocation and then are removed.
+ #
+ # Setting StrictPooling to false and PoolSize to 0 will result in
+ # no pooling. Instead instances will be created on demand and live
+ # for exactly one method call before being removed.
StrictPooling true
+ # Specifies the maximum time that an instance should live before
+ # it should be retired and removed from use. This will happen
+ # gracefully. Useful for situations where bean instances are
+ # designed to hold potentially expensive resources such as memory
+ # or file handles and need to be periodically cleared out.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ MaxAge = 0 hours
+
+ # Specifies the maximum time that an instance should be allowed to
+ # sit idly in the pool without use before it should be retired and
+ # removed.
+ #
+ # Note that all instances in the pool, excluding the minimum, are
+ # eligible for garbage collection by the virtual machine as per
+ # the rules of java.lang.ref.WeakReference, so the use of an
+ # IdleTimeout is not required to conserve JVM-managed memory or
+ # shrink the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ IdleTimeout = 0 minutes
+
+ # The frequency in which the container will sweep the pool and
+ # evict expired instances. Eviction is how the IdleTimeout,
+ # MaxAge, and pool "flush" functionality is enforced. Higher
+ # intervals are better. Expired instances in use while the pool
+ # is swept will still be evicted upon return to the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ PollInterval = 5 minutes
</ServiceProvider>
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/InjectionProcessor.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/InjectionProcessor.java?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/InjectionProcessor.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/InjectionProcessor.java Thu Mar 18 18:09:27 2010
@@ -20,6 +20,7 @@ package org.apache.openejb;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.AsmParameterNameLoader;
+import org.apache.openejb.util.PassthroughFactory;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;
@@ -96,7 +97,7 @@ public class InjectionProcessor<T> {
ObjectRecipe objectRecipe;
if (suppliedInstance != null) {
clazz = (Class<? extends T>) suppliedInstance.getClass();
- objectRecipe = getInstanceRecipe(suppliedInstance);
+ objectRecipe = PassthroughFactory.recipe(suppliedInstance);
} else {
objectRecipe = new ObjectRecipe(clazz);
}
@@ -203,23 +204,5 @@ public class InjectionProcessor<T> {
return context;
}
-
- private static ObjectRecipe getInstanceRecipe(Object instance) {
- ObjectRecipe recipe = new ObjectRecipe(PassthroughFactory.class);
- recipe.setFactoryMethod("create");
-
- String param = "instance"+recipe.hashCode();
-
- recipe.setConstructorArgNames(new String[]{param});
- recipe.setProperty(param, instance);
-
- return recipe;
- }
-
- public static class PassthroughFactory {
- public static Object create(Object instance) {
- return instance;
- }
- }
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java Thu Mar 18 18:09:27 2010
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
import javax.ejb.EJBAccessException;
import javax.ejb.EJBHome;
@@ -48,6 +47,7 @@ import static org.apache.openejb.core.tr
import static org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.util.Duration;
+import org.apache.openejb.util.Pool;
import org.apache.xbean.finder.ClassFinder;
/**
@@ -62,11 +62,11 @@ public class StatelessContainer implemen
private Object containerID = null;
private SecurityService securityService;
- public StatelessContainer(Object id, SecurityService securityService, Duration timeOut, int poolMin, int poolSize, boolean strictPooling) throws OpenEJBException {
+ public StatelessContainer(Object id, SecurityService securityService, Duration accessTimeout, Pool.Builder poolBuilder, int callbackThreads) {
this.containerID = id;
this.securityService = securityService;
- instanceManager = new StatelessInstanceManager(securityService, timeOut, poolMin, poolSize, strictPooling);
+ instanceManager = new StatelessInstanceManager(securityService, accessTimeout, poolBuilder, callbackThreads);
for (DeploymentInfo deploymentInfo : deploymentRegistry.values()) {
org.apache.openejb.core.CoreDeploymentInfo di = (org.apache.openejb.core.CoreDeploymentInfo) deploymentInfo;
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java?rev=924925&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java Thu Mar 18 18:09:27 2010
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.core.stateless;
+
+import org.apache.openejb.spi.SecurityService;
+import org.apache.openejb.util.Duration;
+import org.apache.openejb.util.Pool;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class StatelessContainerFactory {
+
+ private final Pool.Builder pool = new Pool.Builder();
+
+ private Integer max;
+ private Object id;
+ private SecurityService securityService;
+ private Duration accessTimeout;
+ private int callbackThreads = 5;
+
+ public void setCallbackThreads(int callbackThreads) {
+ this.callbackThreads = callbackThreads;
+ }
+
+ public void setId(Object id) {
+ this.id = id;
+ }
+
+ public void setSecurityService(SecurityService securityService) {
+ this.securityService = securityService;
+ }
+
+ /**
+ * Alias for AccessTimeout
+ * backwards compatibility
+ *
+ * @deprecated use AccessTimeout
+ * @param accessTimeout
+ */
+ public void setTimeOut(Duration accessTimeout) {
+ this.accessTimeout = accessTimeout;
+ }
+
+ /**
+ *
+ * @param accessTimeout
+ */
+ public void setAccessTimeout(Duration accessTimeout) {
+ if (this.accessTimeout == null) setTimeOut(accessTimeout);
+ }
+
+ public void setPoolMax(int max) {
+ if (this.max == null) setPoolSize(max);
+ }
+
+ /**
+ * @deprecated use PoolMax
+ * @param max
+ */
+ public void setPoolSize(int max) {
+ this.max = max;
+ pool.setPoolSize(max);
+ }
+
+ public void setPoolMin(int min) {
+ pool.setPoolMin(min);
+ }
+
+ public void setStrictPooling(boolean strict) {
+ pool.setStrictPooling(strict);
+ }
+
+ public void setMaxAge(Duration maxAge) {
+ pool.setMaxAge(maxAge);
+ }
+
+ public void setIdleTimeout(Duration idleTimeout) {
+ pool.setIdleTimeout(idleTimeout);
+ }
+
+ public void setPollInterval(Duration interval) {
+ pool.setPollInterval(interval);
+ }
+
+ public StatelessContainer create() {
+ return new StatelessContainer(id, securityService, accessTimeout, pool, callbackThreads);
+ }
+}
Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java Thu Mar 18 18:09:27 2010
@@ -25,6 +25,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.Executor;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
@@ -48,6 +51,7 @@ import org.apache.openejb.util.LogCatego
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.SafeToolkit;
import org.apache.openejb.util.Pool;
+import org.apache.openejb.util.PassthroughFactory;
import org.apache.xbean.recipe.ConstructionException;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;
@@ -55,33 +59,47 @@ import org.apache.xbean.recipe.Option;
public class StatelessInstanceManager {
private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
- protected int poolLimit = 0;
protected Duration timeout;
protected int beanCount = 0;
- protected boolean strictPooling = false;
protected final SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager");
private SecurityService securityService;
- private int poolMin = 0;
+ private final Pool.Builder poolBuilder;
+ private final Executor executor;
- public StatelessInstanceManager(SecurityService securityService, Duration timeout, int poolMin, int poolMax, boolean strictPooling) {
+ public StatelessInstanceManager(SecurityService securityService, Duration timeout, Pool.Builder poolBuilder, int callbackThreads) {
this.securityService = securityService;
- this.poolLimit = poolMax;
- this.strictPooling = strictPooling;
this.timeout = timeout;
- this.poolMin = poolMin;
-
+ this.poolBuilder = poolBuilder;
+
if (timeout.getUnit() == null) timeout.setUnit(TimeUnit.MILLISECONDS);
- if (this.poolMin > poolLimit) {
- throw new IllegalArgumentException("Minimum pool size cannot be larger than the maximum pool size: min="+ this.poolMin +", max="+poolLimit);
+
+ executor = new ThreadPoolExecutor(callbackThreads, callbackThreads*2,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>());
+ }
+
+ private class StatelessSupplier implements Pool.Supplier<Instance> {
+ private final CoreDeploymentInfo deploymentInfo;
+
+ private StatelessSupplier(CoreDeploymentInfo deploymentInfo) {
+ this.deploymentInfo = deploymentInfo;
}
-
- if (strictPooling && poolMax < 1) {
- throw new IllegalArgumentException("Cannot use strict pooling with a pool size less than one. Strict pooling blocks threads till an instance in the pool is available. Please increase the pool size or set strict pooling to false");
+
+ public void discard(Instance instance) {
+ ThreadContext ctx = new ThreadContext(deploymentInfo, null);
+ ThreadContext oldCallContext = ThreadContext.enter(ctx);
+ try {
+ freeInstance(ctx, instance);
+ } finally {
+ ThreadContext.exit(oldCallContext);
+ }
}
+ public Instance create() {
+ return createInstance(deploymentInfo);
+ }
}
-
/**
* Removes an instance from the pool and returns it for use
* by the container in business methods.
@@ -348,28 +366,41 @@ public class StatelessInstanceManager {
public void deploy(CoreDeploymentInfo deploymentInfo) {
Options options = new Options(deploymentInfo.getProperties());
- int max = options.get("PoolSize", poolLimit);
- boolean strict = options.get("StrictPooling", this.strictPooling);
- int min = options.get("PoolMin", poolMin);
+ final Pool.Builder builder = new Pool.Builder(poolBuilder);
String timeString = options.get("Timeout", this.timeout.toString());
timeString = options.get("AccessTimeout", timeString);
Duration accessTimeout = new Duration(timeString);
- Data data = new Data(max, strict, min, accessTimeout);
+ final ObjectRecipe recipe = PassthroughFactory.recipe(builder);
+ recipe.setAllProperties(deploymentInfo.getProperties());
+
+ builder.setSupplier(new StatelessSupplier(deploymentInfo));
+ builder.setExecutor(executor);
+
+ Data data = new Data(builder.build(), accessTimeout);
deploymentInfo.setContainerData(data);
+ final int min = builder.getMin();
+
+ for (int i = 0; i < min; i++) {
+ Instance obj = createInstance(deploymentInfo);
+ if (obj != null) data.getPool().add(obj);
+ }
+ }
+
+ private Instance createInstance(CoreDeploymentInfo deploymentInfo) {
ThreadContext ctx = new ThreadContext(deploymentInfo, null);
ThreadContext oldCallContext = ThreadContext.enter(ctx);
try {
- for (int i = 0; i < min; i++) {
- data.getPool().add(ceateInstance(ctx));
- }
+ return ceateInstance(ctx);
} catch (OpenEJBException e) {
- logger.error("Unable to pre-fill pool to mimimum size: " + min + " for deployment '" + deploymentInfo.getDeploymentID() + "'", e);
+ logger.error("Unable to fill pool to mimimum size: for deployment '" + deploymentInfo.getDeploymentID() + "'", e);
} finally {
ThreadContext.exit(oldCallContext);
}
+
+ return null;
}
public void undeploy(CoreDeploymentInfo deploymentInfo) {
@@ -384,9 +415,9 @@ public class StatelessInstanceManager {
private final Pool<Instance> pool;
private Duration accessTimeout;
- public Data(int poolLimit, boolean strictPooling, int min, Duration accessTimeout) {
+ public Data(Pool<Instance> pool, Duration accessTimeout) {
this.accessTimeout = accessTimeout;
- pool = new Pool<Instance>(poolLimit, min, strictPooling);
+ this.pool = pool;
}
public Duration getAccessTimeout() {
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionType.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionType.java?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionType.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/transaction/TransactionType.java Thu Mar 18 18:09:27 2010
@@ -17,6 +17,8 @@
*/
package org.apache.openejb.core.transaction;
+import javax.ejb.TransactionAttributeType;
+
public enum TransactionType {
Mandatory,
Never,
@@ -24,5 +26,17 @@ public enum TransactionType {
Required,
RequiresNew,
Supports,
- BeanManaged
+ BeanManaged;
+
+ public static TransactionType get(TransactionAttributeType type) {
+ switch (type) {
+ case REQUIRED: return Required;
+ case REQUIRES_NEW: return RequiresNew;
+ case MANDATORY: return Mandatory;
+ case NEVER: return Never;
+ case NOT_SUPPORTED: return NotSupported;
+ case SUPPORTS: return Supports;
+ default: throw new IllegalStateException("Uknown TransactionAttributeType"+ type);
+ }
+ }
}
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PassthroughFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PassthroughFactory.java?rev=924925&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PassthroughFactory.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PassthroughFactory.java Thu Mar 18 18:09:27 2010
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.util;
+
+import org.apache.xbean.recipe.ObjectRecipe;
+import org.apache.openejb.InjectionProcessor;
+
+/**
+ * @version $Rev$ $Date$
+*/
+public class PassthroughFactory {
+
+ public static Object create(Object instance) {
+ return instance;
+ }
+
+ public static ObjectRecipe recipe(Object instance) {
+ ObjectRecipe recipe = new ObjectRecipe(PassthroughFactory.class);
+ recipe.setFactoryMethod("create");
+
+ String param = "instance"+recipe.hashCode();
+
+ recipe.setConstructorArgNames(new String[]{param});
+ recipe.setProperty(param, instance);
+
+ return recipe;
+ }
+}
Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PassthroughFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java Thu Mar 18 18:09:27 2010
@@ -25,13 +25,15 @@ import java.util.NoSuchElementException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.LinkedBlockingQueue;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Any successful pop() call requires a corresponding push() or discard() call.
@@ -49,51 +51,123 @@ import java.util.concurrent.atomic.Atomi
public class Pool<T> {
private final LinkedList<Entry> pool = new LinkedList<Entry>();
- private final Semaphore maxPolicy;
- private final Semaphore minPolicy;
- private final int max;
+ private final Semaphore instances;
+ private final Semaphore available;
+ private final Semaphore minimum;
private final Executor executor;
+ private final long maxAge;
+ private final AtomicInteger poolVersion = new AtomicInteger();
+ private final Supplier<T> supplier;
- private final Supplier<T> supplier = null;
-
- public Pool(int max, int min, boolean strict) {
- this(max, min, strict, 0, 0, 0, null);
- }
+ public static class Builder<T> {
- public Pool(int max, int min, boolean strict, long maxAge, long idleTimeout, long interval, Executor executor) {
- if (min > max) greater("max", max, "min", min);
- if (maxAge != 0 && idleTimeout > maxAge) greater("MaxAge", maxAge, "IdleTimeout", idleTimeout);
- this.max = max;
- this.minPolicy = new Semaphore(min);
- if (strict) {
- this.maxPolicy = new Semaphore(max);
- } else {
- this.maxPolicy = null;
+ private int max = 10;
+ private int min = 0;
+ private boolean strict = true;
+ private Duration maxAge = new Duration(0, MILLISECONDS);
+ private Duration idleTimeout = new Duration(0, MILLISECONDS);
+ private Duration interval = new Duration(5 * 60, TimeUnit.SECONDS);
+ private Supplier<T> supplier;
+ private Executor executor;
+
+ public Builder(Builder<T> that) {
+ this.max = that.max;
+ this.min = that.min;
+ this.strict = that.strict;
+ this.maxAge = that.maxAge;
+ this.idleTimeout = that.idleTimeout;
+ this.interval = that.interval;
+ this.executor = that.executor;
+ this.supplier = that.supplier;
+ }
+
+ public Builder() {
}
- if (interval == 0) {
- interval = 60 * 1000; // one minute
+ public int getMin() {
+ return min;
}
- final boolean timeouts = maxAge > 0 || idleTimeout > 0;
+ public void setPoolMax(int max) {
+ this.max = max;
+ }
- this.executor = timeouts ? (executor != null) ? executor : createExecutor() : null;
+ /**
+ * Alias for pool size
+ * @param max
+ * @return
+ */
+ public void setPoolSize(int max) {
+ setPoolMax(max);
+ }
- if (timeouts) {
+ public void setPoolMin(int min) {
+ this.min = min;
+ }
+
+ public void setStrictPooling(boolean strict) {
+ this.strict = strict;
+ }
- final Timer timer = new Timer("PoolEviction", true);
- timer.scheduleAtFixedRate(new Eviction(maxAge, idleTimeout), idleTimeout, interval);
+ public void setMaxAge(Duration maxAge) {
+ this.maxAge = maxAge;
+ }
+
+ public void setIdleTimeout(Duration idleTimeout) {
+ this.idleTimeout = idleTimeout;
+ }
+
+ public void setPollInterval(Duration interval) {
+ this.interval = interval;
+ }
+
+ public void setSupplier(Supplier<T> supplier) {
+ this.supplier = supplier;
+ }
+
+ public void setExecutor(Executor executor) {
+ this.executor = executor;
+ }
+
+ public Pool<T> build() {
+ return new Pool(max, min, strict, maxAge.getTime(MILLISECONDS), idleTimeout.getTime(MILLISECONDS), interval.getTime(MILLISECONDS), executor, supplier);
}
}
- private ThreadPoolExecutor createExecutor() {
- return new ThreadPoolExecutor(0, 10, 60 * 60, TimeUnit.SECONDS, new LinkedBlockingQueue());
+ public Pool(int max, int min, boolean strict) {
+ this(max, min, strict, 0, 0, 0, null, null);
+ }
+
+ public Pool(int max, int min, boolean strict, long maxAge, long idleTimeout, long interval, Executor executor, Supplier<T> supplier) {
+ if (min > max) greater("max", max, "min", min);
+ if (maxAge != 0 && idleTimeout > maxAge) greater("MaxAge", maxAge, "IdleTimeout", idleTimeout);
+ this.executor = executor != null ? executor : createExecutor();
+ this.supplier = supplier != null ? supplier : new NoSupplier();
+ this.available = (strict) ? new Semaphore(max) : new Overdraft();
+ this.minimum = new Semaphore(min);
+ this.instances = new Semaphore(max);
+ this.maxAge = maxAge;
+
+ if (interval == 0) interval = 5 * 60 * 1000; // five minutes
+
+ final Timer timer = new Timer("PoolEviction", true);
+ timer.scheduleAtFixedRate(new Eviction(idleTimeout, max), idleTimeout, interval);
+ }
+
+ private Executor createExecutor() {
+ return new ThreadPoolExecutor(5, 10,
+ 0L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>());
}
private void greater(String maxName, long max, String minName, long min) {
throw new IllegalArgumentException(minName + " cannot be greater than " + maxName + ": " + minName + "=" + min + ", " + maxName + "=" + max);
}
+ public void flush() {
+ poolVersion.incrementAndGet();
+ }
+
/**
* Any successful pop() call requires a corresponding push() or discard() call
* <p/>
@@ -107,9 +181,7 @@ public class Pool<T> {
* @throws TimeoutException if no instance could be obtained within the timeout
*/
public Entry<T> pop(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
- if (maxPolicy != null) {
- if (!maxPolicy.tryAcquire(timeout, unit)) throw new TimeoutException("Waited " + timeout + " " + unit);
- }
+ if (!available.tryAcquire(timeout, unit)) throw new TimeoutException("Waited " + timeout + " " + unit);
Entry<T> entry = null;
while (entry == null) {
@@ -144,7 +216,7 @@ public class Pool<T> {
* @return true of the item as added
*/
public boolean add(T obj) {
- return (maxPolicy == null || maxPolicy.tryAcquire()) && push(obj);
+ return add(obj, 0);
}
/**
@@ -155,7 +227,14 @@ public class Pool<T> {
* @return true of the item as added
*/
public boolean add(T obj, int offset) {
- return (maxPolicy == null || maxPolicy.tryAcquire()) && push(new Entry<T>(obj, offset));
+ if (available.tryAcquire()) {
+
+ if (push(obj, offset)) return true;
+
+ available.release();
+ }
+
+ return false;
}
/**
@@ -168,7 +247,7 @@ public class Pool<T> {
* @return false if the pool max size was exceeded
*/
public boolean push(T obj) {
- return push(new Entry<T>(obj));
+ return push(obj, 0);
}
/**
@@ -177,42 +256,61 @@ public class Pool<T> {
* <p/>
* Failure to do so will increase the max pool size by one.
*
- * @param entry entry that was popped from the pool
- * @return true of the item as added
+ * @param obj object to push onto the pool
+ * @param offset
+ * @return false if the pool max size was exceeded
*/
+ private boolean push(T obj, int offset) {
+ if (instances.tryAcquire()){
+ return push(new Entry<T>(obj, offset, poolVersion.get()));
+ }
+ return false;
+ }
+
public boolean push(Entry<T> entry) {
boolean added = false;
+ boolean release = true;
+
+ try {
+ if (entry == null) return added;
- if (entry != null) {
final T obj = entry.active.getAndSet(null);
- if (entry.hard.get() == null && minPolicy.tryAcquire()) {
- entry.hard.set(obj);
- synchronized (pool) {
- if (pool.size() < max) {
- pool.addFirst(entry);
- added = true;
- }
- }
- if (!added) {
- minPolicy.release();
+ final long age = System.currentTimeMillis() - entry.created;
+
+ final boolean aged = maxAge > 0 && age > maxAge;
+ final boolean flushed = entry.version != this.poolVersion.get();
+
+ if (aged || flushed) {
+ if (entry.hasHardReference()) {
+ // Don't release the lock, this
+ // entry will be directly replaced
+ release = false;
+ executor.execute(new Replace(entry));
}
+ } else if (entry.hard.get() == null && minimum.tryAcquire()) {
+ entry.hard.set(obj);
+
+ if (!(added = insert(entry))) minimum.release();
} else {
- synchronized (pool) {
- if (pool.size() < max) {
- pool.addLast(entry);
- added = true;
- }
- }
+ added = insert(entry);
}
+ } finally {
+ if (release) available.release();
}
- if (maxPolicy != null) maxPolicy.release();
-
return added;
}
+ private boolean insert(Entry<T> entry) {
+ synchronized (pool) {
+// if (pool.size() >= max) return false;
+ pool.addFirst(entry);
+ }
+ return true;
+ }
+
/**
* Used when a call to pop() was made that returned null
* indicating that the caller has a permit to create an
@@ -225,14 +323,15 @@ public class Pool<T> {
public void discard(Entry<T> entry) {
if (entry != null) {
- final T obj = entry.active.getAndSet(null);
+ final T obj = entry.get();
if (entry.hard.compareAndSet(obj, null)) {
- minPolicy.release();
+ minimum.release();
}
+ instances.release();
}
- if (maxPolicy != null) maxPolicy.release();
+ available.release();
}
/**
@@ -260,7 +359,7 @@ public class Pool<T> {
public static class Entry<T> {
private final long created;
private long used;
-
+ private final int version;
private final SoftReference<T> soft;
private final AtomicReference<T> hard = new AtomicReference<T>();
@@ -275,32 +374,19 @@ public class Pool<T> {
* object wrapped by this Entry.
* <p/>
* This helps ensure that when an Entry is returned to the pool it is
- * always safe to call {@link java.util.concurrent.Semaphore#release()} which increases the
- * permit size by one.
- *
- * @param obj object that this Entry will wrap
- */
- private Entry(T obj) {
- this(obj, 0);
- }
-
- /**
- * Constructor is private so that it is impossible for an Entry object
- * to exist without there being a corresponding permit issued for the
- * object wrapped by this Entry.
- * <p/>
- * This helps ensure that when an Entry is returned to the pool it is
* always safe to call {@link Semaphore#release()} which increases the
* permit size by one.
*
* @param obj object that this Entry will wrap
* @param offset creation time offset, used for maxAge
+ * @param version
*/
- private Entry(T obj, int offset) {
+ private Entry(T obj, int offset, int version) {
this.soft = new SoftReference<T>(obj);
this.active.set(obj);
this.created = System.currentTimeMillis() + offset;
this.used = created;
+ this.version = version;
}
public T get() {
@@ -319,22 +405,35 @@ public class Pool<T> {
private final class Eviction extends TimerTask {
- private final long maxAge;
+ private final AtomicInteger previousVersion = new AtomicInteger(poolVersion.get());
private final long idleTimeout;
+ private final boolean timeouts;
+ private final int max;
- private Eviction(long maxAge, long idleTimeout) {
- this.maxAge = maxAge;
+ private Eviction(long idleTimeout, int max) {
this.idleTimeout = idleTimeout;
+ timeouts = maxAge > 0 || idleTimeout > 0;
+ this.max = max;
}
public void run() {
+ final int currentVersion = poolVersion.get();
+
+ final boolean isCurrent = previousVersion.getAndSet(currentVersion) == currentVersion;
+
+ // No timeouts to enforce?
+ // Pool version not changed?
+ // Just return
+ if (!timeouts && isCurrent) return;
+
final long now = System.currentTimeMillis();
final List<Entry<T>> entries = new ArrayList(max);
+ // Pull all the entries from the pool
try {
- while (true) entries.add(pop(0, TimeUnit.MILLISECONDS));
+ while (true) entries.add(pop(0, MILLISECONDS));
} catch (InterruptedException e) {
Thread.interrupted();
} catch (TimeoutException e) {
@@ -342,27 +441,35 @@ public class Pool<T> {
}
- final List<Expired> expiredList = new ArrayList<Expired>(max);
-
- { // Expire aged instances
-
- // Any "null" entries are immediately returned
- // Any non-aged "min" refs are immediately returned
+ { // Immediately return all "null" instances to free up locks
final Iterator<Entry<T>> iter = entries.iterator();
while (iter.hasNext()) {
- Entry<T> entry = iter.next();
-
+ final Entry<T> entry = iter.next();
if (entry == null) {
// return the lock immediately
push(entry);
iter.remove();
- continue;
}
+ }
+
+ }
- long age = now - entry.created;
+ final List<Expired> expiredList = new ArrayList<Expired>(max);
- if (maxAge > 0 && age > maxAge) {
+ { // Expire aged instances, enforce pool "versioning"
+
+ // Any non-aged "min" refs are immediately returned
+
+ final Iterator<Entry<T>> iter = entries.iterator();
+ while (iter.hasNext()) {
+ final Entry<T> entry = iter.next();
+
+ // is too old || is old version?
+ final boolean aged = maxAge > 0 && now - entry.created > maxAge;
+ final boolean flushed = entry.version != currentVersion;
+
+ if (aged || flushed) {
// Entry is too old, expire it
@@ -419,7 +526,7 @@ public class Pool<T> {
final long idle = now - entry.used;
- if (idle > idleTimeout) {
+ if (idleTimeout > 0 && idle > idleTimeout) {
// too lazy -- timed out
final Expired expired = new Expired(entry);
@@ -448,32 +555,32 @@ public class Pool<T> {
}
- private class Expired {
- private final Entry<T> entry;
- private final AtomicBoolean discarded = new AtomicBoolean();
+ }
- private Expired(Entry<T> entry) {
- this.entry = entry;
- }
+ private class Expired {
+ private final Entry<T> entry;
+ private final AtomicBoolean discarded = new AtomicBoolean();
- public boolean tryDiscard() {
- if (discarded.getAndSet(true)) return false;
+ private Expired(Entry<T> entry) {
+ this.entry = entry;
+ }
- discard(entry);
+ public boolean tryDiscard() {
+ if (discarded.getAndSet(true)) return false;
- return true;
- }
+ discard(entry);
+ return true;
+ }
- public boolean replaceMinEntry(Entry<T> replacement) {
- if (!entry.hasHardReference()) return false;
- if (replacement.hasHardReference()) return false;
- if (discarded.getAndSet(true)) return false;
+ public boolean replaceMinEntry(Entry<T> replacement) {
+ if (!entry.hasHardReference()) return false;
+ if (replacement.hasHardReference()) return false;
+ if (discarded.getAndSet(true)) return false;
- discardAndReplace(entry, replacement);
+ discardAndReplace(entry, replacement);
- return true;
- }
+ return true;
}
}
@@ -487,12 +594,17 @@ public class Pool<T> {
public void run() {
try {
final T t = supplier.create();
- final Entry entry = new Entry(t);
- entry.hard.set(t);
- push(entry);
+
+ if (t == null) {
+ discard(expired);
+ } else {
+ final Entry entry = new Entry(t, 0 , poolVersion.get());
+ entry.hard.set(t);
+ push(entry);
+ }
} catch (Throwable e) {
- // Possibly re-try
- // TODO: log creation failure
+ // Retry and logging should be done in
+ // the Supplier implementation
discard(expired);
}
}
@@ -517,4 +629,77 @@ public class Pool<T> {
T create();
}
+
+ private static class NoSupplier implements Supplier {
+ public void discard(Object o) {
+ }
+
+ public Object create() {
+ return null;
+ }
+ }
+
+ private static final class Overdraft extends Semaphore {
+ public Overdraft() {
+ super(0);
+ }
+
+ @Override
+ public void acquire() throws InterruptedException {
+ }
+
+ @Override
+ public void acquireUninterruptibly() {
+ }
+
+ @Override
+ public boolean tryAcquire() {
+ return true;
+ }
+
+ @Override
+ public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException {
+ return true;
+ }
+
+ @Override
+ public void release() {
+ }
+
+ @Override
+ public void acquire(int permits) throws InterruptedException {
+ }
+
+ @Override
+ public void acquireUninterruptibly(int permits) {
+ }
+
+ @Override
+ public boolean tryAcquire(int permits) {
+ return true;
+ }
+
+ @Override
+ public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException {
+ return true;
+ }
+
+ @Override
+ public void release(int permits) {
+ }
+
+ @Override
+ public int availablePermits() {
+ return 0;
+ }
+
+ @Override
+ public int drainPermits() {
+ return 0;
+ }
+
+ @Override
+ protected void reducePermits(int reduction) {
+ }
+ }
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml Thu Mar 18 18:09:27 2010
@@ -80,17 +80,20 @@
id="Default Stateless Container"
service="Container"
types="STATELESS"
- constructor="id, securityService, TimeOut, PoolMin, PoolSize, StrictPooling"
- class-name="org.apache.openejb.core.stateless.StatelessContainer">
+ factory-name="create"
+ class-name="org.apache.openejb.core.stateless.StatelessContainerFactory">
# Specifies the time an invokation should wait for an instance
- # of the pool to become available. This measured by default in
- # milliseconds, but other time units can be specified, such as
- # nanoseconds, microsecons, seconds or minutes. After the timeout
- # is reached, if an instance in the pool cannot be obtained, the
- # method invocation will fail.
+ # of the pool to become available.
+ #
+ # After the timeout is reached, if an instance in the pool cannot
+ # be obtained, the method invocation will fail.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
- TimeOut = 0 milliseconds
+ AccessTimeout = 0 milliseconds
# Specifies the minimum number of bean instances that should be
# in the pool for each bean. Pools are prefilled to the minimum
@@ -100,28 +103,72 @@
PoolMin 0
- # Specifies the size of the bean pools for this
- # stateless SessionBean container. If StrictPooling is not
- # used, instances will still be created beyond this number if
- # there is demand, but they will not be returned to the pool
- # and instead will be immediately destroyed.
+ # Specifies the size of the bean pools for this stateless
+ # SessionBean container. If StrictPooling is not used, instances
+ # will still be created beyond this number if there is demand, but
+ # they will not be returned to the pool and instead will be
+ # immediately destroyed.
PoolSize 10
# StrictPooling tells the container what to do when the pool
- # reaches it's maximum size and there are incoming requests
- # that need instances.
+ # reaches it's maximum size and there are incoming requests that
+ # need instances.
#
- # With strict pooling, requests will have to wait for instances
- # to become available. The pool size will never grow beyond the
- # the set PoolSize value.
+ # With strict pooling, requests will have to wait for instances to
+ # become available. The pool size will never grow beyond the the
+ # set PoolSize value. The maximum amount of time a request should
+ # wait is specified via the AccessTimeout setting.
#
# Without strict pooling, the container will create temporary
# instances to meet demand. The instances will last for just one
# method invocation and then are removed.
+ #
+ # Setting StrictPooling to false and PoolSize to 0 will result in
+ # no pooling. Instead instances will be created on demand and live
+ # for exactly one method call before being removed.
StrictPooling true
+ # Specifies the maximum time that an instance should live before
+ # it should be retired and removed from use. This will happen
+ # gracefully. Useful for situations where bean instances are
+ # designed to hold potentially expensive resources such as memory
+ # or file handles and need to be periodically cleared out.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ MaxAge = 0 hours
+
+ # Specifies the maximum time that an instance should be allowed to
+ # sit idly in the pool without use before it should be retired and
+ # removed.
+ #
+ # Note that all instances in the pool, excluding the minimum, are
+ # eligible for garbage collection by the virtual machine as per
+ # the rules of java.lang.ref.WeakReference, so the use of an
+ # IdleTimeout is not required to conserve JVM-managed memory or
+ # shrink the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ IdleTimeout = 0 minutes
+
+ # The frequency in which the container will sweep the pool and
+ # evict expired instances. Eviction is how the IdleTimeout,
+ # MaxAge, and pool "flush" functionality is enforced. Higher
+ # intervals are better. Expired instances in use while the pool
+ # is swept will still be evicted upon return to the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ PollInterval = 5 minutes
</ServiceProvider>
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml Thu Mar 18 18:09:27 2010
@@ -82,17 +82,20 @@
id="Default Stateless Container"
service="Container"
types="STATELESS"
- constructor="id, securityService, TimeOut, PoolMin, PoolSize, StrictPooling"
- class-name="org.apache.openejb.core.stateless.StatelessContainer">
+ factory-name="create"
+ class-name="org.apache.openejb.core.stateless.StatelessContainerFactory">
# Specifies the time an invokation should wait for an instance
- # of the pool to become available. This measured by default in
- # milliseconds, but other time units can be specified, such as
- # nanoseconds, microsecons, seconds or minutes. After the timeout
- # is reached, if an instance in the pool cannot be obtained, the
- # method invocation will fail.
+ # of the pool to become available.
+ #
+ # After the timeout is reached, if an instance in the pool cannot
+ # be obtained, the method invocation will fail.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
- TimeOut = 0 milliseconds
+ AccessTimeout = 0 milliseconds
# Specifies the minimum number of bean instances that should be
# in the pool for each bean. Pools are prefilled to the minimum
@@ -102,28 +105,72 @@
PoolMin 0
- # Specifies the size of the bean pools for this
- # stateless SessionBean container. If StrictPooling is not
- # used, instances will still be created beyond this number if
- # there is demand, but they will not be returned to the pool
- # and instead will be immediately destroyed.
+ # Specifies the size of the bean pools for this stateless
+ # SessionBean container. If StrictPooling is not used, instances
+ # will still be created beyond this number if there is demand, but
+ # they will not be returned to the pool and instead will be
+ # immediately destroyed.
PoolSize 10
# StrictPooling tells the container what to do when the pool
- # reaches it's maximum size and there are incoming requests
- # that need instances.
+ # reaches it's maximum size and there are incoming requests that
+ # need instances.
#
- # With strict pooling, requests will have to wait for instances
- # to become available. The pool size will never grow beyond the
- # the set PoolSize value.
+ # With strict pooling, requests will have to wait for instances to
+ # become available. The pool size will never grow beyond the the
+ # set PoolSize value. The maximum amount of time a request should
+ # wait is specified via the AccessTimeout setting.
#
# Without strict pooling, the container will create temporary
# instances to meet demand. The instances will last for just one
# method invocation and then are removed.
+ #
+ # Setting StrictPooling to false and PoolSize to 0 will result in
+ # no pooling. Instead instances will be created on demand and live
+ # for exactly one method call before being removed.
StrictPooling true
+ # Specifies the maximum time that an instance should live before
+ # it should be retired and removed from use. This will happen
+ # gracefully. Useful for situations where bean instances are
+ # designed to hold potentially expensive resources such as memory
+ # or file handles and need to be periodically cleared out.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ MaxAge = 0 hours
+
+ # Specifies the maximum time that an instance should be allowed to
+ # sit idly in the pool without use before it should be retired and
+ # removed.
+ #
+ # Note that all instances in the pool, excluding the minimum, are
+ # eligible for garbage collection by the virtual machine as per
+ # the rules of java.lang.ref.WeakReference, so the use of an
+ # IdleTimeout is not required to conserve JVM-managed memory or
+ # shrink the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ IdleTimeout = 0 minutes
+
+ # The frequency in which the container will sweep the pool and
+ # evict expired instances. Eviction is how the IdleTimeout,
+ # MaxAge, and pool "flush" functionality is enforced. Higher
+ # intervals are better. Expired instances in use while the pool
+ # is swept will still be evicted upon return to the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ PollInterval = 5 minutes
</ServiceProvider>
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/default.openejb.conf
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/resources/default.openejb.conf?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/default.openejb.conf (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/default.openejb.conf Thu Mar 18 18:09:27 2010
@@ -66,13 +66,16 @@
<Container id="My Stateless Container" type="STATELESS">
# Specifies the time an invokation should wait for an instance
- # of the pool to become available. This measured by default in
- # milliseconds, but other time units can be specified, such as
- # nanoseconds, microsecons, seconds or minutes. After the timeout
- # is reached, if an instance in the pool cannot be obtained, the
- # method invocation will fail.
+ # of the pool to become available.
+ #
+ # After the timeout is reached, if an instance in the pool cannot
+ # be obtained, the method invocation will fail.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
- TimeOut = 0 milliseconds
+ AccessTimeout = 0 milliseconds
# Specifies the minimum number of bean instances that should be
# in the pool for each bean. Pools are prefilled to the minimum
@@ -82,28 +85,73 @@
PoolMin 0
- # Specifies the size of the bean pools for this
- # stateless SessionBean container. If StrictPooling is not
- # used, instances will still be created beyond this number if
- # there is demand, but they will not be returned to the pool
- # and instead will be immediately destroyed.
+ # Specifies the maximum number of bean instances that should be
+ # in the pool for each bean. If StrictPooling is not used, instances
+ # will still be created beyond this number if there is demand, but
+ # they will not be returned to the pool and instead will be
+ # immediately destroyed.
PoolSize 10
# StrictPooling tells the container what to do when the pool
- # reaches it's maximum size and there are incoming requests
- # that need instances.
+ # reaches it's maximum size and there are incoming requests that
+ # need instances.
#
- # With strict pooling, requests will have to wait for instances
- # to become available. The pool size will never grow beyond the
- # the set PoolSize value.
+ # With strict pooling, requests will have to wait for instances to
+ # become available. The pool size will never grow beyond the the
+ # set PoolSize value. The maximum amount of time a request should
+ # wait is specified via the AccessTimeout setting.
#
# Without strict pooling, the container will create temporary
# instances to meet demand. The instances will last for just one
# method invocation and then are removed.
+ #
+ # Setting StrictPooling to false and PoolSize to 0 will result in
+ # no pooling. Instead instances will be created on demand and live
+ # for exactly one method call before being removed.
StrictPooling true
+ # Specifies the maximum time that an instance should live before
+ # it should be retired and removed from use. This will happen
+ # gracefully. Useful for situations where bean instances are
+ # designed to hold potentially expensive resources such as memory
+ # or file handles and need to be periodically cleared out.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ MaxAge = 0 hours
+
+ # Specifies the maximum time that an instance should be allowed to
+ # sit idly in the pool without use before it should be retired and
+ # removed.
+ #
+ # Note that all instances in the pool, excluding the minimum, are
+ # eligible for garbage collection by the virtual machine as per
+ # the rules of java.lang.ref.WeakReference, so the use of an
+ # IdleTimeout is not required to conserve JVM-managed memory or
+ # shrink the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ IdleTimeout = 0 minutes
+
+ # The frequency in which the container will sweep the pool and
+ # evict expired instances. Eviction is how the IdleTimeout,
+ # MaxAge, and pool "flush" functionality is enforced. Higher
+ # intervals are better. Expired instances in use while the pool
+ # is swept will still be evicted upon return to the pool.
+ #
+ # Usable time units: nanoseconds, microsecons, milliseconds,
+ # seconds, minutes, hours, days. Or any combination such as
+ # "1 hour and 27 minutes and 10 seconds"
+
+ PollInterval = 5 minutes
+
</Container>
Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/ConfigureServiceTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/ConfigureServiceTest.java?rev=924925&r1=924924&r2=924925&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/ConfigureServiceTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/ConfigureServiceTest.java Thu Mar 18 18:09:27 2010
@@ -113,7 +113,7 @@ public class ConfigureServiceTest extend
ContainerInfo myStatelessContainer = factory.configureService(container, ContainerInfo.class);
assertNotNull(myStatelessContainer);
- assertEquals("org.apache.openejb.core.stateless.StatelessContainer", myStatelessContainer.className);
+ assertEquals("org.apache.openejb.core.stateless.StatelessContainerFactory", myStatelessContainer.className);
}
public void testConfigureServiceAddedPropertyViaURI() throws Exception {