The CachingEventPipelineuses a very easy but effective approach
to cache the event pipelines of a request: The pipeline process
is cached up to the most possible point.
Each sitemap component (generator or transformer) which might be
cacheable must implement the Cacheable interface. When the
event pipeline is processed each sitemap component starting with
the generator is asked if it implements this interface. This
test stops either when the first component does not implement
the Cacheable interface or when the first cacheable component is
currently not cacheable for any reasons (more about this in a moment).
The Cacheable interface declares a method generateKey()
which must produce a unique key for this sitemap component inside
the component space. For example the FileGenerator generates a hash
of the source argument (the xml document read). All parameters/values
which are used for the processing of the request by the generator must
be used for this key. If, e.g. the request parameters are used by
the component, it must build a key with respect to the current request
parameters.
If for any reason the sitemap component detects that the current request
is not cacheable it can simply return 0
as the key. This has
the same effect as not declaring the Cacheable interface.
Now after the key is build for this particular request, it is looked up
in the cache if it exists. If not, the new request is generated and cached
for further requests.
If a cached response is found for the key, the caching algorithm checks
if this response is still valid. For this check each cacheable component
returns a validity object when the method generateValidity
is invoked. (If a cacheable component returns null
it
is temporarily not cacheable, like returning 0
for the key.)
A CacheValidity
object contains all information the component
needs to verify if the cached content is still valid. For example the
file generator stores the last modification date of the xml document parsed
in the validity object.
When a response is cached all validity objects are stored together with
the cached response in the cache. Actually the CachedEventObject
is stored which encapsulates all this information.
When a new response is generated and the key is build, the caching
algorithm also collects all uptodate cache validity objects. So if the
cached response is found in the cache these validity objects are compared.
If they are valid (or equal) the cached response is used and feed into
the pipeline. If they are not valid any more the cached response is removed
from the cache, the new response is generated and then stored together with
the new validity objects in the cache.
If you have the following pipeline:
Generator[type=file|src=a.xml] -> Transformer[type="xslt"|src=a.xsl] -> Serializer
The file generator is cacheable and generates a key which hashes the src
(or the filename) to build the key. The cache
validity object uses the last modification date of the xml file.
The xslt transformer is cacheable and generates a key which hashes
the filename to build the unique key. The cache validity object
uses the last modification date of the xml file.
Both keys are used to build a unique key for this pipeline,
the first time it is invoked its response is cached. The second time
this pipeline is called, the cached content is get from the cache.
If it is still valid, the cached content is directly feed into
the serializer.
Only part of the following pipeline is cached:
Generator[type=file|src=a.xml] -> Transformer[type="xslt"|src=a.xsl] -> Transformer[type=sql] -> Transformer[type="xslt"|src=b.xsl] -> Serializer
The file generator is cacheable and generates a key which hashes the src
(or the filename) to build the key. The cache
validity object uses the last modification date of the xml file.
The xslt transformer is cacheable and generates a key which hashes
the filename to build the unique key. The cache validity object
uses the last modification date of the xml file.
The sql transformer is not cacheable, so the caching algorithm stops
at this point although the last transformer is cacheable.
So the cached response is absolutely the same as in the first example
and therefore the unique key build from the two keys (from the
generator and the first transformer) is the same as in the first example.
The only difference is when the cached response is used. It is not
feed into the serializer but into the sql transformer.
|