1.1 --- a/patches/pageparams-caching-1.8.diff Sat Mar 29 16:29:52 2014 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,215 +0,0 @@
1.4 -# HG changeset patch
1.5 -# User Paul Boddie <paul@boddie.org.uk>
1.6 -# Date 1390585706 -3600
1.7 -# Node ID 70250fe93a4f946e51eaa63accbb0152054ddab2
1.8 -# Parent d57b620213dd68126d2e5800f173d89f0602403a
1.9 -Added caching support for the "pageparams" dependency where the request
1.10 -parameters are combined with the page name to make a cache entry.
1.11 -
1.12 -diff -r d57b620213dd -r 70250fe93a4f MoinMoin/Page.py
1.13 ---- a/MoinMoin/Page.py Tue Jul 30 17:41:42 2013 +0200
1.14 -+++ b/MoinMoin/Page.py Fri Jan 24 18:48:26 2014 +0100
1.15 -@@ -41,6 +41,7 @@
1.16 -
1.17 - from MoinMoin import config, caching, user, util, wikiutil
1.18 - from MoinMoin.logfile import eventlog
1.19 -+from MoinMoin.support.python_compatibility import hash_new
1.20 -
1.21 - def is_cache_exception(e):
1.22 - args = e.args
1.23 -@@ -1336,7 +1337,7 @@
1.24 -
1.25 - def loadCache(self, request):
1.26 - """ Return page content cache or raises 'CacheNeedsUpdate' """
1.27 -- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
1.28 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.29 - attachmentsPath = self.getPagePath('attachments', check_create=0)
1.30 - if cache.needsUpdate(self._text_filename(), attachmentsPath):
1.31 - raise Exception('CacheNeedsUpdate')
1.32 -@@ -1357,7 +1358,7 @@
1.33 - """ Format content into code, update cache and return code """
1.34 - import marshal
1.35 - from MoinMoin.formatter.text_python import Formatter
1.36 -- formatter = Formatter(request, ["page"], self.formatter)
1.37 -+ formatter = Formatter(request, ["page", "pageparams"], self.formatter)
1.38 -
1.39 - # Save request state while formatting page
1.40 - saved_current_lang = request.current_lang
1.41 -@@ -1369,10 +1370,39 @@
1.42 - src = formatter.assemble_code(text)
1.43 - code = compile(src.encode(config.charset),
1.44 - self.page_name.encode(config.charset), 'exec')
1.45 -- cache = caching.CacheEntry(request, self, self.getFormatterName(), scope='item')
1.46 -+ self.enforceCacheLimit(request)
1.47 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.48 - cache.update(marshal.dumps(code))
1.49 - return code
1.50 -
1.51 -+ def enforceCacheLimit(self, request):
1.52 -+ """ Prevent too many cache entries being stored for a page """
1.53 -+ keys = caching.get_cache_list(request, self, 'item')
1.54 -+ try:
1.55 -+ cache_limit = int(getattr(request.cfg, 'page_cache_limit', "10"))
1.56 -+ except ValueError:
1.57 -+ cache_limit = 10
1.58 -+
1.59 -+ if len(keys) >= cache_limit:
1.60 -+ items = [caching.CacheEntry(request, self, key, scope='item') for key in keys]
1.61 -+ item_ages = [(item.mtime(), item) for item in items]
1.62 -+ item_ages.sort()
1.63 -+ for item_age, item in item_ages[:-cache_limit]:
1.64 -+ item.remove()
1.65 -+
1.66 -+ def getCacheKey(self, request):
1.67 -+ """ Generate a cache key for a page using optional request information """
1.68 -+ key = self.getFormatterName()
1.69 -+ if request.args:
1.70 -+ args = request.args.items()
1.71 -+ args.sort()
1.72 -+ key_args = []
1.73 -+ for k, v in args:
1.74 -+ key_args.append("%s=%s" % (k, wikiutil.url_quote(v)))
1.75 -+ arg_str = "&".join(key_args)
1.76 -+ key = "%s:%s" % (key, hash_new('sha1', arg_str).hexdigest())
1.77 -+ return key
1.78 -+
1.79 - def _specialPageText(self, request, special_type):
1.80 - """ Output the default page content for new pages.
1.81 -
1.82 -# HG changeset patch
1.83 -# User Paul Boddie <paul@boddie.org.uk>
1.84 -# Date 1390599896 -3600
1.85 -# Node ID 02d1fa8951523776357a9a37235ad5c37f42fcc8
1.86 -# Parent 70250fe93a4f946e51eaa63accbb0152054ddab2
1.87 -Acquire the request formatter name when the page formatter has not yet been set.
1.88 -
1.89 -diff -r 70250fe93a4f -r 02d1fa895152 MoinMoin/Page.py
1.90 ---- a/MoinMoin/Page.py Fri Jan 24 18:48:26 2014 +0100
1.91 -+++ b/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
1.92 -@@ -1240,15 +1240,17 @@
1.93 - request.formatter = old_formatter
1.94 -
1.95 -
1.96 -- def getFormatterName(self):
1.97 -+ def getFormatterName(self, request=None):
1.98 - """ Return a formatter name as used in the caching system
1.99 -
1.100 -+ @param request: the active request (optional)
1.101 - @rtype: string
1.102 - @return: formatter name as used in caching
1.103 - """
1.104 -- if not hasattr(self, 'formatter') or self.formatter is None:
1.105 -+ formatter = getattr(self, 'formatter', None) or request and getattr(request, 'formatter', None)
1.106 -+ if not formatter:
1.107 - return ''
1.108 -- module = self.formatter.__module__
1.109 -+ module = formatter.__module__
1.110 - return module[module.rfind('.') + 1:]
1.111 -
1.112 - def canUseCache(self, parser=None):
1.113 -@@ -1392,7 +1394,7 @@
1.114 -
1.115 - def getCacheKey(self, request):
1.116 - """ Generate a cache key for a page using optional request information """
1.117 -- key = self.getFormatterName()
1.118 -+ key = self.getFormatterName(request)
1.119 - if request.args:
1.120 - args = request.args.items()
1.121 - args.sort()
1.122 -# HG changeset patch
1.123 -# User Paul Boddie <paul@boddie.org.uk>
1.124 -# Date 1390675730 -3600
1.125 -# Node ID 561fe9439debfd095753a32d884383c315dde7ec
1.126 -# Parent 02d1fa8951523776357a9a37235ad5c37f42fcc8
1.127 -Added tracking of reported dependencies and prevented generation of specific
1.128 -cache entries for request parameter combinations when no extension requires or
1.129 -supports such specific entries.
1.130 -
1.131 -diff -r 02d1fa895152 -r 561fe9439deb MoinMoin/Page.py
1.132 ---- a/MoinMoin/Page.py Fri Jan 24 22:44:56 2014 +0100
1.133 -+++ b/MoinMoin/Page.py Sat Jan 25 19:48:50 2014 +0100
1.134 -@@ -1339,9 +1339,12 @@
1.135 -
1.136 - def loadCache(self, request):
1.137 - """ Return page content cache or raises 'CacheNeedsUpdate' """
1.138 -- cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.139 -- attachmentsPath = self.getPagePath('attachments', check_create=0)
1.140 -- if cache.needsUpdate(self._text_filename(), attachmentsPath):
1.141 -+ for with_params in (True, False):
1.142 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
1.143 -+ attachmentsPath = self.getPagePath('attachments', check_create=0)
1.144 -+ if not cache.needsUpdate(self._text_filename(), attachmentsPath):
1.145 -+ break
1.146 -+ else:
1.147 - raise Exception('CacheNeedsUpdate')
1.148 -
1.149 - import marshal
1.150 -@@ -1373,7 +1376,10 @@
1.151 - code = compile(src.encode(config.charset),
1.152 - self.page_name.encode(config.charset), 'exec')
1.153 - self.enforceCacheLimit(request)
1.154 -- cache = caching.CacheEntry(request, self, self.getCacheKey(request), scope='item')
1.155 -+ # Determine whether the parameters/args need to be incorporated into the
1.156 -+ # cache entry key.
1.157 -+ with_params = "pageparams" in formatter.getReportedDependencies()
1.158 -+ cache = caching.CacheEntry(request, self, self.getCacheKey(request, with_params), scope='item')
1.159 - cache.update(marshal.dumps(code))
1.160 - return code
1.161 -
1.162 -@@ -1392,10 +1398,10 @@
1.163 - for item_age, item in item_ages[:-cache_limit]:
1.164 - item.remove()
1.165 -
1.166 -- def getCacheKey(self, request):
1.167 -+ def getCacheKey(self, request, with_params=False):
1.168 - """ Generate a cache key for a page using optional request information """
1.169 - key = self.getFormatterName(request)
1.170 -- if request.args:
1.171 -+ if with_params and request.args:
1.172 - args = request.args.items()
1.173 - args.sort()
1.174 - key_args = []
1.175 -diff -r 02d1fa895152 -r 561fe9439deb MoinMoin/formatter/text_python.py
1.176 ---- a/MoinMoin/formatter/text_python.py Fri Jan 24 22:44:56 2014 +0100
1.177 -+++ b/MoinMoin/formatter/text_python.py Sat Jan 25 19:48:50 2014 +0100
1.178 -@@ -10,6 +10,7 @@
1.179 -
1.180 - import time
1.181 - from MoinMoin import wikiutil
1.182 -+from MoinMoin.support.python_compatibility import set
1.183 -
1.184 -
1.185 - class Formatter:
1.186 -@@ -40,6 +41,12 @@
1.187 - self.text_cmd_begin = '\nrequest.write('
1.188 - self.text_cmd_end = ')\n'
1.189 -
1.190 -+ # Record dependency requirements of certain content
1.191 -+ self.__dependencies = set()
1.192 -+
1.193 -+ def getReportedDependencies(self):
1.194 -+ return self.__dependencies
1.195 -+
1.196 - def assemble_code(self, text):
1.197 - """inserts the code into the generated text
1.198 - """
1.199 -@@ -186,7 +193,10 @@
1.200 - return self.formatter.div(on, **kw)
1.201 -
1.202 - def macro(self, macro_obj, name, args, markup=None):
1.203 -- if self.__is_static(macro_obj.get_dependencies(name)):
1.204 -+ Dependencies = macro_obj.get_dependencies(name)
1.205 -+ self.__dependencies.update(Dependencies)
1.206 -+
1.207 -+ if self.__is_static(Dependencies):
1.208 - # XXX: why is this necessary??
1.209 - macro_obj.formatter = self
1.210 - return macro_obj.execute(name, args)
1.211 -@@ -204,6 +214,7 @@
1.212 - Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies")
1.213 - except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError):
1.214 - Dependencies = self.defaultDependencies
1.215 -+ self.__dependencies.update(Dependencies)
1.216 -
1.217 - if self.__is_static(Dependencies):
1.218 - return self.formatter.parser(parser_name, lines)