001: /**
002: *
003: */package clime.messadmin.providers.lifecycle;
004:
005: import java.util.Collections;
006: import java.util.HashSet;
007: import java.util.Iterator;
008: import java.util.Set;
009: import java.util.Timer;
010: import java.util.TimerTask;
011:
012: import javax.servlet.ServletContext;
013: import javax.servlet.http.HttpSession;
014:
015: import clime.messadmin.model.Application;
016: import clime.messadmin.model.IApplicationInfo;
017: import clime.messadmin.model.Server;
018: import clime.messadmin.model.Session;
019: import clime.messadmin.providers.spi.ApplicationLifeCycleProvider;
020: import clime.messadmin.utils.SessionUtils;
021:
022: /**
023: * Manually expire zombie Tomcat HttpSessions...
024: * @author Cédrik LIME
025: */
026: public class SessionKiller implements ApplicationLifeCycleProvider {
027: /**
028: * Default time to wait between two sweeps: {@value} ms.
029: */
030: public static final long DELAY = 20 * 60 * 1000; // 20 minutes
031: private static Timer timer;
032: private static TimerTask timerTask;
033: final static Set/*<String>*/contexts = Collections
034: .synchronizedSet(new HashSet());
035:
036: /**
037: *
038: */
039: public SessionKiller() {
040: super ();
041: maybeInitialize();
042: }
043:
044: protected static synchronized void maybeInitialize() {
045: if (timerTask != null || timer != null) {
046: return;
047: }
048: timerTask = new TimerTask() {
049: /**
050: * {@inheritDoc}
051: */
052: public void run() {
053: try {
054: synchronized (contexts) {
055: Iterator appIter = contexts.iterator();
056: while (appIter.hasNext()) {
057: Application application = Server
058: .getInstance().getApplication(
059: (String) appIter.next());
060: if (application == null) {
061: //shouldn't ever happen, but let's play safe
062: continue;
063: }
064: try {
065: Iterator sessIter = application
066: .getActiveSessions().iterator();
067: while (sessIter.hasNext()) {
068: Session session = (Session) sessIter
069: .next();
070: if (session.getSessionInfo()
071: .getTTL() < 0) {
072: reportExpiringSession(
073: application
074: .getApplicationInfo(),
075: session
076: .getSessionInfo());
077: session.getSessionInfo()
078: .invalidate();
079: }
080: }
081: } catch (RuntimeException rte) {
082: //swallow
083: }
084: }
085: }
086: } catch (Exception e) {
087: //swallow
088: }
089: }
090: };
091: timer = new Timer(true);//"Zombie Tomcat HttpSessions killer", true);
092: timer.schedule(timerTask, DELAY, DELAY);
093: }
094:
095: protected static void reportExpiringSession(
096: IApplicationInfo application, HttpSession session) {
097: String id = "";
098: String contextPath = application.getContextPath();
099: try {
100: id = session.getId();
101: } catch (IllegalStateException ise) {
102: }
103: System.out
104: .println("MessAdmin INFO: invalidating expired session "
105: + id + " for context " + contextPath);
106: }
107:
108: /**
109: * {@inheritDoc}
110: */
111: public void contextInitialized(ServletContext servletContext) {
112: contexts.add(SessionUtils.getContext(servletContext));
113: }
114:
115: /**
116: * {@inheritDoc}
117: */
118: public void contextDestroyed(ServletContext servletContext) {
119: contexts.remove(SessionUtils.getContext(servletContext));
120: }
121:
122: /**
123: * {@inheritDoc}
124: */
125: public int getPriority() {
126: // no need for a priority, really
127: return 0;
128: }
129:
130: }
|