001: // ========================================================================
002: // $Id: AbstractStore.java,v 1.5 2004/06/22 16:23:44 jules_gosnell Exp $
003: // Copyright 2002-2004 Mort Bay Consulting Pty. Ltd.
004: // ------------------------------------------------------------------------
005: // Licensed under the Apache License, Version 2.0 (the "License");
006: // you may not use this file except in compliance with the License.
007: // You may obtain a copy of the License at
008: // http://www.apache.org/licenses/LICENSE-2.0
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014: // ========================================================================
015:
016: package org.mortbay.j2ee.session;
017:
018: //----------------------------------------
019:
020: import java.util.Timer;
021: import java.util.TimerTask;
022:
023: import javax.servlet.http.HttpServletRequest;
024:
025: import org.jboss.logging.Logger;
026:
027: //----------------------------------------
028:
029: public abstract class AbstractStore implements Store {
030: protected final static Logger _log = Logger
031: .getLogger(AbstractStore.class);
032:
033: // distributed scavenging
034:
035: /**
036: * The period between scavenges
037: */
038: protected int _scavengerPeriod = 60 * 30; // 1/2 an hour
039:
040: public int getScavengerPeriod() {
041: return _scavengerPeriod;
042: }
043:
044: public void setScavengerPeriod(int secs) {
045: _scavengerPeriod = secs;
046: }
047:
048: /**
049: * The extra time we wait before tidying up a CMPState to ensure that if it
050: * loaded locally it will be scavenged locally first...
051: */
052: protected int _scavengerExtraTime = 60 * 30; // 1/2 an hour
053:
054: public int getScavengerExtraTime() {
055: return _scavengerExtraTime;
056: }
057:
058: public void setScavengerExtraTime(int secs) {
059: _scavengerExtraTime = secs;
060: }
061:
062: /**
063: * A maxInactiveInterval of -1 means never scavenge. The DB would fill up
064: * very quickly - so we can override -1 with a real value here.
065: */
066: protected int _actualMaxInactiveInterval = 60 * 60 * 24 * 28; // 28 days
067:
068: public int getActualMaxInactiveInterval() {
069: return _actualMaxInactiveInterval;
070: }
071:
072: public void setActualMaxInactiveInterval(int secs) {
073: _actualMaxInactiveInterval = secs;
074: }
075:
076: public Object clone() {
077: try {
078: AbstractStore as = (AbstractStore) (getClass()
079: .newInstance());
080: as.setScavengerPeriod(_scavengerPeriod);
081: as.setScavengerExtraTime(_scavengerExtraTime);
082: as.setActualMaxInactiveInterval(_actualMaxInactiveInterval);
083: return as;
084: } catch (Exception e) {
085: _log.warn("could not clone Store", e);
086: return null;
087: }
088: }
089:
090: protected Manager _manager;
091:
092: public Manager getManager() {
093: return _manager;
094: }
095:
096: public void setManager(Manager manager) {
097: _manager = manager;
098: }
099:
100: protected Timer _scavenger;
101:
102: // Store LifeCycle
103: public void start() throws Exception {
104: _log.trace("starting...");
105: boolean isDaemon = true;
106: _scavenger = new Timer(isDaemon);
107: long delay = _scavengerPeriod
108: + Math.round(Math.random() * _scavengerPeriod);
109: if (_log.isDebugEnabled())
110: _log
111: .debug("starting distributed scavenger thread...(period: "
112: + delay + " secs)");
113: _scavenger.scheduleAtFixedRate(new Scavenger(), delay * 1000,
114: _scavengerPeriod * 1000);
115: _log.debug("...distributed scavenger thread started");
116: _log.trace("...started");
117: }
118:
119: public void stop() {
120: _log.trace("stopping...");
121: _log.debug("stopping distributed scavenger thread...");
122: _scavenger.cancel();
123: _scavenger = null;
124: _log.debug("...distributed scavenger thread stopped");
125:
126: try {
127: scavenge();
128: } catch (Exception e) {
129: _log.warn("error scavenging distributed sessions", e);
130: }
131:
132: _log.trace("...stopped");
133: }
134:
135: public void destroy() {
136: _log.trace("destroying...");
137: _log.trace("...destroyed");
138: }
139:
140: class Scavenger extends TimerTask {
141: public void run() {
142: try {
143: scavenge();
144: } catch (Throwable e) {
145: _log.warn("could not scavenge distributed sessions", e);
146: }
147: }
148: }
149:
150: // ID allocation
151:
152: public String allocateId(HttpServletRequest request) {
153: return getManager().getIdGenerator().nextId(request);
154: }
155:
156: public void deallocateId(String id) {
157: // these ids are disposable
158: }
159:
160: // still abstract...
161:
162: // // Store LifeCycle
163: // void destroy(); // corresponds to ctor
164: //
165: // boolean isDistributed();
166: //
167: // // State LifeCycle
168: // State newState(String id, int maxInactiveInterval) throws Exception;
169: // State loadState(String id) throws Exception;
170: // void storeState(State state) throws Exception;
171: // void removeState(State state) throws Exception;
172: //
173: // // Store misc
174: // void scavenge() throws Exception;
175: // void passivateSession(StateAdaptor sa);
176: }
|