Source Code Cross Referenced for LRUEnterpriseContextCachePolicy.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » plugins » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.plugins 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.ArrayList;
025:        import java.util.Timer;
026:        import java.util.TimerTask;
027:
028:        import org.jboss.deployment.DeploymentException;
029:        import org.jboss.ejb.EnterpriseContext;
030:        import org.jboss.logging.Logger;
031:        import org.jboss.metadata.MetaData;
032:        import org.jboss.metadata.XmlLoadable;
033:        import org.jboss.monitor.Monitorable;
034:        import org.jboss.monitor.client.BeanCacheSnapshot;
035:        import org.jboss.util.LRUCachePolicy;
036:        import org.w3c.dom.Element;
037:
038:        /**
039:         * Least Recently Used cache policy for EnterpriseContexts.
040:         *
041:         * @see AbstractInstanceCache
042:         * @author <a href="mailto:simone.bordet@compaq.com">Simone Bordet</a>
043:         * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
044:         * @version $Revision: 57209 $
045:         */
046:        public class LRUEnterpriseContextCachePolicy extends LRUCachePolicy
047:                implements  XmlLoadable, Monitorable {
048:            // Constants -----------------------------------------------------
049:
050:            // Attributes ----------------------------------------------------
051:            protected static Logger log = Logger
052:                    .getLogger(LRUEnterpriseContextCachePolicy.class);
053:            protected static Timer tasksTimer = new Timer(true);
054:            static {
055:                log.debug("Cache policy timer started, tasksTimer="
056:                        + tasksTimer);
057:            }
058:
059:            /** The AbstractInstanceCache that uses this cache policy */
060:            private AbstractInstanceCache m_cache;
061:
062:            /** The period of the resizer's runs */
063:            private long m_resizerPeriod;
064:
065:            /** The period of the overager's runs */
066:            private long m_overagerPeriod;
067:
068:            /** The age after which a bean is automatically passivated */
069:            private long m_maxBeanAge;
070:
071:            /**
072:             * Enlarge cache capacity if there is a cache miss every or less
073:             * this member's value
074:             */
075:            private long m_minPeriod;
076:
077:            /**
078:             * Shrink cache capacity if there is a cache miss every or more
079:             * this member's value
080:             */
081:            private long m_maxPeriod;
082:
083:            /**
084:             * The resizer will always try to keep the cache capacity so
085:             * that the cache is this member's value loaded of cached objects
086:             */
087:            private double m_factor;
088:
089:            /** The overager timer task */
090:            private TimerTask m_overager;
091:
092:            /** The resizer timer task */
093:            private TimerTask m_resizer;
094:
095:            /** Useful for log messages */
096:            private StringBuffer m_buffer = new StringBuffer();
097:
098:            // Static --------------------------------------------------------
099:
100:            // Constructors --------------------------------------------------
101:
102:            /**
103:             * Creates a LRU cache policy object given the instance cache that use
104:             * this policy object.
105:             */
106:            public LRUEnterpriseContextCachePolicy(AbstractInstanceCache eic) {
107:                if (eic == null)
108:                    throw new IllegalArgumentException(
109:                            "Instance cache argument cannot be null");
110:
111:                m_cache = eic;
112:            }
113:
114:            // Public --------------------------------------------------------
115:
116:            // Monitorable implementation ------------------------------------
117:
118:            public void sample(Object s) {
119:                if (m_cache == null)
120:                    return;
121:
122:                BeanCacheSnapshot snapshot = (BeanCacheSnapshot) s;
123:                LRUList list = getList();
124:                synchronized (m_cache.getCacheLock()) {
125:                    snapshot.m_cacheMinCapacity = list.m_minCapacity;
126:                    snapshot.m_cacheMaxCapacity = list.m_maxCapacity;
127:                    snapshot.m_cacheCapacity = list.m_capacity;
128:                    snapshot.m_cacheSize = list.m_count;
129:                }
130:            }
131:
132:            // Z implementation ----------------------------------------------
133:
134:            public void start() {
135:                if (m_resizerPeriod > 0) {
136:                    m_resizer = new ResizerTask(m_resizerPeriod);
137:                    long delay = (long) (Math.random() * m_resizerPeriod);
138:                    tasksTimer.schedule(m_resizer, delay, m_resizerPeriod);
139:                }
140:
141:                if (m_overagerPeriod > 0) {
142:                    m_overager = new OveragerTask(m_overagerPeriod);
143:                    long delay = (long) (Math.random() * m_overagerPeriod);
144:                    tasksTimer.schedule(m_overager, delay, m_overagerPeriod);
145:                }
146:            }
147:
148:            public void stop() {
149:                if (m_resizer != null) {
150:                    m_resizer.cancel();
151:                }
152:                if (m_overager != null) {
153:                    m_overager.cancel();
154:                }
155:                super .stop();
156:            }
157:
158:            public void destroy() {
159:                m_overager = null;
160:                m_resizer = null;
161:                m_cache = null;
162:                super .destroy();
163:            }
164:
165:            /**
166:             * Reads from the configuration the parameters for this cache policy, that are
167:             * all optionals.
168:             * FIXME 20010626 marcf:
169:             *  Simone seriously arent' all the options overkill? give it another 6 month .
170:             *	 Remember you are exposing the guts of this to the end user, also provide defaults
171:             *  so that if an entry is not specified you can still work and it looks _much_ better in
172:             *  the configuration files.
173:             *
174:             */
175:            public void importXml(Element element) throws DeploymentException {
176:                String min = MetaData.getElementContent(MetaData
177:                        .getOptionalChild(element, "min-capacity"));
178:                String max = MetaData.getElementContent(MetaData
179:                        .getOptionalChild(element, "max-capacity"));
180:                String op = MetaData.getElementContent(MetaData
181:                        .getOptionalChild(element, "overager-period"));
182:                String rp = MetaData.getElementContent(MetaData
183:                        .getOptionalChild(element, "resizer-period"));
184:                String ma = MetaData.getElementContent(MetaData
185:                        .getOptionalChild(element, "max-bean-age"));
186:                String map = MetaData.getElementContent(MetaData
187:                        .getOptionalChild(element, "max-cache-miss-period"));
188:                String mip = MetaData.getElementContent(MetaData
189:                        .getOptionalChild(element, "min-cache-miss-period"));
190:                String fa = MetaData.getElementContent(MetaData
191:                        .getOptionalChild(element, "cache-load-factor"));
192:                try {
193:                    if (min != null) {
194:                        int s = Integer.parseInt(min);
195:                        if (s <= 0) {
196:                            throw new DeploymentException(
197:                                    "Min cache capacity can't be <= 0");
198:                        }
199:                        m_minCapacity = s;
200:                    }
201:                    if (max != null) {
202:                        int s = Integer.parseInt(max);
203:                        if (s <= 0) {
204:                            throw new DeploymentException(
205:                                    "Max cache capacity can't be <= 0");
206:                        }
207:                        m_maxCapacity = s;
208:                    }
209:                    if (op != null) {
210:                        int p = Integer.parseInt(op);
211:                        if (p <= 0) {
212:                            throw new DeploymentException(
213:                                    "Overager period can't be <= 0");
214:                        }
215:                        m_overagerPeriod = p * 1000;
216:                    }
217:                    if (rp != null) {
218:                        int p = Integer.parseInt(rp);
219:                        if (p <= 0) {
220:                            throw new DeploymentException(
221:                                    "Resizer period can't be <= 0");
222:                        }
223:                        m_resizerPeriod = p * 1000;
224:                    }
225:                    if (ma != null) {
226:                        int a = Integer.parseInt(ma);
227:                        if (a <= 0) {
228:                            throw new DeploymentException(
229:                                    "Max bean age can't be <= 0");
230:                        }
231:                        m_maxBeanAge = a * 1000;
232:                    }
233:                    if (map != null) {
234:                        int p = Integer.parseInt(map);
235:                        if (p <= 0) {
236:                            throw new DeploymentException(
237:                                    "Max cache miss period can't be <= 0");
238:                        }
239:                        m_maxPeriod = p * 1000;
240:                    }
241:                    if (mip != null) {
242:                        int p = Integer.parseInt(mip);
243:                        if (p <= 0) {
244:                            throw new DeploymentException(
245:                                    "Min cache miss period can't be <= 0");
246:                        }
247:                        m_minPeriod = p * 1000;
248:                    }
249:                    if (fa != null) {
250:                        double f = Double.parseDouble(fa);
251:                        if (f <= 0.0) {
252:                            throw new DeploymentException(
253:                                    "Cache load factor can't be <= 0");
254:                        }
255:                        m_factor = f;
256:                    }
257:                } catch (NumberFormatException x) {
258:                    throw new DeploymentException(
259:                            "Can't parse policy configuration", x);
260:                }
261:            }
262:
263:            // Y overrides ---------------------------------------------------
264:
265:            /**
266:             * Flush is overriden here because in this policy impl
267:             * flush might not actually remove all the instances from the cache.
268:             * Those instances that are in use (associated with a transaction) should not
269:             * be removed from the cache. So, the iteration is done not until the cache is empty
270:             * but until we tried to age-out every instance in the cache.
271:             */
272:            public void flush() {
273:                int i = size();
274:                LRUCacheEntry entry = null;
275:                while (i-- > 0 && (entry = m_list.m_tail) != null) {
276:                    ageOut(entry);
277:                }
278:            }
279:
280:            // Package protected ---------------------------------------------
281:
282:            // Protected -----------------------------------------------------
283:
284:            protected LRUList createList() {
285:                return new ContextLRUList();
286:            }
287:
288:            protected void ageOut(LRUCacheEntry entry) {
289:                if (m_cache == null)
290:                    return;
291:
292:                if (entry == null) {
293:                    throw new IllegalArgumentException(
294:                            "Cannot remove a null cache entry");
295:                }
296:
297:                if (log.isTraceEnabled()) {
298:                    m_buffer.setLength(0);
299:                    m_buffer.append("Aging out from cache bean ");
300:                    m_buffer.append(m_cache.getContainer().getBeanMetaData()
301:                            .getEjbName());
302:                    m_buffer.append("with id = ");
303:                    m_buffer.append(entry.m_key);
304:                    m_buffer.append("; cache size = ");
305:                    m_buffer.append(getList().m_count);
306:                    log.trace(m_buffer.toString());
307:                }
308:
309:                // This will schedule the passivation
310:                m_cache.release((EnterpriseContext) entry.m_object);
311:            }
312:
313:            protected void cacheMiss() {
314:                LRUList list = getList();
315:                ++list.m_cacheMiss;
316:            }
317:
318:            // Private -------------------------------------------------------
319:
320:            private LRUList getList() {
321:                return m_list;
322:            }
323:
324:            // Inner classes -------------------------------------------------
325:
326:            /**
327:             * This TimerTask resizes the cache capacity using the cache miss frequency
328:             * algorithm, that is the more cache misses we have, the more the cache size
329:             * is enlarged, and viceversa. <p>
330:             * Of course, the maximum and minimum capacity are the bounds that this
331:             * resizer never passes.
332:             */
333:            protected class ResizerTask extends TimerTask {
334:                private String m_message;
335:                private StringBuffer m_buffer;
336:                private long resizerPeriod;
337:
338:                protected ResizerTask(long resizerPeriod) {
339:                    this .resizerPeriod = resizerPeriod;
340:                    m_message = "Resized cache for bean "
341:                            + m_cache.getContainer().getBeanMetaData()
342:                                    .getEjbName() + ": old capacity = ";
343:                    m_buffer = new StringBuffer();
344:                }
345:
346:                public void run() {
347:                    // For now implemented as a Cache Miss Frequency algorithm
348:                    if (m_cache == null) {
349:                        cancel();
350:                        return;
351:                    }
352:
353:                    LRUList list = getList();
354:
355:                    // Sync with the cache, since it is accessed also by another thread
356:                    synchronized (m_cache.getCacheLock()) {
357:                        int period = list.m_cacheMiss == 0 ? Integer.MAX_VALUE
358:                                : (int) (resizerPeriod / list.m_cacheMiss);
359:                        int cap = list.m_capacity;
360:                        if (period <= m_minPeriod && cap < list.m_maxCapacity) {
361:                            // Enlarge cache capacity: if period == m_minPeriod then
362:                            // the capacity is increased of the (1-m_factor)*100 %.
363:                            double factor = 1.0
364:                                    + ((double) m_minPeriod / period)
365:                                    * (1.0 - m_factor);
366:                            int newCap = (int) (cap * factor);
367:                            list.m_capacity = newCap < list.m_maxCapacity ? newCap
368:                                    : list.m_maxCapacity;
369:                            log(cap, list.m_capacity);
370:                        } else if (period >= m_maxPeriod
371:                                && cap > list.m_minCapacity
372:                                && list.m_count < (cap * m_factor)) {
373:                            // Shrink cache capacity
374:                            int newCap = (int) (list.m_count / m_factor);
375:                            list.m_capacity = newCap > list.m_minCapacity ? newCap
376:                                    : list.m_minCapacity;
377:                            log(cap, list.m_capacity);
378:                        }
379:                        list.m_cacheMiss = 0;
380:                    }
381:                }
382:
383:                private void log(int oldCapacity, int newCapacity) {
384:                    if (log.isTraceEnabled()) {
385:                        m_buffer.setLength(0);
386:                        m_buffer.append(m_message);
387:                        m_buffer.append(oldCapacity);
388:                        m_buffer.append(", new capacity = ");
389:                        m_buffer.append(newCapacity);
390:                        log.trace(m_buffer.toString());
391:                    }
392:                }
393:            }
394:
395:            /**
396:             * This TimerTask passivates cached beans that have not been called for a while.
397:             */
398:            protected class OveragerTask extends TimerTask {
399:                private String m_message;
400:                private StringBuffer m_buffer;
401:
402:                protected OveragerTask(long period) {
403:                    m_message = getTaskLogMessage()
404:                            + " "
405:                            + m_cache.getContainer().getBeanMetaData()
406:                                    .getEjbName() + " with id = ";
407:                    m_buffer = new StringBuffer();
408:                }
409:
410:                public void run() {
411:                    if (m_cache == null) {
412:                        cancel();
413:                        return;
414:                    }
415:
416:                    LRUList list = getList();
417:                    long now = System.currentTimeMillis();
418:                    ArrayList passivateEntries = null;
419:                    synchronized (m_cache.getCacheLock()) {
420:                        for (LRUCacheEntry entry = list.m_tail; entry != null; entry = entry.m_prev) {
421:                            if (now - entry.m_time >= getMaxAge()) {
422:                                // Attempt to remove this entry from cache
423:                                if (passivateEntries == null)
424:                                    passivateEntries = new ArrayList();
425:                                passivateEntries.add(entry);
426:                            } else {
427:                                break;
428:                            }
429:                        }
430:                    }
431:                    // We need to do this outside of cache lock because of deadlock possibilities
432:                    // with EntityInstanceInterceptor and Stateful. This is because tryToPassivate
433:                    // calls lock.synch and other interceptor call lock.synch and after call a cache method that locks
434:                    if (passivateEntries != null) {
435:                        for (int i = 0; i < passivateEntries.size(); i++) {
436:                            LRUCacheEntry entry = (LRUCacheEntry) passivateEntries
437:                                    .get(i);
438:                            try {
439:                                m_cache
440:                                        .tryToPassivate((EnterpriseContext) entry.m_object);
441:                            } catch (Throwable t) {
442:                                log
443:                                        .debug(
444:                                                "Ignored error while trying to passivate ctx",
445:                                                t);
446:                            }
447:                        }
448:                    }
449:                }
450:
451:                private void log(Object key, int count) {
452:                    if (log.isTraceEnabled()) {
453:                        m_buffer.setLength(0);
454:                        m_buffer.append(m_message);
455:                        m_buffer.append(key);
456:                        m_buffer.append(" - Cache size = ");
457:                        m_buffer.append(count);
458:                        log.trace(m_buffer.toString());
459:                    }
460:                }
461:
462:                protected String getTaskLogMessage() {
463:                    return "Scheduling for passivation overaged bean";
464:                }
465:
466:                protected String getJMSTaskType() {
467:                    return "OVERAGER";
468:                }
469:
470:                protected long getMaxAge() {
471:                    return m_maxBeanAge;
472:                }
473:            }
474:
475:            /**
476:             * Subclass that logs list activity events.
477:             */
478:            protected class ContextLRUList extends LRUList {
479:                boolean trace = log.isTraceEnabled();
480:
481:                protected void entryPromotion(LRUCacheEntry entry) {
482:                    if (trace)
483:                        log.trace("entryPromotion, entry=" + entry);
484:
485:                    // The cache is full, temporarily increase it
486:                    if (m_count == m_capacity && m_capacity >= m_maxCapacity) {
487:                        ++m_capacity;
488:                        log
489:                                .warn("Cache has reached maximum capacity for container "
490:                                        + m_cache.getContainer().getJmxName()
491:                                        + " - probably because all instances are in use. "
492:                                        + "Temporarily increasing the size to "
493:                                        + m_capacity);
494:                    }
495:                }
496:
497:                protected void entryAdded(LRUCacheEntry entry) {
498:                    if (trace)
499:                        log.trace("entryAdded, entry=" + entry);
500:                }
501:
502:                protected void entryRemoved(LRUCacheEntry entry) {
503:                    if (trace)
504:                        log.trace("entryRemoved, entry=" + entry);
505:                }
506:
507:                protected void capacityChanged(int oldCapacity) {
508:                    if (trace)
509:                        log
510:                                .trace("capacityChanged, oldCapacity="
511:                                        + oldCapacity);
512:                }
513:            }
514:
515:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.