Source Code Cross Referenced for PagedSessionHome.java in  » J2EE » Enhydra-Application-Framework » com » lutris » appserver » server » sessionEnhydra » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Enhydra Application Framework » com.lutris.appserver.server.sessionEnhydra 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Enhydra Java Application Server Project
003:         *
004:         * The contents of this file are subject to the Enhydra Public License
005:         * Version 1.1 (the "License"); you may not use this file except in
006:         * compliance with the License. You may obtain a copy of the License on
007:         * the Enhydra web site ( http://www.enhydra.org/ ).
008:         *
009:         * Software distributed under the License is distributed on an "AS IS"
010:         * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011:         * the License for the specific terms governing rights and limitations
012:         * under the License.
013:         *
014:         * The Initial Developer of the Enhydra Application Server is Lutris
015:         * Technologies, Inc. The Enhydra Application Server and portions created
016:         * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017:         * All Rights Reserved.
018:         *
019:         * Contributor(s):
020:         *
021:         * $Id: PagedSessionHome.java,v 1.3 2007-10-19 10:05:39 sinisa Exp $
022:         */
023:
024:        package com.lutris.appserver.server.sessionEnhydra;
025:
026:        import java.util.Enumeration;
027:        import java.util.Hashtable;
028:        import java.util.Vector;
029:
030:        import com.lutris.appserver.server.Enhydra;
031:        import com.lutris.appserver.server.session.SessionException;
032:        import com.lutris.logging.Logger;
033:        import com.lutris.util.Config;
034:        import com.lutris.util.ConfigException;
035:
036:        /**
037:         * The StandardSessionManager uses PagedSessionHome to manage
038:         * a collection of sessions that can be paged to disk.<p>
039:         *
040:         * PagedSessionHome will page sessions to disk
041:         * as soon as a pre-configured threshold of sessions has been
042:         * reached.  Only sessions in the 'passive' state will be
043:         * paged to disk.  If all sessions are in the 'active' state
044:         * and the threshold has been reached, then a request to create
045:         * a new session will block until one of the 'active' sessions
046:         * goes into the 'passive' state.  At this point the session
047:         * that just became 'passive' is paged to disk and a new
048:         * session is created.<p>
049:         *
050:         * Sessions are paged to disk by serializing
051:         * the all data (excluding the session manager) that is
052:         * associated with a session.  This requires that
053:         * the session data and user associated with a session
054:         * are serializable.<p>
055:         *
056:         * The following parameters can be used to configure
057:         * the PagedSessionHome.  They should be grouped together in a section,
058:         * normally <code>SessionManager.SessionHome</code>, which is specified to
059:         * the constructor.<p>
060:         *
061:         * <ul>
062:         *
063:         * <li><code>PageThreshold: {int}</code><p>
064:         * Specifies the maximum number of session that may reside in memory
065:         * simultaneously.  If set to zero the the paged session home acts
066:         * as a write through cache.  If set to -1, then the page threshold
067:         * is assumed to be infinite and paging will never take place.
068:         * If not set, defaults to -1.<p>
069:         *
070:         * <li><code>PageTimeThreshold: {long}</code><p>
071:         * Specifies the amount of time a session may remain in memory
072:         * before it is paged out to disk.
073:         * If this parameter is not set, or, it is set to -1, then the session
074:         * will not be paged out unless the <i>PageThreshold</i> is reached.<p>
075:         *
076:         * <li><code>PageWait: {int}</code><p>
077:         * Specifies the maximum time (in milliseconds) that a thread will
078:         * wait for a session to be created or retrieved.  If the
079:         * page threshold has been reached, then a thread has to wait for
080:         * an existing session to be paged before a new session can be
081:         * created or a pre-existing session (that has been paged to
082:         * disk) can be activated.  If not set, defaults to 1 minute.
083:         * If this time is exceeded then an exception is thrown - this
084:         * prevents a possible deadlock situation.<p>
085:         *
086:         * <li><code>PageDir: {String}</code><p>
087:         * The directory where sessions will be paged.  This setting is
088:         * required.<p>
089:         *
090:         * <li><code>MaxSessions: {int}</code><p>
091:         * Specifies the maximum number of in use concurrent sessions.  If this value
092:         * is exceeded then CreateSession() will throw a CreateSessionException.
093:         * -1 indicates unlimited session.  If MaxSessions is not set
094:         * in the application's configuration then MaxSessions defaults to
095:         * unlimited sessions.<p>
096:         *
097:         * </ul>
098:         *
099:         * @see         StandardSession
100:         * @see         StandardSessionManager
101:         * @version	$Revision: 1.3 $
102:         * @author	Kyle Clark
103:         */
104:        public abstract class PagedSessionHome implements  StandardSessionHome {
105:
106:            /**
107:             * The active cache contains sessions that are
108:             * actively in use (associated with) by a request.
109:             */
110:            private Hashtable activeCache = new Hashtable();
111:
112:            /**
113:             * The active thread cache holds all the association
114:             * between active sessions and the threads that have
115:             * checked them out.
116:             */
117:            private Hashtable activeThreadCache = new Hashtable();
118:
119:            /**
120:             * The passive cache contains sessions that
121:             * aren't currently associated with a request.
122:             */
123:            private Hashtable passiveCache = new Hashtable();
124:
125:            /**
126:             * Config options for paged session home.
127:             */
128:            //    private Config config;
129:            /**
130:             * Maximum number of allowed sessions.
131:             */
132:            private long maxSessions = -1;
133:
134:            /**
135:             * The threshold where paging beings.
136:             */
137:            private long pageThreshold = -1;
138:
139:            /**
140:             * The amount of time a session may remain in memory
141:             * unused before it is paged out.  In seconds.
142:             */
143:            private long pageTimeThreshold = -1;
144:
145:            /**
146:             * The pageTimeThreshold timer.
147:             */
148:            private PagedSessionThresholdTimer thresholdTimer;
149:
150:            /**
151:             * If a thread has to wait for a session to be paged
152:             * before it can retrieve (get) or create a session then
153:             * pageWait specifies that maximum amount of time
154:             * that the thread will wait before an exception is
155:             * thrown.
156:             */
157:            private long pageWait = 60000; // milliseconds
158:
159:            /**
160:             * Configuration keys.
161:             */
162:            private static final String MAX_SESSIONS_KEY = "MaxSessions";
163:            private static final String PAGE_THRESHOLD_KEY = "PageThreshold";
164:            private static final String PAGE_TIME_THRESHOLD_KEY = "PageTimeThreshold";
165:            private static final String PAGE_WAIT_KEY = "PageWait";
166:            private static final long UNDEFINED_MAX_SESSIONS = -1;
167:
168:            /**
169:             * The class loader to use when reading in paged data.
170:             */
171:            protected ClassLoader loader;
172:
173:            /**
174:             * The session manager associated with the session home.
175:             */
176:            protected StandardSessionManager sessionMgr;
177:
178:            /**
179:             * @param sessionMgr
180:             *   The session manager associated with this session home.
181:             * @param config
182:             *   Object parsed from configuration file.  This should be
183:             *   for the section containing the standard session home configuration.
184:             * @param loader
185:             *   The class load to use when load objects from persistent store.
186:             * @exception ConfigException
187:             *   signifies a problem in the configuration file.
188:             * @exception SessionException
189:             *   if the initialization fails.
190:             */
191:            public PagedSessionHome(StandardSessionManager sessionMgr,
192:                    Config config, ClassLoader loader) throws SessionException,
193:                    ConfigException {
194:                //        this.config = config;
195:                this .loader = loader;
196:                this .sessionMgr = sessionMgr;
197:                if (config.containsKey(MAX_SESSIONS_KEY)) {
198:                    maxSessions = config.getLong(MAX_SESSIONS_KEY);
199:                }
200:                if (maxSessions <= 0) {
201:                    maxSessions = UNDEFINED_MAX_SESSIONS;
202:                }
203:                debug(MAX_SESSIONS_KEY + " = " + maxSessions);
204:                pageThreshold = config.getLong(PAGE_THRESHOLD_KEY);
205:                debug(PAGE_THRESHOLD_KEY + " = " + pageThreshold);
206:                if (config.containsKey(PAGE_WAIT_KEY)) {
207:                    pageWait = config.getLong(PAGE_WAIT_KEY);
208:                    if (pageWait <= 0) {
209:                        throw new ConfigException("PagedSessionHome: "
210:                                + "PageWait cannot be <= 0.");
211:                    }
212:                }
213:                if (config.containsKey(PAGE_TIME_THRESHOLD_KEY)) {
214:                    pageTimeThreshold = config.getLong(PAGE_TIME_THRESHOLD_KEY) * 1000;
215:                    if (!isWriteThroughCache() && (pageTimeThreshold > 0)) {
216:                        thresholdTimer = new PagedSessionThresholdTimer(this ,
217:                                sessionMgr.app);
218:                        thresholdTimer.start();
219:                    }
220:                }
221:                debug(PAGE_TIME_THRESHOLD_KEY + " = " + pageTimeThreshold);
222:            }
223:
224:            /**
225:             * Creates a new session instance in the cache.  The
226:             * session is associated with the session key and the
227:             * current thread.
228:             *
229:             * @param sessionKey the key to associate with the session.
230:             * @return the newly created session.
231:             * @exception DuplicateKeyException
232:             *   if the session cannot
233:             *   be created because the key is already in use.
234:             * @exception CreateSessionException
235:             *   if the session could not be created.
236:             * @exception SessionException
237:             *   any other internal error.
238:             */
239:            public synchronized StandardSession createSession(String sessionKey)
240:                    throws CreateSessionException, DuplicateKeyException,
241:                    SessionException {
242:                if (containsKey(sessionKey)) {
243:                    throw new DuplicateKeyException("Session key " + sessionKey
244:                            + " is already in use.");
245:                }
246:                if ((maxSessions != UNDEFINED_MAX_SESSIONS)
247:                        && (maxSessions <= size())) {
248:                    cleanupNewSession();
249:                    if (maxSessions <= size()) {
250:                        throw new CreateSessionException(
251:                                "Maximum session limit of " + maxSessions
252:                                        + " sessions has been reached.");
253:                    }
254:                }
255:                ensureNewSession();
256:                PagedSession session = newSession(sessionMgr, sessionKey);
257:                SessionThread activeKey = new SessionThread(Thread
258:                        .currentThread(), sessionKey);
259:                session.incrementRefCount(); // keeps track of # of threads that reference session
260:                activeThreadCache.put(activeKey, session);
261:                activeCache.put(sessionKey, session);
262:                // v. strahinja, 01 okt 2002          debug(3, "createSession: " + activeKey);
263:                debug("createSession: " + activeKey);
264:                return (StandardSession) session;
265:            }
266:
267:            /**
268:             * Creates a new session object.  This method is intended to be
269:             * overriden by classes that extend PagedSessionHome.
270:             *
271:             * @return a new session.
272:             * @exception SessionException if an error occurs.
273:             */
274:            protected abstract PagedSession newSession(
275:                    StandardSessionManager mgr, String sessionKey)
276:                    throws SessionException;
277:
278:            /**
279:             * Deletes a paged session.  If the session doesn't exist then this
280:             * is a noop.
281:             *
282:             * @param sessionKey the key identifying the session
283:             *   that should be deleted.
284:             */
285:            protected abstract void deleteSession(String sessionKey)
286:                    throws SessionException;
287:
288:            /**
289:             * Returns the session associated with the session key.
290:             * The session must already be associated with the current thread
291:             * otherwize null is returned.
292:             *
293:             * @param sessionKey the session key
294:             * @return the session.
295:             * @see #getSession(Thread, String)
296:             * @exception SessionException
297:             *   if the session could not be retrieved.
298:             */
299:            public synchronized StandardSession getSession(String sessionKey)
300:                    throws SessionException {
301:                // v. strahinja, 01 okt 2002          debug(3, "get session: key = " + sessionKey);
302:                debug("get session: key = " + sessionKey);
303:                SessionThread activeKey = new SessionThread(Thread
304:                        .currentThread(), sessionKey);
305:                PagedSession s = (PagedSession) activeThreadCache
306:                        .get(activeKey);
307:                return s;
308:            }
309:
310:            /**
311:             * Returns the session associated with the session key.
312:             * The session is associated with the specified thread.
313:             * The session is put into the 'active' state.
314:             *
315:             * @param thread the thread to associate with the session.
316:             * @param sessionKey the session key for the session
317:             *   that will be made 'active' and returned.  If the
318:             *   session doesn't exist or it hasn't been
319:             *   associated with this thread then null is returned.
320:             * @return the session.
321:             * @exception SessionException
322:             *   if the session could not be retrieved.
323:             */
324:            public synchronized StandardSession getSession(Thread thread,
325:                    String sessionKey) throws SessionException {
326:                // v. strahinja, 01 okt 2002          debug(3, "getSession: " + sessionKey);
327:                debug("getSession: " + sessionKey);
328:                SessionThread activeKey = new SessionThread(thread, sessionKey);
329:                PagedSession s = (PagedSession) activeThreadCache
330:                        .get(activeKey);
331:                if (s == null) {
332:                    s = (PagedSession) activeCache.get(sessionKey);
333:                    if (s == null) {
334:                        s = activateSession(sessionKey);
335:                    }
336:                    if (s != null) {
337:                        activeThreadCache.put(activeKey, s);
338:                        // keeps track of # of threads that reference session
339:                        s.incrementRefCount();
340:                    }
341:                }
342:                return s;
343:            }
344:
345:            /**
346:             * Removes the session associated with the session key.
347:             *
348:             * @param sessionKey the session key for the session
349:             *   that will be made 'active' and returned.
350:             * @return the session.
351:             * @exception SessionException
352:             *   if the session couldn't be removed.
353:             */
354:            public synchronized void removeSession(String sessionKey)
355:                    throws SessionException {
356:                // v. strahinja, 01 okt 2002          debug(3, "removeSession: " + sessionKey);
357:                debug("removeSession: " + sessionKey);
358:                Enumeration e = activeThreadCache.keys();
359:                while (e.hasMoreElements()) {
360:                    SessionThread key = (SessionThread) e.nextElement();
361:                    if (key.sessionKey.equals(sessionKey)) {
362:                        activeThreadCache.remove(key);
363:                    }
364:                }
365:                activeCache.remove(sessionKey);
366:                passiveCache.remove(sessionKey);
367:                deleteSession(sessionKey);
368:                notify();
369:            }
370:
371:            /**
372:             * Puts an 'active' session into the 'passive' state.
373:             *
374:             * @param thread the thread associated with the session.
375:             * @param sessionKey the session key for the session
376:             *   that will be made persistent.
377:             * @exception SessionException
378:             *   if the session coulnd not be put into the passive state.
379:             */
380:            public synchronized void passivateSession(Thread thread,
381:                    String sessionKey) throws SessionException {
382:                SessionThread activeKey = new SessionThread(thread, sessionKey);
383:                try {
384:                    // v. strahinja, 01 okt 2002              debug(3, "passivateSession: " + activeKey);
385:                    debug("passivateSession: " + activeKey);
386:                    if (activeThreadCache.containsKey(activeKey)) {
387:                        PagedSession s = (PagedSession) activeThreadCache
388:                                .remove(activeKey);
389:                        s.decrementRefCount();
390:                        // If there aren't any other threads associated with the session
391:                        if (s.getRefCount() == 0) {
392:                            if (isWriteThroughCache()) {
393:                                pageOut(s);
394:                            } else if ((pageThreshold < 0)
395:                                    || ((activeCache.size() + passiveCache
396:                                            .size()) < pageThreshold)) {
397:                                // v. strahinja, 01 okt 2002                          debug(3, "active -> passive: " + sessionKey);
398:                                debug("active -> passive: " + sessionKey);
399:                                passiveCache.put(sessionKey, s);
400:                            } else {
401:                                pageOut(s);
402:                            }
403:                            activeCache.remove(sessionKey);
404:                        }
405:                    } else {
406:                        // v. strahinja, 01 okt 2002                  debug(3, "passivateSession called but active session "
407:                        debug("passivateSession called but active session "
408:                                + " doesn't exist: " + sessionKey);
409:                    }
410:                } catch (Exception e) {
411:                    throw new SessionException(e);
412:                } finally {
413:                    notify();
414:                }
415:            }
416:
417:            /**
418:             * Pages a session to disk.
419:             *
420:             * @param session the session to page.
421:             * @exception SessionException if the paged session could not be
422:             *   paged out.
423:             */
424:            protected abstract void pageOut(PagedSession s)
425:                    throws SessionException;
426:
427:            /**
428:             * Reads a paged session from disk.
429:             *
430:             * @param sessionKey the key identifying the session that should
431:             *   be paged in.
432:             * @return the paged session that was read in.  May be null if
433:             *   the session referenced by sessionKey doesn't exist.
434:             * @exception SessionException if the paged session could not be
435:             *   read in.
436:             */
437:            protected abstract PagedSession pageIn(String sessionKey)
438:                    throws SessionException;
439:
440:            /**
441:             * Returns the number of paged sessions.
442:             */
443:            protected abstract int getPagedSessionCount()
444:                    throws SessionException;
445:
446:            /**
447:             * Puts a session into the 'active' state.  Reads paged version
448:             * if necessary.
449:             *
450:             * @param activeKey the session-thread key for the session
451:             *   that should be activated.
452:             * @exception SessionException
453:             *   if the session cannot be activated.
454:             */
455:            private synchronized PagedSession activateSession(String sessionKey)
456:                    throws SessionException {
457:                PagedSession session = null;
458:                boolean isPaged = !activeCache.containsKey(sessionKey)
459:                        && !passiveCache.containsKey(sessionKey);
460:                // v. strahinja, 01 okt 2002          debug(3, "activateSession: " + sessionKey);
461:                debug("activateSession: " + sessionKey);
462:                if (isPaged) {
463:                    ensureNewSession();
464:                    session = pageIn(sessionKey);
465:                } else if (passiveCache.containsKey(sessionKey)) {
466:                    // v. strahinja, 01 okt 2002              debug(3, "passive -> active : " + sessionKey);
467:                    debug("passive -> active : " + sessionKey);
468:                    session = (PagedSession) passiveCache.remove(sessionKey);
469:                } else if (activeCache.containsKey(sessionKey)) {
470:                    // v. strahinja, 01 okt 2002              debug(3, "session is active : " + sessionKey);
471:                    debug("session is active : " + sessionKey);
472:                    session = (PagedSession) activeCache.get(sessionKey);
473:                }
474:                if (session != null) {
475:                    activeCache.put(sessionKey, session);
476:                }
477:                return session;
478:            }
479:
480:            /**
481:             * Specifies if a key is currently in use.
482:             *
483:             * @param sessionKey the session key to be tested.
484:             * @return true if the session key is in use.
485:             * @exception SessionException if an error occurs.
486:             */
487:            public boolean containsKey(String sessionKey)
488:                    throws SessionException {
489:                if (activeCache.containsKey(sessionKey)
490:                        || passiveCache.containsKey(sessionKey)
491:                        || pagedSessionKeyExists(sessionKey)) {
492:                    return true;
493:                }
494:                return false;
495:            }
496:
497:            /**
498:             * Returns true if the specified session key is in use
499:             * by a session that has been paged out.
500:             *
501:             * @param sessionKey the session key to test.
502:             * @return true if the session key is in use by a paged session.
503:             * @exception SessionException if an error occurs.
504:             */
505:            protected abstract boolean pagedSessionKeyExists(String sessionKey)
506:                    throws SessionException;
507:
508:            /**
509:             * Returns the current number of sessions.
510:             *
511:             * @return the session count.
512:             * @exception SessionException if an error occurs.
513:             */
514:            public int size() throws SessionException {
515:                return activeCache.size() + passiveCache.size()
516:                        + getPagedSessionCount();
517:            }
518:
519:            /**
520:             * Returns the current number of sessions that are paged to
521:             * persistent store.
522:             *
523:             * @return
524:             *   the 'paged' session count.
525:             * @exception SessionException
526:             *   if the size cannot be determined
527:             */
528:            public int pagedSize() throws SessionException {
529:                return getPagedSessionCount();
530:            }
531:
532:            /**
533:             * Returns an enumeration of keys for the cached sessions.
534:             *
535:             * @return the session keys enumeration.
536:             * @exception SessionException if an error occurs.
537:             */
538:            public synchronized Enumeration keys() throws SessionException {
539:                try {
540:                    Vector v = new Vector();
541:                    String sessionKey;
542:                    Enumeration e;
543:                    e = activeCache.keys();
544:                    while (e.hasMoreElements()) {
545:                        sessionKey = (String) e.nextElement();
546:                        if (!v.contains(sessionKey)) {
547:                            v.addElement(sessionKey);
548:                        }
549:                    }
550:                    e = passiveCache.keys();
551:                    while (e.hasMoreElements()) {
552:                        sessionKey = (String) e.nextElement();
553:                        if (!v.contains(sessionKey)) {
554:                            v.addElement(sessionKey);
555:                        }
556:                    }
557:                    e = getPagedSessionKeys();
558:                    while (e.hasMoreElements()) {
559:                        sessionKey = (String) e.nextElement();
560:                        if (!v.contains(sessionKey)) {
561:                            v.addElement(sessionKey);
562:                        }
563:                    }
564:                    return v.elements();
565:                } catch (Exception e) {
566:                    throw new SessionException(e);
567:                }
568:            }
569:
570:            /**
571:             * Returns an enumeration of the keys of all the sessions that have
572:             * been paged out to persistent storage.
573:             *
574:             * @return the session key enumeration.
575:             * @exception SessionException if an error occurs.
576:             */
577:            protected abstract Enumeration getPagedSessionKeys()
578:                    throws SessionException;
579:
580:            /**
581:             * Cleans up (removes) the oldest unused (new) session from the
582:             * passive cache.
583:             *
584:             * @return true if an unused session was cleaned up.
585:             */
586:            private void cleanupNewSession() throws SessionException {
587:                if (!cleanupNewPagedSession()) {
588:                    Enumeration e;
589:                    String key = null;
590:                    long oldestTime = -1;
591:                    e = passiveCache.keys();
592:                    while (e.hasMoreElements()) {
593:                        PagedSession s = (PagedSession) passiveCache.get(e
594:                                .nextElement());
595:                        if (s.isNew()) {
596:                            if ((oldestTime < 0)
597:                                    || (s.getTimeCreated() < oldestTime)) {
598:                                oldestTime = s.getTimeCreated();
599:                                key = s.getSessionKey();
600:                            }
601:                        }
602:                    }
603:                    if (key != null) {
604:                        removeSession(key);
605:                    }
606:                }
607:            }
608:
609:            /**
610:             * Pages out any sessions that are passive and have exceeded
611:             * the page time threshold.
612:             *
613:             * @return returns the amount of time in milliseconds when
614:             *   the next check should occur.
615:             */
616:            long checkPassiveSessions() throws SessionException {
617:                return checkPassiveSessions(pageTimeThreshold);
618:            }
619:
620:            /**
621:             * Pages out any sessions that are passive and have exceeded
622:             * the page time threshold.
623:             *
624:             * @param threshold the threshold when a passive session
625:             *   should be paged.
626:             * @return returns the amount of time in milliseconds when
627:             *   the next check should occur.
628:             */
629:            private synchronized long checkPassiveSessions(long threshold)
630:                    throws SessionException {
631:                long nextCheck = threshold;
632:                Enumeration e = passiveCache.elements();
633:                long now = System.currentTimeMillis();
634:                while (e.hasMoreElements()) {
635:                    PagedSession s = (PagedSession) e.nextElement();
636:                    long passiveTime = now - s.getTimeLastUsed();
637:                    if (passiveTime >= threshold) {
638:                        pageOut(s);
639:                        passiveCache.remove(s.getSessionKey());
640:                    } else if (nextCheck > (threshold - passiveTime)) {
641:                        nextCheck = threshold - passiveTime;
642:                    }
643:                }
644:                return nextCheck;
645:            }
646:
647:            /**
648:             * Removes a session that is new and paged.
649:             *
650:             * @return true is a new session was found and deleted.
651:             * @exception SessionException if an error occurs.
652:             */
653:            protected abstract boolean cleanupNewPagedSession()
654:                    throws SessionException;
655:
656:            /**
657:             * Ensures that a new session can be put into the list
658:             * in-core sessions that are being managed.
659:             * If necessary, this method will page a passive session disk in
660:             * in order to guarantee that another session can be
661:             * read into memory (or created).  This method may block
662:             * if a session first needs to be paged to disk.
663:             */
664:            private void ensureNewSession() throws SessionException {
665:                if (pageThreshold > 0) { // If not a write-through cache....
666:                    while ((activeCache.size() + passiveCache.size()) > pageThreshold) {
667:                        if (passiveCache.size() == 0) {
668:                            try {
669:                                // v. strahinja, 01 okt 2002                          debug(3, "waiting for a passive session that can be paged...");
670:                                debug("waiting for a passive session that can be paged...");
671:                                wait(pageWait);
672:                                if (passiveCache.size() <= 0) {
673:                                    throw new SessionException(
674:                                            "Unable to activate session: "
675:                                                    + "no sessions are ready to be paged.");
676:                                }
677:                            } catch (InterruptedException e) {
678:                                // ignore
679:                            }
680:                        } else {
681:                            // v. strahinja, 01 okt 2002                      debug(3, "a passive session ready to be paged");
682:                            debug("a passive session ready to be paged");
683:                            Enumeration keys = passiveCache.keys();
684:                            PagedSession s = (PagedSession) passiveCache
685:                                    .get((String) keys.nextElement());
686:                            pageOut(s);
687:                            passiveCache.remove(s.getSessionKey());
688:                        }
689:                    }
690:                }
691:            }
692:
693:            /**
694:             * Shuts down the session home.  Pages out all active sessions.
695:             */
696:            public synchronized void shutdown() {
697:                try {
698:                    if (thresholdTimer != null) {
699:                        thresholdTimer.shutdown();
700:                        thresholdTimer = null;
701:                    }
702:                    // DT 17.11.2003 BEG
703:                    Enumeration e = activeThreadCache.keys();
704:                    while (e.hasMoreElements()) {
705:                        SessionThread s = (SessionThread) e.nextElement();
706:                        passivateSession(s.thread, s.sessionKey);
707:                    }
708:                    // DT 17.11.2003 END
709:                    checkPassiveSessions(0);
710:                } catch (Exception e) {
711:                    Enhydra
712:                            .getLogChannel()
713:                            .write(
714:                                    Logger.ERROR,
715:                                    "PagedSessionHome: "
716:                                            + "failed to page out active and passive sessions.",
717:                                    e);
718:                }
719:            }
720:
721:            /**
722:             * Returns true if the current configuration is for
723:             * a write trhough cache.
724:             *
725:             * @return true if write through cache is configured.
726:             */
727:            private boolean isWriteThroughCache() {
728:                return (pageThreshold == 0);
729:            }
730:
731:            /**
732:             * Prints debug information under Logger.DEBUG.
733:             *
734:             * @param msg the message to print.
735:             */
736:            protected void debug(String msg) {
737:                debug(0, msg);
738:            }
739:
740:            /**
741:             * Prints debug information under Logger.DEBUG.
742:             *
743:             * @param level the debug level.
744:             * @param msg the message to print.
745:             */
746:            protected void debug(int level, String msg) {
747:                int dbg = Logger.DEBUG;
748:                switch (level) {
749:                case 1:
750:                    dbg = Logger.DEBUG1;
751:                    break;
752:                case 2:
753:                    dbg = Logger.DEBUG2;
754:                    break;
755:                case 3:
756:                    dbg = Logger.DEBUG3;
757:                    break;
758:                case 4:
759:                    dbg = Logger.DEBUG4;
760:                    break;
761:                case 5:
762:                    dbg = Logger.DEBUG5;
763:                    break;
764:                case 6:
765:                    dbg = Logger.DEBUG6;
766:                    break;
767:                case 7:
768:                    dbg = Logger.DEBUG7;
769:                    break;
770:                case 8:
771:                    dbg = Logger.DEBUG8;
772:                    break;
773:                case 9:
774:                    dbg = Logger.DEBUG9;
775:                    break;
776:                default:
777:                    dbg = Logger.DEBUG;
778:                    break;
779:                }
780:                Enhydra.getLogChannel().write(
781:                        dbg,
782:                        "PersistentSessionHome("
783:                                + Thread.currentThread().getName() + "): "
784:                                + msg);
785:            }
786:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.