I'm just starting out with AxKit, and I'm trying to use the cache system
to cache raw XML from database queries done by a custom provider which can
be quite lengthy (I touch a file in the filesystem when I update the
database and use this file's mtime to invalidate the cache).  I've had to
use a "dumb hack" to get around the fact that stylesheets are apparently
cached on a per-process, rather than global basis (or so it seems --
AxKit::Provider::AxKit's get_styles_xs function likes to call my
provider's get_strref method the first time it's run from a process), and
my queries never use stylesheet PIs nor do they depend on AddRootProcessor
processing. This is simple enough:

package MyProvider;
...
sub get_strref {
    my $p = shift;
    if (caller() eq 'Apache::AxKit::Provider') {
        # never run query to determine styles
        return \"<?xml version=\"1.0\">\n<null />";
    }
    else {
        unless (defined $p->{qp_strref}) {
            $p->{qp_strref} = \($p->get_dom->toString);
        }
    }
    return $p->{qp_strref};
}
...

Note that I cache the (DOM [not shown here] and the) strref in the
provider object so AxKit can ask for it as many times as it wants in one
request without requerying (I can't use caller() to prevent this, nor do I
need to, because at this point we already know the data isn't cached).
Finally, I pass the data through an "identity" stylesheet to get it in the
cache (is there any other way, short of writing a "null" language
processor?).  Ugly, but it works. Anyway, I suspect there's a better way,
but this works well enough and I'm moving on.  Suggestions,
however, are welcome.

Next problem is a bit harier -- the principal consumer of the cached query
data is a document() function in an XSLT stylesheet (I'm generating a
report whose structure is defined in an XML template file which needs to
pull data from the database -- I'm taking advantage of AxKit's
AddRootProcessor to choose the stylesheet based on the template XML file's
root element). If I use a relative path in the document function, the
get_strref function is called directly from Apache::AxKit::LibXMLSupport,
bypassing the cache. If I use an axkit: URI, data is _read_ from the cache
if available, but the cache is never _written_ from a request through an
axkit: URI. Looks like cache writing is done in AxKit::deliver_to_browser,
which is never called from get_axkit_uri which delivers its content
directly.

The obvious solution is to "cut and paste" the cache-writing code from
deliver_to_browser into get_axkit_uri. Obviously I might also reorganize
the dataflow so cache writing is done in a routine called through both
paths (normal and axkit:), but as an AxKit novice with a poor
understanding of the structure of the system, this seems more likely to
cause problems.

I'm going to give this a try, but I was just wondering if there might be a
better solution, or if doing what I propose might cause other problems
down the road (if there isn't and it won't, this seems like generally
desireable behavior, and I'd be happy to submit my patches to the
community).

Finally, to answer the obvious question: yes, the data really does need to
be cached upstream of the stylesheet, because the same data will be reused
by many stylesheets (or, more precisely, by the same stylesheet with
different query strings). Caching of already-displayed pages works fine,
but it's not acceptable for the queries to run every time the page is
displayed with a different query string.

-jtm

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to