Matt, After the discussion last week, I've implemented patches against AxKit to support caching of each stage of the processing. In the process of implementing this, I had to make some pretty significant changes to the way AxKit.pm handles requests. An upshot of this is that there is now also support for TTL's of responses.
I'll describe the changes and patches are below.
- Updated Apache::AxKit::Provider::Scalar to take an xml_string,
xml_strref or dom_tree as a constructor argument. (I guess it
could be renamed from Scalar to something else now).
- After each handler is run the result is collected and put into an
Apache::AxKit::Provider::Scalar object, which is used as the
provider object given to the next stage of processing.
- In addition to the previous point, the API for handler (language)
objects has been changed so that the handler can return a hashref
in addition to the result code. The hashref contains values for
the result. Eg.
...
return (Apache::Constants::OK,
{ dom_tree => $result, content_type => $type, ttl => 60 });
However, I've ensured that it is still backwards compatible with
the old way of passing back results via pnotes or printing to the
AxKit::Apache object (see notes on AxKit::Apache object below).
There is also a new argument passed to the handler, a cachekey (an
hex string based on the initial request and the styles to be
applied). It can be used to uniquely identify the pipeline if
required for caching within the handler. If the cachekey is
undef, then caching is not possible for the remainder of the
pipeline and the handler should not perform internal result
caching. This would be useful for the XSP handler so that it can
determine whether to cache the compiled form of the XSP page.
- The Apache::AxKit::Provider API has been extended to include a
'ttl' and 'deliver' method. The former returns the ttl for the
resource (or undef for unlimited, which is the default). The
latter is used to send the data to the client. The deliver method
is provided with the Apache object to deliver to as well as any
transformers that need to be run. It is essentially what was the
main part of the deliver_to_browser routine. The default deliver
implementation should work for any derived Provider object that
implements get_strref().
- The Apache::AxKit::Cache object has been entirely redone.
Unfortunately the changes aren't backwards compatible, but I can't
find any implementations of derived Caching systems so I don't
think it's a problem. Trying to maintain backwards compatibility
was too difficult. Now the Cache class is now actually derived
from the Provider class - and implements all the required methods.
This allows a Cache object to be used as a Provider input to any
stage of processing. It also includes it's own implementation of
'deliver' that is tuned for delivering from the cache file.
- The cache now also stores the content_type, ttl and dependancies
in a metadata file alongside the cached data. A gzip'ed version
of the data is also stored alongside (and is created only when
required). The cache honor also honors the ttl of an object.
- The caching is implemented by creating a Cache object before each
processing stage is attempted. If the cache is valid, then the
cache object replaces the current provider and the processing
moves on to the next stage.
- The process_request routine now returns a result_provider instead
of leaving the result in pnotes. It also returns the content_type
and ttl of the result. These values are then passed onto the
deliver_to_browser routine. This saves having to pass everything
around in pnotes and makes it much clearer where the information
goes. It also allows the a Cache object to be returned.
- Each handler has the option of returning a ttl (via the updated
API). The ttl is stored with the cache of the result, and the
smallest ttl is used for the 'Expires' or 'Cache-Control' header
that is sent to the client. When a stage returns a ttl of 0
(indicating an uncacheable response), further attempts to cache
results is disabled and the no-cache headers are sent.
- I have changed the way the AxKit::Apache object is used. As the
results are no longer passed around via pnotes internally, there
is no need try and rebless the Apache object all over the place.
Instead it is only reblessed just prior to calling a handler (and
restored after) so as to maintain backwards compatibility for old
handlers. I have also changed the implementation of the wrapper
to never directly modify the underlying Apache object (eg when
content_type is called), but instead store the changes into pnotes
where they are then pulled out again after the handler completes.
So really, the AxKit::Apache object is only now required for
backwards compatibility.
- A couple of smaller changes: I've removed
Apache::AxKit::Exception::OK since it doesn't fit into the new
model very well, and wasn't being used anywhere anyway. I've also
ensured that providers returning undef from the mtime method are
considered 'fresh'. This is simpler than having them return the
current time.
I think this summarizes it. If there are more specific questions,
then let me know.
On with the patches. These are all against the current CVS tree as
of the time of this email. The main patch file is available here:
http://www.leishman.org/axkit_patches/axkit-incr-cache.patch
I've tested this pretty well I think - everything seems to work
without issue.
I've also updated the implementation of
Apache::AxKit::Language::LibXSLT to use the updated handler API.
I've also tested this works well - but note that it is not required
since the API is backwards compatible. The patch for this is
available here:
http://www.leishman.org/axkit_patches/axkit-libxslt-newapi.patch
In addition, I've implemented patches to many of the supplied
Language classes to use the new API. However, NONE OF THESE HAVE
BEEN TESTED - I provide them only as examples. Remember that these
are not required since the API is backwards compatible.
<NOT TESTED>
http://www.leishman.org/axkit_patches/axkit-axpoint-newapi.patch
http://www.leishman.org/axkit_patches/axkit-htmldoc-newapi.patch
http://www.leishman.org/axkit_patches/axkit-passivetex-newapi.patch
http://www.leishman.org/axkit_patches/axkit-petal-newapi.patch
http://www.leishman.org/axkit_patches/axkit-sablot-newapi.patch
http://www.leishman.org/axkit_patches/axkit-saxmachines-newapi.patch
http://www.leishman.org/axkit_patches/axkit-xsp-newapi.patch
</NOT TESTED>
Obviously they could be updated further to take advantage of some of
the new options, like the ability to return a ttl.
Please get back to me with your comments - it would be nice if you
can use this code!
Regards,
Chris
MD5Sums:
dc68103154dc51928bb833598d98e860 axkit-incr-cache.patch
1b869e7757a7ab425e273a0041aa2029 axkit-libxslt-newapi.patch
cf5c06c0e6d0df4ea94fb732a360189c axkit-axpoint-newapi.patch
f891f07840aa217f368176c005e72a3d axkit-htmldoc-newapi.patch
15352a3257e5c9f7274e885552e2dbc2 axkit-passivetex-newapi.patch
4ac0d4f30cfa48d8d31ca2dc7048f405 axkit-petal-newapi.patch
61700180de51f711dd7a0329c3a068ee axkit-sablot-newapi.patch
9e6eea32b674fe3d7d4d52f6403e39f6 axkit-saxmachines-newapi.patch
5b3ae5aa45acba9976f7cb9c3a547d6f axkit-xsp-newapi.patch
pgp00000.pgp
Description: PGP signature
