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

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to