|
jacquard 1.12.0 by The Web Engineering Factory and Toolworks | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectjavax.servlet.GenericServlet
javax.servlet.http.HttpServlet
uk.co.weft.maybeupload.MaybeUploadServlet
uk.co.weft.htform.Servlet
uk.co.weft.htform.WithExceptionHandlerServlet
uk.co.weft.domutil.DocPage
uk.co.weft.domutil.TransformPage
uk.co.weft.domutil.CachedPage
a CachedPage is a servlet which generates a page which doesn't often change. A lot of our pages are generated off databases where change to the underlying database is infrequent, and where exact up-to-the-minute up to dateness is not critical. The idea of this class is to reduce the load on the server by cacheing pages as they are generated and then delivering from the cache; the cache is only refreshed if the age of the document in the cache exceeds the document's time-to-live.
This class is not perfect.
db_password to it using the GET method
would reveal that password in the URL, which is pretty insecure.
Nevertheless, this class has very broad applicability for generating near-real-time public content on data-driven Websites. If the content will on average be requested more than once in the cache time-to-live assigned, this class will show performance benefits over DocPage, q.v. The more hits within the cache TTL, the greater the performance gain.
In addition to all the configuration paramaters which DocPage knows about, CachedPage also handles:
javax.servlet.context.tempdir within the ServletContext.
Note that if the path starts with the separator character it will be
looked for in the file system root; if it doesn't, in the servlet context.
Because CachedPage's configuration is a superset of DocPage's, the two are plug-compatible, and you can switch between them in configuration without having to recompile anything.
A note on locking: because Servlets don't have access to the thread that drives them, you can't sleep() while servicing a request. But two invocations of the same Servlet may be running simultaneously. Write locks are implemented, so that while one invocation is writing to a cache file, no other will either write or read it. Unfortunately, because they can't sleep for the few moments required, they will throw an UnavailableException. Ideally there would be a reciprocal lock set by a reading process so that no invocation will start to write while another is reading, but that has not yet been implemented.
TODO: Add something to periodically clean the cache; add something to fail gracefully if insufficient disk space. Fixup so that necessary subdirectories within the cache are created automatically - at present they aren't.
DocPage,
Serialized Form| Field Summary | |
protected int |
bufferBlockSize
how large a buffer I use for schlurping files out to the net |
protected java.lang.String |
cachePath
where my cache is in the file system; default to /tmp |
protected static int |
hits
number of requests satisfied from the cache |
protected java.util.Hashtable |
locks
Holds write locks on the cache when writing to it so as to prevent a pull happening when a write is in progress |
protected static int |
misses
number of hits satisfied by regenerating |
static java.lang.String |
REFRESHMAGICTOKEN
A token which, if it has the value 'true' in the service context, will cause the cache to be refreshed immediately. |
protected int |
ttl
how long things live in my cache; default is twenty minutes |
static java.lang.String |
UPDATINGPAGECONFIGTOKEN
A token on which I shall look in my config for the URL of a page template to serve if a request is received when my cache is updating |
protected java.net.URL |
updatingPageURL
the url of our when-updating page |
static java.lang.String |
WHENLOCKEDERROR
The error message to send when the cache is locked and there is no updating template available. |
| Fields inherited from class uk.co.weft.domutil.TransformPage |
transforms |
| Fields inherited from class uk.co.weft.domutil.DocPage |
ACCEPTHEADER, ACCEPTSXMLMAGICTOKEN, AXMLMIMETYPE, caxton, chosenGeneratorMagicToken, CHOSENGENERATORMAGICTOKEN, entitiesFileName, generators, processClientSide, PROCESSCLIENTSIDECONFIGTOKEN, transformerFactory, TXMLMIMETYPE, xslDocument, xslStylesheetName, XSLTRANSFORMCONFIGTOKEN |
| Fields inherited from class uk.co.weft.htform.WithExceptionHandlerServlet |
EXCEPTIONHANDLERCLASSCONFIGTOKEN |
| Fields inherited from class uk.co.weft.maybeupload.MaybeUploadServlet |
allowOverwrite, maxUpload, saveUploadedFilesToDisk, silentlyRename, uploadDir, uploadDirPath, uploadDirURL |
| Fields inherited from interface uk.co.weft.htform.ResourceConsumer |
RESOURCEBUNDLEMAGICTOKEN |
| Constructor Summary | |
CachedPage()
|
|
| Method Summary | |
protected boolean |
checkLock(java.lang.String key,
Context context)
Check to see if this cache is currently locked for updating. |
protected void |
doPost(javax.servlet.http.HttpServletRequest req,
javax.servlet.http.HttpServletResponse res)
Specialisation: we can't effectively cache post requests, so we must handle doPost differently from doGet. |
protected void |
generateContent(Context context)
produce my content, pulling it from cache if available and not aged out |
protected java.lang.String |
getCacheName(Context context)
compute, as a string, the cache name associated with this request and return it. |
void |
init(Context config)
Initialisation: Set up my variables from my configuration. |
protected void |
useCache(java.io.File file,
Context context)
take the document from this file and print it to the output stream |
| Methods inherited from class uk.co.weft.domutil.TransformPage |
getXSLDocument |
| Methods inherited from class uk.co.weft.domutil.DocPage |
clientAcceptsXML, destroy, generateContent, generateDocument, getContentType, printDocument, tryGenerators |
| Methods inherited from class uk.co.weft.htform.WithExceptionHandlerServlet |
whinge, whinge, whinge |
| Methods inherited from class uk.co.weft.htform.Servlet |
addCookie, addCookie, coerceCookiesToContext, coerceToContext, coerceToContext, coerceToContext, coerceToContext, coerceToUrl, createContext, doGet, doPost, fixupMagicValues, getCalendar, getDebug, getLocale, getOutputStream, getResource, getResourceString, getServletInfo, grs, grs, handleAction, handleCookies, handleRedirect, init, makeReady, outputRedirectBlock, setCookieValues, storeOnSession |
| Methods inherited from class uk.co.weft.maybeupload.MaybeUploadServlet |
doDelete, doHead, doOptions, doPut, doTrace, getUploadDir, getUploadURL, service |
| Methods inherited from class javax.servlet.http.HttpServlet |
doDelete, doGet, doHead, doOptions, doPut, doTrace, getLastModified, service |
| Methods inherited from class javax.servlet.GenericServlet |
getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletName, init, log, log |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
public static final java.lang.String REFRESHMAGICTOKEN
public static final java.lang.String UPDATINGPAGECONFIGTOKEN
public static final java.lang.String WHENLOCKEDERROR
protected static int hits
protected static int misses
protected java.util.Hashtable locks
protected java.lang.String cachePath
protected java.net.URL updatingPageURL
protected int bufferBlockSize
protected int ttl
| Constructor Detail |
public CachedPage()
| Method Detail |
public void init(Context config)
throws InitialisationException
init in class TransformPageInitialisationExceptionprotected java.lang.String getCacheName(Context context)
GET foo?a=1&b=2
is treated as being different from GET foo?b=2&a=1. It
would be a good thing to normalise this, but this method is
exceedingly time critical. Note also that where the servlet path of a
request contain one or more file separator characters (i.e. '/' on
UNX) these will be replaced by the non-separator-character, by default
'_'. Consequently if the cache is fed the paths
'servlet/foo' and 'servlet_foo', those two
names will collide. Again, it would be better if they didn't but this
code is time critical.
context - The context of this request
protected boolean checkLock(java.lang.String key,
Context context)
key - the cache file name to checkcontext - the context for this request
getCacheName(Context)
protected void doPost(javax.servlet.http.HttpServletRequest req,
javax.servlet.http.HttpServletResponse res)
throws javax.servlet.ServletException,
java.io.IOException
req - , the requestres - , the response object
javax.servlet.ServletException
java.io.IOException
protected void generateContent(Context context)
throws GenerationException,
java.io.IOException,
javax.servlet.ServletException
generateContent in class DocPagecontext - the context of this request
throws - GenerationException on failure to generate
throws - UnavailableException if locked for updating
java.io.IOException - if anything goes wrong while printing.
GenerationException - if anything goes wrong while generating
javax.servlet.ServletException - if cannot generate for other reasons
protected void useCache(java.io.File file,
Context context)
throws GenerationException
file - the cache file to printcontext - the context of this request
throws - GenerationException if for any reason the file can't
be copied out
GenerationException
|
jacquard 1.12.0 by The Web Engineering Factory and Toolworks | |||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||