The Artima Developer Community
Sponsored Link

Python Buzz Forum
The Binds That Tie

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Ben Last

Posts: 247
Nickname: benlast
Registered: May, 2004

Ben Last is no longer using Python.
The Binds That Tie Posted: Jun 16, 2004 8:25 PM
Reply to this message Reply

This post originated from an RSS feed registered with Python Buzz by Ben Last.
Original Post: The Binds That Tie
Feed Title: The Law Of Unintended Consequences
Feed URL: http://benlast.livejournal.com/data/rss
Feed Description: The Law Of Unintended Consequences
Latest Python Buzz Posts
Latest Python Buzz Posts by Ben Last
Latest Posts From The Law Of Unintended Consequences

Advertisement
Since Googling finds nothing on this subject, I thought I'd save the results of a little investigation into Zope, caching and Page Templates (also known as ZPT or PageTemplates).

The Zope AcceleratedHTTPCacheManager is, in combination with Apache or Squid, an excellent thing.  It'll set headers on your HTML pages to allow them to be cached by clients, proxy servers or (and most usefully), an Apache installation running in reverse-proxy mode as a "front-end" to Zope.  Thus repeated requests for the same data are served by Apache and don't load your Zope instance; considering the difference in speed, that can be crucial.

But it's not clear (or at least, I haven't been able to find out) what aspects of a "call" to a page template allow it to be cached, and which cause the template to be re-rendered.  Reading the source for AcceleratedHTTPCacheManager helped, in that a comment at the end pointed me to http://www.web-caching.com/proxy-caches.html. ; You might also want to take a look at RFC2616 for the low-level dope on how caches work (you want section 13).  The big question we want to answer is; "what is the key that is used to look up data from the cache?"

The short answer, for HTTP caches, is that it's done on the URL[1].  Assuming you're a Python person, think of a cache like a big dict, with the URL as the key and the result of the page as the value.  Something to bear in mind here is that cookies are not part of the URL, so if the contents of your template are affected by the values of cookies, you may well not want to cache it using an external cache.  Similarly, many caches won't cache anything that contains an Authorization header (it's not part of the URL), so if you need to log into your site via the standard browser username/password dialogue, that might well mean your templates won't be cached.

Consider a typical GET request that contains a query, something like http://my.test.site/MyTemplate?parameter=value. ; The parameter and the value are both part of the URL, so they're part of the key.  However, if you use a POST request, then the parameters are not part of the URL.  This almost certainly means that your template will get invoked every time (which is the safest course of action).  Remember how Internet Explorer says something like "This page cannot be reloaded without resending the data"?  That's why.  You might also (depending on how long you've been online) remember how Netscape used to say "Repost Form Data?" in the same situation.  That always took my award for the most obscure error message ever; three words, each of which meant nothing to the average user.  Incidentally, for an interesting summary of the rationales that led to GET and POST and the recommendations for which should be used, see this document; in short, it recommends using POST for requests to do critical things like ordering products or charging money, where a re-request might be a Bad Thing.  You'll also learn the word "idempotence"; use it in conversation today!

As a fallback for misses on an AcceleratedHTTPCache, the RAMCacheManager is able to make much more use of the Zope environment in which the template's executed as the key.  A text file along with the source says "The values in it are indexed by a tuple of a view_name, interesting request variables, and extra keywords passed to Cache.ZCache_set()", which doesn't help us very much.

Time for some empirical observation.  A ZopePageTemplate object is cacheable because it inherits from OFS.Cache.Cacheable.  In the ZopePageTemplate.py file (in lib/python/Products/PageTemplates), in the _exec method, I added a line to dump out the keyset used; this is visible when you run Zope via the runzope script in the bin subdirectory of the Zope instance.  For reference, here's where it goes:
        # Retrieve the value from the cache.
        keyset = None
        if self.ZCacheable_isCachingEnabled():
            # Prepare a cache key.
            keyset = {'here': self._getContext(),
                      'bound_names': bound_names}
            #Add this line in to dump the keyset.
            print keyset
            result = self.ZCacheable_get(keywords=keyset)
            if result is not None:
                # Got a cached value.
                return result


The output you get is something like this, which came from invoking a Page Template on an instance of MyProduct with a URL like: http://www.mytest.site/Folder/Object/ScriptName/flash
{'bound_names': {'traverse_subpath': ['flash'], 'options': {'args': ()}, 'user': Anonymous User}, 'here': }


So, we can see that the cache key includes most of the stuff that will make a difference:

  • user; bear in mind that if you're building a public-access website (as opposed to some Intranet product) most of your users will be Anonymous User

  • here; the object on which the page template is invoked

  • traverse_subpath; the route that acquisition took before finding the script name (in effect)


These are (as far as I can tell) in addition to the URL itself, so variations in query parameters or the path by which the template is invoked cause the cache to see the requests as different.

[1] Yes, I know - this is a summary, ok?  Strictly speaking, it's done on the URIs, and with a bunch of caveats about case-sensitivity and the like; see RFC2616 3.2.3 for more...

Read: The Binds That Tie

Topic: On the responsibility of running a well-linked website. Previous Topic   Next Topic Topic: Swapping It All Back In

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use