Author: dblevins Date: Mon May 17 21:40:43 2010 New Revision: 945401 URL: http://svn.apache.org/viewvc?rev=945401&view=rev Log: svn merge -r 944756:944757 https://svn.apache.org/repos/asf/openejb/trunk/openejb3
http://svn.apache.org/viewvc?rev=944757&view=rev ------------------------------------------------------------------------ r944757 | dblevins | 2010-05-15 19:40:43 -0700 (Sat, 15 May 2010) | 3 lines OPENEJB-1279: Stateless PostConstruct called on undeploy/shutdown OPENEJB-1235 ------------------------------------------------------------------------ Added: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/util/CountingLatch.java - copied unchanged from r944757, openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/CountingLatch.java openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/util/CountingLatchTest.java - copied unchanged from r944757, openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/CountingLatchTest.java Modified: openejb/branches/openejb-3.1.x/ (props changed) openejb/branches/openejb-3.1.x/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml openejb/branches/openejb-3.1.x/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml openejb/branches/openejb-3.1.x/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/config/BusinessInterfacesTest.java (props changed) openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/util/PoolTest.java openejb/branches/openejb-3.1.x/container/openejb-osgi/src/main/resources/META-INF/org.apache.openejb/service-jar.xml openejb/branches/openejb-3.1.x/examples/alternate-descriptors/src/main/resources/META-INF/test.ejb-jar.xml (props changed) Propchange: openejb/branches/openejb-3.1.x/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon May 17 21:40:43 2010 @@ -1,2 +1,2 @@ /openejb/branches/openejb-3.1.1:779593 -/openejb/trunk/openejb3:943472,943862,943965 +/openejb/trunk/openejb3:943472,943862,943965,944757 Modified: openejb/branches/openejb-3.1.x/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/branches/openejb-3.1.x/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml (original) +++ openejb/branches/openejb-3.1.x/assembly/openejb-jetty/openejb-jetty-webapp/src/main/resources/META-INF/org.apache.openejb.jetty/service-jar.xml Mon May 17 21:40:43 2010 @@ -251,6 +251,17 @@ CallbackThreads = 5 + # PostConstruct methods are invoked on all instances in the pool + # when the bean is undeployed and its pool is closed. The + # CloseTimeout specifies the maximum time to wait for the pool to + # close and PostConstruct methods to be invoked. + # + # Usable time units: nanoseconds, microsecons, milliseconds, + # seconds, minutes, hours, days. Or any combination such as + # "1 hour and 27 minutes and 10 seconds" + + CloseTimeout = 5 minutes + </ServiceProvider> Modified: openejb/branches/openejb-3.1.x/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/branches/openejb-3.1.x/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml (original) +++ openejb/branches/openejb-3.1.x/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml Mon May 17 21:40:43 2010 @@ -251,6 +251,17 @@ CallbackThreads = 5 + # PostConstruct methods are invoked on all instances in the pool + # when the bean is undeployed and its pool is closed. The + # CloseTimeout specifies the maximum time to wait for the pool to + # close and PostConstruct methods to be invoked. + # + # Usable time units: nanoseconds, microsecons, milliseconds, + # seconds, minutes, hours, days. Or any combination such as + # "1 hour and 27 minutes and 10 seconds" + + CloseTimeout = 5 minutes + </ServiceProvider> Modified: openejb/branches/openejb-3.1.x/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml (original) +++ openejb/branches/openejb-3.1.x/assembly/openejb-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml Mon May 17 21:40:43 2010 @@ -251,6 +251,17 @@ CallbackThreads = 5 + # PostConstruct methods are invoked on all instances in the pool + # when the bean is undeployed and its pool is closed. The + # CloseTimeout specifies the maximum time to wait for the pool to + # close and PostConstruct methods to be invoked. + # + # Usable time units: nanoseconds, microsecons, milliseconds, + # seconds, minutes, hours, days. Or any combination such as + # "1 hour and 27 minutes and 10 seconds" + + CloseTimeout = 5 minutes + </ServiceProvider> Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java Mon May 17 21:40:43 2010 @@ -62,11 +62,11 @@ public class StatelessContainer implemen private Object containerID = null; private SecurityService securityService; - public StatelessContainer(Object id, SecurityService securityService, Duration accessTimeout, Pool.Builder poolBuilder, int callbackThreads) { + public StatelessContainer(Object id, SecurityService securityService, Duration accessTimeout, Duration closeTimeout, Pool.Builder poolBuilder, int callbackThreads) { this.containerID = id; this.securityService = securityService; - instanceManager = new StatelessInstanceManager(securityService, accessTimeout, poolBuilder, callbackThreads); + instanceManager = new StatelessInstanceManager(securityService, accessTimeout, closeTimeout, poolBuilder, callbackThreads); for (DeploymentInfo deploymentInfo : deploymentRegistry.values()) { org.apache.openejb.core.CoreDeploymentInfo di = (org.apache.openejb.core.CoreDeploymentInfo) deploymentInfo; Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainerFactory.java Mon May 17 21:40:43 2010 @@ -32,6 +32,7 @@ public class StatelessContainerFactory { private SecurityService securityService; private Duration accessTimeout; private int callbackThreads = 5; + private Duration closeTimeout; public void setCallbackThreads(int callbackThreads) { this.callbackThreads = callbackThreads; @@ -105,7 +106,11 @@ public class StatelessContainerFactory { pool.setMaxAgeOffset(maxAgeOffset); } + public void setCloseTimeout(Duration closeTimeout) { + this.closeTimeout = closeTimeout; + } + public StatelessContainer create() { - return new StatelessContainer(id, securityService, accessTimeout, pool, callbackThreads); + return new StatelessContainer(id, securityService, accessTimeout, closeTimeout, pool, callbackThreads); } } Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java Mon May 17 21:40:43 2010 @@ -39,10 +39,6 @@ import javax.naming.NamingException; import javax.xml.ws.WebServiceContext; import javax.management.ObjectName; import javax.management.MBeanServer; -import javax.management.InstanceAlreadyExistsException; -import javax.management.MBeanRegistrationException; -import javax.management.NotCompliantMBeanException; -import javax.management.InstanceNotFoundException; import org.apache.openejb.Injection; import org.apache.openejb.OpenEJBException; @@ -72,7 +68,8 @@ import org.apache.xbean.recipe.Option; public class StatelessInstanceManager { private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources"); - protected Duration timeout; + protected Duration accessTimeout; + protected Duration closeTimeout; protected int beanCount = 0; protected final SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager"); @@ -80,12 +77,13 @@ public class StatelessInstanceManager { private final Pool.Builder poolBuilder; private final Executor executor; - public StatelessInstanceManager(SecurityService securityService, Duration timeout, Pool.Builder poolBuilder, int callbackThreads) { + public StatelessInstanceManager(SecurityService securityService, Duration accessTimeout, Duration closeTimeout, Pool.Builder poolBuilder, int callbackThreads) { this.securityService = securityService; - this.timeout = timeout; + this.accessTimeout = accessTimeout; + this.closeTimeout = closeTimeout; this.poolBuilder = poolBuilder; - if (timeout.getUnit() == null) timeout.setUnit(TimeUnit.MILLISECONDS); + if (accessTimeout.getUnit() == null) accessTimeout.setUnit(TimeUnit.MILLISECONDS); executor = new ThreadPoolExecutor(callbackThreads, callbackThreads*2, 0L, TimeUnit.MILLISECONDS, @@ -394,17 +392,20 @@ public class StatelessInstanceManager { final Pool.Builder builder = new Pool.Builder(poolBuilder); - String timeString = options.get("Timeout", this.timeout.toString()); + String timeString = options.get("Timeout", this.accessTimeout.toString()); timeString = options.get("AccessTimeout", timeString); Duration accessTimeout = new Duration(timeString); + String s = options.get("CloseTimeout", this.closeTimeout.toString()); + Duration closeTimeout = new Duration(s); + 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); + Data data = new Data(builder.build(), accessTimeout, closeTimeout); deploymentInfo.setContainerData(data); final int min = builder.getMin(); @@ -474,11 +475,6 @@ public class StatelessInstanceManager { public void undeploy(CoreDeploymentInfo deploymentInfo) { Data data = (Data) deploymentInfo.getContainerData(); if (data == null) return; - data.getPool().stop(); - - //TODO *maybe* call ejbRemove on each bean in pool. - - deploymentInfo.setContainerData(null); MBeanServer server = ManagementFactory.getPlatformMBeanServer(); for (ObjectName objectName : data.jmxNames) { @@ -488,16 +484,28 @@ public class StatelessInstanceManager { logger.error("Unable to unregister MBean "+objectName); } } + + try { + if (!data.closePool()) { + logger.error("Timed-out waiting for stateless pool to close: for deployment '" + deploymentInfo.getDeploymentID() + "'"); + } + } catch (InterruptedException e) { + Thread.interrupted(); + } + + deploymentInfo.setContainerData(null); } private static final class Data { private final Pool<Instance> pool; - private Duration accessTimeout; + private final Duration accessTimeout; + private final Duration closeTimeout; private final List<ObjectName> jmxNames = new ArrayList<ObjectName>(); - public Data(Pool<Instance> pool, Duration accessTimeout) { - this.accessTimeout = accessTimeout; + private Data(Pool<Instance> pool, Duration accessTimeout, Duration closeTimeout) { this.pool = pool; + this.accessTimeout = accessTimeout; + this.closeTimeout = closeTimeout; } public Duration getAccessTimeout() { @@ -512,6 +520,10 @@ public class StatelessInstanceManager { return pool; } + public boolean closePool() throws InterruptedException { + return pool.close(closeTimeout.getTime(), closeTimeout.getUnit()); + } + public ObjectName add(ObjectName name) { jmxNames.add(name); return name; Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/main/java/org/apache/openejb/util/Pool.java Mon May 17 21:40:43 2010 @@ -70,6 +70,8 @@ public class Pool<T> { private final AtomicReference<Timer> timer = new AtomicReference<Timer>(); private final Sweeper sweeper; + private final CountingLatch out = new CountingLatch(); + @Managed private final long interval; @@ -112,11 +114,15 @@ public class Pool<T> { public void stop() { Timer timer = this.timer.get(); - if (this.timer.compareAndSet(timer, null)) { + if (timer != null && this.timer.compareAndSet(timer, null)) { timer.cancel(); } } + public boolean running() { + return timer.get() != null; + } + private Executor createExecutor() { return new ThreadPoolExecutor(5, 10, 0L, TimeUnit.SECONDS, @@ -142,11 +148,28 @@ public class Pool<T> { * @return an entry from the pool or null indicating permission to create and push() an instance into the pool * @throws InterruptedException vm level thread interruption * @throws IllegalStateException if a permit could not be acquired - * @throws TimeoutException if no instance could be obtained within the timeout + * @throws java.util.concurrent.TimeoutException if no instance could be obtained within the timeout */ public Entry<T> pop(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException { + return pop(timeout, unit, true); + } + + /** + * Any successful pop() call requires a corresponding push() or discard() call + * <p/> + * A pop() call that returns null is considered successful. + * + * @param timeout time to block while waiting for an instance + * @param unit unit of time dicated by the timeout + * @param record should this be reflected in the stats + * @return an entry from the pool or null indicating permission to create and push() an instance into the pool + * @throws InterruptedException vm level thread interruption + * @throws IllegalStateException if a permit could not be acquired + * @throws TimeoutException if no instance could be obtained within the timeout + */ + private Entry<T> pop(long timeout, TimeUnit unit, boolean record) throws InterruptedException, TimeoutException { if (!available.tryAcquire(timeout, unit)) { - stats.accessTimeouts.record(); + if (record) stats.accessTimeouts.record(); throw new TimeoutException("Waited " + timeout + " " + unit); } @@ -346,6 +369,25 @@ public class Pool<T> { available.release(); } + public boolean close(long timeout, TimeUnit unit) throws InterruptedException { + // drain all keys so no new instances will be accepted into the pool + while (instances.tryAcquire()); + while (minimum.tryAcquire()); + + // Stop the sweeper thread + stop(); + + // flush and sweep + flush(); + sweeper.run(); + + // Drain all leases + if (!(available instanceof Overdraft)) while (available.tryAcquire()); + + // Wait for any pending discards + return out.await(timeout, unit); + } + /** * This internal method allows us to "swap" the status * of two entries before returning them to the pool. @@ -468,7 +510,7 @@ public class Pool<T> { // Pull all the entries from the pool try { while (true) { - final Entry<T> entry = pop(0, MILLISECONDS); + final Entry<T> entry = pop(0, MILLISECONDS, false); if (entry == null) { push(entry, true); break; @@ -640,6 +682,11 @@ public class Pool<T> { } public void run() { + if (!running()) { + discard(expired); + return; + } + try { final T t = supplier.create(); @@ -665,6 +712,7 @@ public class Pool<T> { private final Event event; private Discard(T expired, Event event) { + out.countUp(); if (expired == null) throw new NullPointerException("expired object cannot be null"); this.expired = expired; this.event = event; @@ -677,7 +725,11 @@ public class Pool<T> { case FULL: stats.overdrafts.record(); break; case IDLE: stats.idleTimeouts.record(); break; } - supplier.discard(expired, event); + try { + supplier.discard(expired, event); + } finally { + out.countDown(); + } } } Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml Mon May 17 21:40:43 2010 @@ -244,6 +244,17 @@ CallbackThreads = 5 + # PostConstruct methods are invoked on all instances in the pool + # when the bean is undeployed and its pool is closed. The + # CloseTimeout specifies the maximum time to wait for the pool to + # close and PostConstruct methods to be invoked. + # + # Usable time units: nanoseconds, microsecons, milliseconds, + # seconds, minutes, hours, days. Or any combination such as + # "1 hour and 27 minutes and 10 seconds" + + CloseTimeout = 5 minutes + </ServiceProvider> <!-- Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml Mon May 17 21:40:43 2010 @@ -246,6 +246,17 @@ CallbackThreads = 5 + # PostConstruct methods are invoked on all instances in the pool + # when the bean is undeployed and its pool is closed. The + # CloseTimeout specifies the maximum time to wait for the pool to + # close and PostConstruct methods to be invoked. + # + # Usable time units: nanoseconds, microsecons, milliseconds, + # seconds, minutes, hours, days. Or any combination such as + # "1 hour and 27 minutes and 10 seconds" + + CloseTimeout = 5 minutes + </ServiceProvider> Propchange: openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/config/BusinessInterfacesTest.java ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon May 17 21:40:43 2010 @@ -1,2 +1,2 @@ /openejb/branches/openejb-3.1.1/container/openejb-core/src/test/java/org/apache/openejb/config/UberInterfaceTest.java:779593 -/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/BusinessInterfacesTest.java:943472,943862,943965 +/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/BusinessInterfacesTest.java:943472,943862,943965,944757 Modified: openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/util/PoolTest.java URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/util/PoolTest.java?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/util/PoolTest.java (original) +++ openejb/branches/openejb-3.1.x/container/openejb-core/src/test/java/org/apache/openejb/util/PoolTest.java Mon May 17 21:40:43 2010 @@ -259,6 +259,66 @@ public class PoolTest extends TestCase { } + public void testClose() throws Exception { + System.out.println("PoolTest.testClose"); + + final int min = 4; + final int max = 9; + final int sweepInterval = 200; + final int pause = 1000; + + final List<Bean> discarded = new CopyOnWriteArrayList<Bean>(); + final CountDownLatch discard = new CountDownLatch(max); + final Pool.Builder builder = new Pool.Builder(); + builder.setPoolMin(min); + builder.setPoolMax(max); + builder.setPollInterval(new Duration(sweepInterval, TimeUnit.MILLISECONDS)); + builder.setSupplier(new Pool.Supplier<Bean>() { + public void discard(Bean bean, Pool.Event reason) { + try { + Thread.sleep(pause); + } catch (InterruptedException e) { + Thread.interrupted(); + } + bean.discard(); + discarded.add(bean); + discard.countDown(); + } + + public Bean create() { + return new Bean(); + } + }); + + + final Pool pool = this.pool = builder.build().start(); + + // Fill pool to max + Bean.instances.set(0); + for (int i = 0; i < max; i++) { + assertTrue(pool.add(new Bean())); + } + + + { // Should have a full, non-null pool + final List entries = drain(pool, 100); + checkMin(min, entries); + checkEntries(max, entries); + push(pool, entries); + } + + long start = System.currentTimeMillis(); + assertTrue(pool.close(10, TimeUnit.SECONDS)); + long time = System.currentTimeMillis() - start; + + // All instances should have been removed + assertEquals(max, discarded.size()); + + // Should have taken at least three seconds + assertTrue(time >= pause); + + } + /** * Tests the idle timeout as well as the Thread pool * used to invoke the discard/create jobs. Modified: openejb/branches/openejb-3.1.x/container/openejb-osgi/src/main/resources/META-INF/org.apache.openejb/service-jar.xml URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.1.x/container/openejb-osgi/src/main/resources/META-INF/org.apache.openejb/service-jar.xml?rev=945401&r1=945400&r2=945401&view=diff ============================================================================== --- openejb/branches/openejb-3.1.x/container/openejb-osgi/src/main/resources/META-INF/org.apache.openejb/service-jar.xml (original) +++ openejb/branches/openejb-3.1.x/container/openejb-osgi/src/main/resources/META-INF/org.apache.openejb/service-jar.xml Mon May 17 21:40:43 2010 @@ -246,6 +246,17 @@ CallbackThreads = 5 + # PostConstruct methods are invoked on all instances in the pool + # when the bean is undeployed and its pool is closed. The + # CloseTimeout specifies the maximum time to wait for the pool to + # close and PostConstruct methods to be invoked. + # + # Usable time units: nanoseconds, microsecons, milliseconds, + # seconds, minutes, hours, days. Or any combination such as + # "1 hour and 27 minutes and 10 seconds" + + CloseTimeout = 5 minutes + </ServiceProvider> Propchange: openejb/branches/openejb-3.1.x/examples/alternate-descriptors/src/main/resources/META-INF/test.ejb-jar.xml ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon May 17 21:40:43 2010 @@ -1,2 +1,2 @@ /openejb/branches/openejb-3.1.1/examples/alternate-descriptors/src/main/resources/META-INF/ejb-jar.xml:779593 -/openejb/trunk/openejb3/examples/alternate-descriptors/src/main/resources/META-INF/test.ejb-jar.xml:943472,943862,943965 +/openejb/trunk/openejb3/examples/alternate-descriptors/src/main/resources/META-INF/test.ejb-jar.xml:943472,943862,943965,944757
