summaryrefslogtreecommitdiff
path: root/docs/html/_sources/dev_guide/cache.rst.txt
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/_sources/dev_guide/cache.rst.txt')
-rw-r--r--docs/html/_sources/dev_guide/cache.rst.txt395
1 files changed, 395 insertions, 0 deletions
diff --git a/docs/html/_sources/dev_guide/cache.rst.txt b/docs/html/_sources/dev_guide/cache.rst.txt
new file mode 100644
index 0000000..18014c5
--- /dev/null
+++ b/docs/html/_sources/dev_guide/cache.rst.txt
@@ -0,0 +1,395 @@
+Caching placeholders and #cache
+===============================
+
+
+Dynamic placeholder - no cache
+------------------------------
+
+
+The template:
+
+::
+
+ Dynamic variable: $voom
+
+The command line and the output:
+
+::
+
+ % voom='Voom!' python x.py --env
+ Dynamic variable: Voom!
+
+The generated code:
+
+::
+
+ write('Dynamic variable: ')
+ write(filter(VFS(SL,"voom",1))) # generated from '$voom' at line 1, col 20.
+ write('\n')
+
+Just what we expected, like any other dynamic placeholder.
+
+Static placeholder
+------------------
+
+
+The template:
+
+::
+
+ Cached variable: $*voom
+
+The command line and output:
+
+::
+
+ % voom='Voom!' python x.py --env
+ Cached variable: Voom!
+
+The generated code, with line numbers:
+
+::
+
+ 1 write('Cached variable: ')
+ 2 ## START CACHE REGION: at line, col (1, 19) in the source.
+ 3 RECACHE = True
+ 4 if '19760169' not in self._cacheData:
+ 5 pass
+ 6 else:
+ 7 RECACHE = False
+ 8 if RECACHE:
+ 9 orig_trans = trans
+ 10 trans = cacheCollector = DummyTransaction()
+ 11 write = cacheCollector.response().write
+ 12 write(filter(VFS(SL,"voom",1))) # generated from '$*voom' at line 1,
+ # col 19.
+ 13 trans = orig_trans
+ 14 write = trans.response().write
+ 15 self._cacheData['19760169'] = cacheCollector.response().getvalue()
+ 16 del cacheCollector
+ 17 write(self._cacheData['19760169'])
+ 18 ## END CACHE REGION
+
+ 19 write('\n')
+
+That one little star generated a whole lotta code. First, instead
+of an ordinary {VFS} lookup (searchList) lookup, it converted the
+placeholder to a lookup in the {.\_cacheData} dictionary. Cheetah
+also generated a unique key ({'19760169'}) for our cached item -
+this is its cache ID.
+
+Second, Cheetah put a pair of if-blocks before the {write}. The
+first (lines 3-7) determine whether the cache value is missing or
+out of date, and sets local variable {RECACHE} true or false. This
+stanza may look unnecessarily verbose - lines 3-7 could be
+eliminated if line 8 was changed to
+
+::
+
+ if '19760169' not in self._cacheData:
+
+- but this model is expandable for some of the cache features we'll
+see below.
+
+The second if-block, lines 8-16, do the cache updating if
+necessary. Clearly, the programmer is trying to stick as close to
+normal (dynamic) workflow as possible. Remember that {write}, even
+though it looks like a local function, is actually a method of a
+file-like object. So we create a temporary file-like object to
+divert the {write} object into, then read the result and stuff it
+into the cache.
+
+Timed-refresh placeholder
+-------------------------
+
+
+The template:
+
+::
+
+ Timed cache: $*.5m*voom
+
+The command line and the output:
+
+::
+
+ % voom='Voom!' python x.py --env
+ Timed cache: Voom!
+
+The generated method's docstring:
+
+::
+
+ """
+ This is the main method generated by Cheetah
+ This cache will be refreshed every 30.0 seconds.
+ """
+
+The generated code:
+
+::
+
+ 1 write('Timed cache: ')
+ 2 ## START CACHE REGION: at line, col (1, 15) in the source.
+ 3 RECACHE = True
+ 4 if '55048032' not in self._cacheData:
+ 5 self.__cache55048032__refreshTime = currentTime() + 30.0
+ 6 elif currentTime() > self.__cache55048032__refreshTime:
+ 7 self.__cache55048032__refreshTime = currentTime() + 30.0
+ 8 else:
+ 9 RECACHE = False
+ 10 if RECACHE:
+ 11 orig_trans = trans
+ 12 trans = cacheCollector = DummyTransaction()
+ 13 write = cacheCollector.response().write
+ 14 write(filter(VFS(SL,"voom",1))) # generated from '$*.5m*voom' at
+ # line 1, col 15.
+ 15 trans = orig_trans
+ 16 write = trans.response().write
+ 17 self._cacheData['55048032'] = cacheCollector.response().getvalue()
+ 18 del cacheCollector
+ 19 write(self._cacheData['55048032'])
+ 20 ## END CACHE REGION
+
+ 21 write('\n')
+
+This code is identical to the static cache example except for the
+docstring and the first if-block. (OK, so the cache ID is different
+and the comment on line 14 is different too. Big deal.)
+
+Each timed-refresh cache item has a corrsponding private attribute
+{.\_\_cache########\_\_refreshTime} giving the refresh time in
+ticks (=seconds since January 1, 1970). The first if-block (lines
+3-9) checks whether the cache value is missing or its update time
+has passed, and if so, sets {RECACHE} to true and also schedules
+another refresh at the next interval.
+
+The method docstring reminds the user how often the cache will be
+refreshed. This information is unfortunately not as robust as it
+could be. Each timed-cache placeholder blindly generates a line in
+the docstring. If all refreshes are at the same interval, there
+will be multiple identical lines in the docstring. If the refreshes
+are at different intervals, you get a situation like this:
+
+::
+
+ """
+ This is the main method generated by Cheetah
+ This cache will be refreshed every 30.0 seconds.
+ This cache will be refreshed every 60.0 seconds.
+ This cache will be refreshed every 120.0 seconds.
+ """
+
+The docstring tells only that "something" will be refreshed every
+60.0 seconds, but doesn't reveal { which} placeholder that is. Only
+if you know the relative order of the placeholders in the template
+can you figure that out.
+
+Timed-refresh placeholder with braces
+-------------------------------------
+
+
+This example is the same but with the long placeholder syntax. It's
+here because it's a Cheetah FAQ whether to put the cache interval
+inside or outside the braces. (It's also here so I can look it up
+because I frequently forget.) The answer is: outside. The braces go
+around only the placeholder name (and perhaps some output-filter
+arguments.)
+
+The template:
+
+::
+
+ Timed with {}: $*.5m*{voom}
+
+The output:
+
+::
+
+ Timed with {}: Voom!
+
+The generated code differs only in the comment. Inside the
+cache-refresh if-block:
+
+::
+
+ write(filter(VFS(SL,"voom",1))) # generated from '$*.5m*{voom}' at line 1,
+ #col 17.
+
+If you try to do it this way:
+
+::
+
+ Timed with {}: ${*.5m*voom} ## Wrong!
+
+you get:
+
+::
+
+ Timed with {}: ${*.5m*voom}
+
+``${`` is not a valid placeholder, so it gets treated as ordinary
+text.
+
+#cache
+------
+
+
+The template:
+
+::
+
+ #cache
+ This is a cached region. $voom
+ #end cache
+
+The output:
+
+::
+
+ This is a cached region. Voom!
+
+The generated code:
+
+::
+
+ 1 ## START CACHE REGION: at line, col (1, 1) in the source.
+ 2 RECACHE = True
+ 3 if '23711421' not in self._cacheData:
+ 4 pass
+ 5 else:
+ 6 RECACHE = False
+ 7 if RECACHE:
+ 8 orig_trans = trans
+ 9 trans = cacheCollector = DummyTransaction()
+ 10 write = cacheCollector.response().write
+ 11 write('This is a cached region. ')
+ 12 write(filter(VFS(SL,"voom",1))) # generated from '$voom' at line 2,
+ # col 27.
+ 13 write('\n')
+ 14 trans = orig_trans
+ 15 write = trans.response().write
+ 16 self._cacheData['23711421'] = cacheCollector.response().getvalue()
+ 17 del cacheCollector
+ 18 write(self._cacheData['23711421'])
+ 19 ## END CACHE REGION
+
+This is the same as the {$\*voom} example, except that the plain
+text around the placeholder is inside the second if-block.
+
+#cache with timer and id
+------------------------
+
+
+The template:
+
+::
+
+ #cache timer='.5m', id='cache1'
+ This is a cached region. $voom
+ #end cache
+
+The output:
+
+::
+
+ This is a cached region. Voom!
+
+The generated code is the same as the previous example except the
+first if-block:
+
+::
+
+ RECACHE = True
+ if '13925129' not in self._cacheData:
+ self._cacheIndex['cache1'] = '13925129'
+ self.__cache13925129__refreshTime = currentTime() + 30.0
+ elif currentTime() > self.__cache13925129__refreshTime:
+ self.__cache13925129__refreshTime = currentTime() + 30.0
+ else:
+ RECACHE = False
+
+#cache with test: expression and method conditions
+--------------------------------------------------
+
+
+The template:
+
+::
+
+ #cache test=$isDBUpdated
+ This is a cached region. $voom
+ #end cache
+
+
+The template:
+
+::
+
+ #cache id='cache1', test=($isDBUpdated or $someOtherCondition)
+ This is a cached region. $voom
+ #end cache
+
+The output:
+
+::
+
+ This is a cached region. Voom!
+
+The first if-block in the generated code:
+
+::
+
+ RECACHE = True
+ if '36798144' not in self._cacheData:
+ self._cacheIndex['cache1'] = '36798144'
+ elif (VFS(SL,"isDBUpdated",1) or VFS(SL,"someOtherCondition",1)):
+ RECACHE = True
+ else:
+ RECACHE = False
+
+The second if-block is the same as in the previous example. If you
+leave out the {()} around the test expression, the result is the
+same, although it may be harder for the template maintainer to
+read.
+
+You can even combine arguments, although this is of questionable
+value.
+
+The template:
+
+::
+
+ #cache id='cache1', timer='30m', test=$isDBUpdated or $someOtherCondition
+ This is a cached region. $voom
+ #end cache
+
+The output:
+
+::
+
+ This is a cached region. Voom!
+
+The first if-block:
+
+::
+
+ RECACHE = True
+ if '88939345' not in self._cacheData:
+ self._cacheIndex['cache1'] = '88939345'
+ self.__cache88939345__refreshTime = currentTime() + 1800.0
+ elif currentTime() > self.__cache88939345__refreshTime:
+ self.__cache88939345__refreshTime = currentTime() + 1800.0
+ elif VFS(SL,"isDBUpdated",1) or VFS(SL,"someOtherCondition",1):
+ RECACHE = True
+ else:
+ RECACHE = False
+
+We are planning to add a {'varyBy'} keyword argument in the future
+that will allow separate cache instances to be created for a
+variety of conditions, such as different query string parameters or
+browser types. This is inspired by ASP.net's varyByParam and
+varyByBrowser output caching keywords. Since this is not
+implemented yet, I cannot provide examples here.
+
+