001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins;
023:
024: import java.util.TimerTask;
025:
026: import org.jboss.deployment.DeploymentException;
027: import org.jboss.metadata.MetaData;
028: import org.w3c.dom.Element;
029:
030: /**
031: * Least Recently Used cache policy for StatefulSessionEnterpriseContexts.
032: * @author <a href="mailto:simone.bordet@compaq.com">Simone Bordet</a>
033: * @author Scott.Stark@jboss.org
034: * @version $Revision: 57209 $
035: */
036: public class LRUStatefulContextCachePolicy extends
037: LRUEnterpriseContextCachePolicy {
038: // Constants -----------------------------------------------------
039:
040: // Attributes ----------------------------------------------------
041: /* The age after which a bean is automatically removed */
042: private long m_maxBeanLife;
043: /* The remover timer task */
044: private TimerTask m_remover;
045: /* The period of the remover's runs */
046: private long m_removerPeriod;
047: /**
048: * The typed stateful cache
049: */
050: private StatefulSessionInstanceCache ssiCache;
051:
052: // Static --------------------------------------------------------
053:
054: // Constructors --------------------------------------------------
055: /**
056: * Creates a LRU cache policy object given the instance cache that use this
057: * policy object.
058: */
059: public LRUStatefulContextCachePolicy(AbstractInstanceCache eic) {
060: super (eic);
061: ssiCache = (StatefulSessionInstanceCache) eic;
062: }
063:
064: // Public --------------------------------------------------------
065:
066: // Monitorable implementation ------------------------------------
067:
068: // Z implementation ----------------------------------------------
069: public void start() {
070: super .start();
071: if (m_maxBeanLife > 0) {
072: m_remover = new RemoverTask(m_removerPeriod);
073: long delay = (long) (Math.random() * m_removerPeriod);
074: tasksTimer.schedule(m_remover, delay, m_removerPeriod);
075: }
076: }
077:
078: public void stop() {
079: if (m_remover != null) {
080: m_remover.cancel();
081: }
082: super .stop();
083: }
084:
085: /**
086: * Reads from the configuration the parameters for this cache policy, that
087: * are all optionals.
088: */
089: public void importXml(Element element) throws DeploymentException {
090: super .importXml(element);
091:
092: String rp = MetaData.getElementContent(MetaData
093: .getOptionalChild(element, "remover-period"));
094: String ml = MetaData.getElementContent(MetaData
095: .getOptionalChild(element, "max-bean-life"));
096: try {
097: if (rp != null) {
098: int p = Integer.parseInt(rp);
099: if (p <= 0) {
100: throw new DeploymentException(
101: "Remover period can't be <= 0");
102: }
103: m_removerPeriod = p * 1000;
104: }
105: if (ml != null) {
106: int a = Integer.parseInt(ml);
107: if (a <= 0) {
108: throw new DeploymentException(
109: "Max bean life can't be <= 0");
110: }
111: m_maxBeanLife = a * 1000;
112: }
113: } catch (NumberFormatException x) {
114: throw new DeploymentException(
115: "Can't parse policy configuration", x);
116: }
117: }
118:
119: // Y overrides ---------------------------------------------------
120:
121: // Package protected ---------------------------------------------
122:
123: // Protected -----------------------------------------------------
124:
125: // Private -------------------------------------------------------
126:
127: // Inner classes -------------------------------------------------
128: /**
129: * This TimerTask removes beans that have not been called for a while.
130: */
131: protected class RemoverTask extends OveragerTask {
132: protected RemoverTask(long period) {
133: super (period);
134: }
135:
136: protected String getTaskLogMessage() {
137: return "Removing from cache bean";
138: }
139:
140: protected void kickOut(LRUCacheEntry entry) {
141: remove(entry.m_key);
142: }
143:
144: protected long getMaxAge() {
145: return m_maxBeanLife;
146: }
147:
148: public void run() {
149: if (ssiCache == null) {
150: cancel();
151: return;
152: }
153:
154: synchronized (ssiCache.getCacheLock()) {
155: log.debug("Running RemoverTask");
156: // Remove beans from cache and passivate them
157: super .run();
158: log.debug("RemoverTask, PassivatedCount="
159: + ssiCache.getPassivatedCount());
160: }
161: try {
162: // Throw away any passivated beans that have expired
163: ssiCache.removePassivated(getMaxAge()
164: - super .getMaxAge());
165: log.debug("RemoverTask, done");
166: } catch (Throwable t) {
167: log
168: .debug(
169: "Ignored error trying to remove passivated beans from cache",
170: t);
171: }
172: }
173: }
174: }
|