Fix for Issue 4 - Allow programmatic shutdown of EbeanServer

This commit is contained in:
Robin Bygrave
2013-04-26 23:21:25 +12:00
parent 384931d92e
commit bcce1a7148
31 changed files with 1397 additions and 2073 deletions
@@ -1,11 +1,9 @@
package com.avaje.ebeaninternal.server.lib;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.avaje.ebeaninternal.api.Monitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -16,71 +14,73 @@ import org.slf4j.LoggerFactory;
*/
public final class DaemonThreadPool extends ThreadPoolExecutor {
private static final Logger logger = LoggerFactory.getLogger(DaemonThreadPool.class);
private static final Logger logger = LoggerFactory.getLogger(DaemonThreadPool.class);
private final Monitor monitor = new Monitor();
private final String namePrefix;
private int shutdownWaitSeconds;
/**
* Construct the DaemonThreadPool.
*
* @param coreSize
* the core size of the thread pool.
* @param keepAliveSecs
* the time in seconds idle threads are keep alive
* @param shutdownWaitSeconds
* the time in seconds allowed for the pool to shutdown nicely.
* After this the pool is forced to shutdown.
*/
public DaemonThreadPool(int coreSize, long keepAliveSecs, int shutdownWaitSeconds, String namePrefix) {
super(coreSize, coreSize, keepAliveSecs, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DaemonThreadFactory(namePrefix));
this.shutdownWaitSeconds = shutdownWaitSeconds;
this.namePrefix = namePrefix;
// we want to shutdown nicely when either the web application stops.
// Adding the JVM shutdown hook as a safety (and when not run in tomcat)
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
}
private final String namePrefix;
/**
* Shutdown this thread pool nicely if possible.
* <p>
* This will wait a maximum of 20 seconds before terminating any threads
* still working.
* </p>
*/
public void shutdown() {
synchronized (monitor) {
if (super.isShutdown()) {
logger.debug("... DaemonThreadPool["+namePrefix+"] already shut down");
return;
}
try {
logger.debug("DaemonThreadPool["+namePrefix+"] shutting down...");
super.shutdown();
if (!super.awaitTermination(shutdownWaitSeconds, TimeUnit.SECONDS)) {
logger.info("DaemonThreadPool["+namePrefix+"] shut down timeout exceeded. Terminating running threads.");
super.shutdownNow();
}
private final int shutdownWaitSeconds;
} catch (Exception e) {
String msg = "Error during shutdown of DaemonThreadPool["+namePrefix+"]";
logger.error(msg, e);
e.printStackTrace();
}
/**
* Construct the DaemonThreadPool.
*
* @param coreSize
* the core size of the thread pool.
* @param keepAliveSecs
* the time in seconds idle threads are keep alive
* @param shutdownWaitSeconds
* the time in seconds allowed for the pool to shutdown nicely. After
* this the pool is forced to shutdown.
*/
public DaemonThreadPool(int coreSize, long keepAliveSecs, int shutdownWaitSeconds, String namePrefix) {
super(coreSize, coreSize, keepAliveSecs, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new DaemonThreadFactory(namePrefix));
allowCoreThreadTimeOut(true);
this.shutdownWaitSeconds = shutdownWaitSeconds;
this.namePrefix = namePrefix;
}
/**
* Register a shutdown hook with the JVM Runtime.
*/
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
}
/**
* Shutdown this thread pool nicely if possible.
* <p>
* This will wait a maximum of 20 seconds before terminating any threads still
* working.
* </p>
*/
public void shutdown() {
synchronized (this) {
if (super.isShutdown()) {
logger.debug("DaemonThreadPool[" + namePrefix + "] already shut down");
return;
}
try {
logger.debug("DaemonThreadPool[" + namePrefix + "] shutting down...");
super.shutdown();
if (!super.awaitTermination(shutdownWaitSeconds, TimeUnit.SECONDS)) {
logger.info("DaemonThreadPool[" + namePrefix+ "] shut down timeout exceeded. Terminating running threads.");
super.shutdownNow();
}
}
/**
* Fired by the JVM Runtime shutdown.
*/
private class ShutdownHook extends Thread {
@Override
public void run() {
shutdown();
}
};
} catch (Exception e) {
logger.error("Error during shutdown of DaemonThreadPool[" + namePrefix + "]", e);
e.printStackTrace();
}
}
}
/**
* Fired by the JVM Runtime shutdown.
*/
private class ShutdownHook extends Thread {
@Override
public void run() {
shutdown();
}
};
}