1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4
<link rel="STYLESHEET" type="text/css"
5
href="../css/site.css">
9
<div id="page-logo"> <img src="../images/ehcache_logo_trans.gif"
10
alt="ehcache" align="left">Constructs Documentation</div>
11
<div id="page-buttons">
12
<a href="http://sourceforge.net/projects/ehcache/">Summary</a> |
13
<a href="http://sourceforge.net/project/admin/?group_id=93232">Admin</a> |
14
<a href="../"><span class="tabs">Home Page</span></a> | <a
15
href="http://sourceforge.net/forum/?group_id=93232">Forums</a> |
16
<a href="http://sourceforge.net/tracker/?group_id=93232">Tracker</a> |
17
<a href="http://sourceforge.net/tracker/?group_id=93232">Bugs</a> |
18
<a href="http://sourceforge.net/tracker/?group_id=93232">Support</a> |
19
<a href="http://sourceforge.net/tracker/?group_id=93232">Patches</a> |
20
<a href="http://sourceforge.net/tracker/?group_id=93232">RFE</a> |
21
<a href="http://sourceforge.net/mail/?group_id=93232">Lists</a> |
22
<a href="http://sourceforge.net/pm/?group_id=93232">Tasks</a> |
23
<a href="http://ehcache.sourceforge.net/documentation/">Docs</a> |
24
<a href="http://sourceforge.net/news/?group_id=93232">News</a> |
25
<a href="http://sourceforge.net/svn/?group_id=93232">SVN</a> |
26
<a href="http://sourceforge.net/project/showfiles.php?group_id=93232">Files</a><br>
30
<div class="toc">Table of Contents</div>
32
<!--mozToc h1 1 h2 2 h3 3 h4 4--><li><a href="#mozTocId544025">1
36
<li><a href="#mozTocId177637">Constructs</a></li>
37
<li><a href="#mozTocId304590">Caching meets
38
Concurrent Programming
41
<li><a href="#mozTocId626748">Safety Failures</a></li>
42
<li><a href="#mozTocId946646">Liveness Failures</a></li>
47
<li><a href="#mozTocId764933">2 Provided Pattern
51
<li><a href="#mozTocId225705">General Purpose
53
<li><a href="#mozTocId997710">Web Caching
57
<li><a href="#mozTocId366944">3 Java
59
<li><a href="#mozTocId477330">4 Dependencies</a></li>
60
<li><a href="#mozTocId747622">5 Installation
62
<li><a href="#mozTocId265501">6 Logging</a></li>
63
<li><a href="#mozTocId430833">7 Obtaining the
66
<li><a href="#mozTocId688132">Online
68
<li><a href="#mozTocId244950">CVS</a></li>
71
<li><a href="#mozTocId722946">8 Using The Constructs </a>
73
<li><a href="#mozTocId937608">BlockingCache</a>
75
<li><a href="#mozTocId159833">Scenario</a></li>
76
<li><a href="#mozTocId22662">Solution</a></li>
77
<li><a href="#mozTocId659272">Implementation</a></li>
80
<li><a href="#mozTocId640475">SelfPopulatingCache</a>
82
<li><a href="#mozTocId483719">Scenario</a></li>
83
<li><a href="#mozTocId598598">Solution</a></li>
84
<li><a href="#mozTocId563482">Implementation</a></li>
91
<h1><a class="mozTocH1" name="mozTocId544025"></a>1 Introduction<br>
93
Ehcache-constructs provides implementations of common caching patterns.
94
They can be used as they are or as a starting pointing for custom
95
caching code. Ehcache-constructs uses ehcache for the backing cache. <br>
96
<h2><a class="mozTocH2" name="mozTocId177637"></a>Constructs</h2>
97
Doug Lea in his book <a
98
href="http://www.amazon.com/gp/reader/0201310090/ref=sib_dp_pt/104-1236350-6447122#reader-link">Concurrent
99
Programming in Java</a> talks about concurrency support constructs. One
100
meaning of a construct is "an abstract or general idea inferred or
101
derived from specific instances". Just like patterns emerge from
102
noting the similarities of problems and gradually finding a solution to
103
classes of them, so to constructs are general solutions to commond
104
problems. With ehcache-constructs, concrete, extensible implementations
105
are offered to solve these common problems.<br>
106
<h2><a class="mozTocH2" name="mozTocId304590"></a>Caching meets
107
Concurrent Programming<br>
109
All of the constructs use a combination of ehcache and concurrent
110
programming. As Adam, a friend of mine says, "What could possibly go
111
wrong?" Well in concurrent programming, the answer is: "A lot".<br>
113
(The following section is based on Chapter 1.3 of Doug Lea's <a
114
href="http://www.amazon.com/gp/reader/0201310090/ref=sib_dp_pt/104-1236350-6447122#reader-link">Concurrent
115
Programming in Java</a>). <br>
117
There are two often conflicting design goals at play in concurrent
118
programming. They are:<br>
120
<li>liveness, where something eventually happens within an activity. <br>
122
<li>safety, where nothing bad ever happens to an object.</li>
124
<h3><a class="mozTocH3" name="mozTocId626748"></a>Safety Failures</h3>
126
Failures of safety include: <br>
128
<li>Read/Write Conflicts, where one thread is reading from a field
129
and another is writing to it. The value read depends on who won the
131
<li>Write/Write Conflicts, where two threads write to the same field.
132
The value on the next read is impossible to predict.</li>
134
A cache is similar to a global variable. By its nature it is accessible
135
to multiple threads. Because caching is often done for performance,
136
cache entries can be highly contended for.<br>
138
<h3><a class="mozTocH3" name="mozTocId946646"></a>Liveness Failures</h3>
140
Failures of liveness include:<br>
142
<li>Deadlock. This is caused by a circular dependency among locks.
143
The threads involved cannot make progress.</li>
144
<li>Missed Signals. A thread entered the wait state after a
145
notification to wake it up was produced.</li>
146
<li>Nested monitor lockouts. A waiting thread holds a lock needed by
147
a thread wishing to wake it up</li>
148
<li>Livelock. A continously retried action continously fails.</li>
149
<li>Starvation. Some threads never get allocated CPU time. <br>
151
<li>Resource Exhaustion. All resourcesof some kind are in use by
152
threads, none of which will give one up.</li>
153
<li>Distributed Failure. A remote machine connected by socket becomes
156
<li>Stampede. With notifyAll(), all threads wake up and in a
157
stampede, attempt to make progress.</li>
159
There are many different failures. Testing for all of them is tedious
160
and time-consuming. It is sometimes hard to foresee all of them. The
161
first <code>BlockingCache</code> implementation ran for almost a year
162
on a very busy application before finally getting overwhelmed. It was
163
using <code>notifyAll()</code>, and once the load on the cache got
164
very high indeed, the threads started spending most of their time
165
stampeding to the object lock and very little time doing anything else.
166
The result was that server threads went to 1500 and server output
167
dropped to almost nothing.<br>
169
Ehcache-constructs provides high-quality, unit and production-tested
170
implementations for developers to use. All
171
released constructs have had a minimum of several months production
172
use. Some of them have several years of production time. In
173
addition each one has tests in the test package. These tests include
174
concurrency and scalability tests. See the tests <a
175
href="http://cvs.sourceforge.net/viewcvs.py/ehcache/ehcache/test/java/net/sf/ehcache/constructs/blocking/">here</a>.
177
<h1><a class="mozTocH2" name="mozTocId764933"></a>2 Provided Pattern
180
<p>At present ehcache-constructs contains:<br>
182
<h2><a class="mozTocH3" name="mozTocId225705"></a>General Purpose
186
<li><a href="index.html#mozTocId937608">BlockingCache</a> - a cache
187
which blocks subsequent threads until the
188
first read thread populates a cache entry </li>
189
<li><a href="index.html#mozTocId640475">SelfPopulatingCache</a> - a
190
read-through cache. A cache that
191
populates elements as they are requested without requiring the caller
192
to know how the entries are populated. It also enables refreshes of
193
cache entries without blocking reads on the same entries.</li>
194
<li>UpdatingSelfPopulatingCache - a read-through cache. A cache that
195
populates elements as they are requested without requiring the caller
196
to know how the entries are populated. The cache entry is automatically
197
updated on subsequent reads. <br>
199
<li>SelfPopulatingCollectionsCache - a SelfPopulatingCache that adds
200
threading safety where it is known in advance that all entries will be
206
<h2><a class="mozTocH3" name="mozTocId997710"></a>Web Caching<br>
208
Servlet 2.3 caching filters that cache HTTP/S responses:<br>
210
<li>CachingFilter - an abstract, extensible caching filter.<br>
212
<li>SimplePageCachingFilter - a concrete implementation which caches
213
pages based on the request URI and Query String.<br>
215
<li>SimplePageFragmentCachingFilter - a concrete implementation which
216
caches page fragments based on the request URI and Query String.</li>
220
<h1><a class="mozTocH2" name="mozTocId366944"></a><span
221
style="font-weight: bold;">3 Java
222
Requirements</span></h1>
223
Ehcache-constructs supports
224
JDK1.2, 1.3, 1.4 and 5 at runtime. When compiling from source, the
226
process requires JDK 1.4 or 5. <span><br>
228
Ehcache-constructs does not work with JDK1.1.<br>
231
<h1><a class="mozTocH2" name="mozTocId477330"></a>4 Dependencies</h1>
232
<span></span>Ehcache-constructs requires:<br>
234
<li><a href="http://ehcache.org/">ehcache-1.1</a> <br>
236
<li><a href="http://jakarta.apache.org/commons/logging.html">commons-logging</a>,
237
from Apache's Jakarta project.</li>
239
<p>In addition For JDK1.2 and JDK
240
1.3, ehcache requires:</p>
242
<li>Apache Jakarta's <a
243
href="http://jakarta.apache.org/commons/collections.html">commons-collections</a>
244
(commons-collection.jar),
246
<li>Apache <a href="http://xml.apache.org/xerces2-j/">xerces</a>
247
(xml-apis.jar and xercesImpl.jar), version 2.5</li>
249
The dependencies are also required for ehcache and Hibernate, so if you
250
already have either of those, your dependency requirements are met.<br>
252
The filter constructs are designed to run in a Web Container which
253
meets the <a href="http://java.sun.com/products/servlet/download.html">Servlet
254
2.3 specification</a>.<br>
257
href="https://sourceforge.net/tracker/index.php?func=detail&aid=1025128&group_id=93232&atid=603559">reported</a>
258
that IBM Websphere 5.1 running on IBM JDK1.4 requires
259
commons-collection.jar even though it does not use it. <br>
261
<h1><a class="mozTocH1" name="mozTocId747622"></a>5 Installation<br>
266
the ehcache-constructs-X.X.jar into your classpath. </li>
267
<li>Ensure that any libraries required to satisfy <a
268
href="file:///wotif/work/ehcache/site/documentation/index.html#dependencies">dependencies</a>
269
are also in the classpath.</li>
270
<li>As an optional step, configure an appropriate <a
271
href="file:///wotif/work/ehcache/site/documentation/index.html#logging">logging</a>
274
<h1><a class="mozTocH1" name="mozTocId265501"></a>6 Logging</h1>
276
the Apache Commons Logging library. It acts as a thin bridge between
277
logging statements in the code and logging infrastructure detected in
278
the classpath. It will use in order of preference: log4j, JDK1.4
279
logging and then its own <code>SimpleLog</code> . This enables
280
ehcache to use logging infrastructures compatible with Java versions
281
from JDK1.2 to JDK5. It does create a dependency on Apache Commons
282
Logging, however many projects, including Hibernate, share the same
285
For normal production use, use the <code>WARN</code> level in log4J
286
and the <code>WARNING</code> level for JDK1.4 logging. <br>
287
<h1><a class="mozTocH1" name="mozTocId430833"></a>7 Obtaining the
289
The source code is distributed in the root directory of the download.
290
It is called ehcache-constructs-x.x-src.zip. It is also available from
292
online or through cvs.<br>
294
<h2><a class="mozTocH2" name="mozTocId688132"></a>Online<br>
296
The source code can be viewed online via <a
297
href="http://cvs.sourceforge.net/viewcvs.py/ehcache/ehcache-constructs/">viewcvs.</a><br>
298
<h2><a class="mozTocH2" name="mozTocId244950"></a>CVS</h2>
299
You can check out the sourcecode anonymously using cvs as follows:<br>
305
-d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ehcache login <br>
306
2. cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ehcache co
307
ehcache-constructs</td>
312
<h1><a class="mozTocH1" name="mozTocId722946"></a>8 Using The
315
In this section each construct is presented in a context of a pattern.<br>
317
For each one, there are tests which show further examples of
318
usage. See the online <a
319
href="http://cvs.sourceforge.net/viewcvs.py/ehcache/ehcache-constructs/test/java/net/sf/ehcache/constructs/blocking/">tests</a>.<span
320
style="font-weight: bold;"><br>
322
<h2><a name="mozTocId937608" class="mozTocH3"></a>BlockingCache</h2>
323
<h3><a name="mozTocId159833" class="mozTocH4"></a>Scenario</h3>
324
An expensive operation is required, say rendering a large web page,
325
which takes 30 seconds. The page is not considered stale until it is 5
326
minutes old. The page is hit very heavily and will be hit an
327
average of 20 times per minute each 5 minutes.<br>
328
<h3><a name="mozTocId22662" class="mozTocH4"></a>Solution</h3>
329
You could use Cache directly here and do a <a
330
href="http://ehcache.sourceforge.net/javadoc/net/sf/ehcache/Cache.html#put%28net.sf.ehcache.Element%29">Cache.put(Element
331
element)</a> to put it in after rendering and then a <a
332
href="http://ehcache.sourceforge.net/javadoc/net/sf/ehcache/Cache.html#get%28java.io.Serializable%29">Cache.get(Serializable
333
key)</a> to get the cached versions out. This will work quite well.
334
However once every five minutes the page will expire and it will need
335
to be re-rendered. In the 30 seconds required to do so, 9 more requests
336
will come in, each of which will be rendered. After that, the rendered
337
page will be put in the cache and the cache will be hit with requests.
338
So rather than doing only 1 render every 5 minutes 10 are required.<br>
340
If, instead you use a BlockingCache, when the page is being rendered
341
the other 9 requests that come in will be blocked. When the first
342
rendering request finishes, the other 9 requests will be returned the
343
cached page. This approach only requires 1 render each 5 minutes. <br>
344
<h3><a name="mozTocId659272" class="mozTocH4"></a>Implementation</h3>
345
Below is a code fragment showing the semantics for using a
346
BlockingCache to implement the solution,<br>
352
private BlockingCache blockingCache;<br>
354
private PageInfo processRequest(HttpServletRequest request,
355
HttpServletResponse response) throws Exception {<br>
356
final String key = calculateKey(request);<br>
357
PageInfo pageInfo = (PageInfo)
358
blockingCache.get(key);<br>
359
if (pageInfo == null) {<br>
360
try {<br>
361
362
//Page is not cached - build the response, cache it, and send to client<br>
363
pageInfo =
364
buildPage(request, response, chain);<br>
365
366
blockingCache.put(key, pageInfo);<br>
367
369
} catch (final Throwable throwable) {<br>
370
// Must unlock the
371
cache if the above fails<br>
372
373
blockingCache.put(key, null);<br>
374
throw new
375
Exception("Could not build cached page.", throwable);<br>
376
}<br>
383
<h2><a name="mozTocId640475" class="mozTocH3"></a>SelfPopulatingCache</h2>
384
<h3><a class="mozTocH4" name="mozTocId483719"></a>Scenario</h3>
385
A number of database queries need to be done to build a complicated
386
collection of value objects to perform a search and generate search
387
results. A search takes 30 seconds to perform. Search
388
results can be no staler than 2 minutes. An average of 100 searches
389
with the same queries are done per minute.<br>
390
<h3><a class="mozTocH4" name="mozTocId598598"></a>Solution</h3>
391
A Hibernate <a href="mozTocId182189">Query Cache</a> could be
392
used. The cache could be configured to expire after two minutes. Once
393
expired however, in the time taken for the Hibernate Query Cache to
394
repopulate, 50 searches will have occurred. Over the 2 minutes, out of
395
200 searches performed, 50 will be uncached.<br>
397
A <a href="mozTocId937608">BlockingCache</a> will remove the extra
398
searches, while the repopulate is being done. The uncached searches
399
will drop to 1 out of 200. However, all search threads will block while
400
the repopulate takes place. A user will usually see fast
401
responses but every two minutes 50 requests will take 30 seconds. <br>
402
<h3><a class="mozTocH4" name="mozTocId563482"></a>Implementation</h3>
405
<li>Extend SelfPopulatingCacheManager </li>
406
<li>Create a SelfPopulatingCache </li>
407
<li>Create a SelfPopulatingCacheEntryFactory </li>
408
<li>Use a thread to call refresh. Perhpas JMX or a timing service
409
such as Quartz. </li>
410
<li>Configure the cache in ehcache.xml. The cache might be external
411
because it is being refreshed. </li>
414
<hr><a href="http://sourceforge.net"><img
415
style="border: 0px solid ; width: 88px; height: 31px;"
416
alt="SourceForge.net" src="../images/sflogo.php.png"></a><br>