How does CherryPy caching work?

2019-06-03 10:23发布

问题:

I recently discovered that page object attributes in CherryPy are persistent between requests (and between clients). So I'm wondering, would it make sense to store page output in such an attribute? Like this:

class Page:
    def default(self, pagenumber):
        if pagenumber not in self.validpages:
            return 'Page number not found'
        try:
            html = self.pageoutput[pagenumber]
        except KeyError:
            html = self.formatter(self.dbcall(pagenumber))
        return html
    default.exposed = True

    def formatter(self, data):
        html = # Formatting code here
        return html

    def dbcall(self, pagenumber):
        data = # Database lookup code here
        return data

I know CherryPy caches GET requests by default. In my tests, when an object attribute was part of the output and that attribute changed, CherryPy served the attribute's new value. Does that mean the output was only partially cached?

To me this would be useful as long as you updated self.pageoutput every time you changed your database. The only difficulty I could imagine is if I wanted to display user-specific information. What do you think?

回答1:

CherryPy does not cache GET requests by default; you have to explicitly turn on the caching tool as described in that documentation.

To answer your first question, yes, it's perfectly valid to store things like "pageoutput" that do not change between calls. However, there are a couple of caveats:

  1. HTTP caching is far better than what you can write on your own. So prefer that for whole responses.
  2. Therefore, use ad-hoc caching for parts of responses, such as templates and banners and such.
  3. Be very careful to design your storage to be safely concurrent. See effbot's writeup on that subject for a start. In general, try to generate and store such values at application startup if feasible, instead of during a request; if you write such data in the main thread only at startup, it should be safely readable by multiple threads for each request. If you need such data to change as the application state progresses, you probably want to use a database or some other mechanism that has had hundreds of man-years of work to make it safely concurrent.