[z3-checkins] r31937 - z3/jsonserver/branch/merge/concatresource
reebalazs at codespeak.net
reebalazs at codespeak.net
Fri Sep 1 17:10:39 CEST 2006
Author: reebalazs
Date: Fri Sep 1 17:10:36 2006
New Revision: 31937
Modified:
z3/jsonserver/branch/merge/concatresource/README
z3/jsonserver/branch/merge/concatresource/cachingadapter.py
z3/jsonserver/branch/merge/concatresource/concatfileresource.py
z3/jsonserver/branch/merge/concatresource/directives.py
z3/jsonserver/branch/merge/concatresource/meta.py
z3/jsonserver/branch/merge/concatresource/resource.py
Log:
Enhance caching for debugging options
- implement lmt_check_period and caching=memory options for easier degugging
- fix a rounding bug that cause If-Modified-Since requests replied
wrongly in some cases, causing the resource to be cooked over
Modified: z3/jsonserver/branch/merge/concatresource/README
==============================================================================
--- z3/jsonserver/branch/merge/concatresource/README (original)
+++ z3/jsonserver/branch/merge/concatresource/README Fri Sep 1 17:10:36 2006
@@ -37,7 +37,7 @@
observation: in Z3 the original resources attempt to handle the cache
headers correctly but never really check if the file gets changed on the
filesystem (only on restart). If this is really a problem and not just I
-believe, then it is fixed in my code.
+believe, then it is fixed in my code. (Read more in the Caching part.)
More information on this issue:
@@ -52,7 +52,7 @@
name="test.js"
files="test1.js
test2.js"
- compress_level="full"
+ compress_level="full"
/>
Some explanation:
@@ -69,14 +69,69 @@
- Specifying "none" will leave your resource uncompressed. This
can be useful for debugging.
+Caching control
+---------------
+
+You have some possibility to control how caching of resources are done.
+
+ <browser:concatresource
+ name="test.js"
+ files="test1.js
+ test2.js"
+ caching="memory"
+ lmt_check_period="10.0"
+ />
+
+The attribute "lmt_checking_period" controls how often the file
+modification dates are checked from the filesystem. By default this is
+60.0, this means that once the file modification is checked, it will not be
+checked before the next 60 seconds elapses. In other words, if you change
+the files on the filesystem, it will cause a maximum of this long delay
+until the changes propagate to the rendered resources. For debugging this
+can be set to 0 to allow immediate changes, however in production this
+setup would cause the files often looked up in the filesystem, which,
+especially with badly implemented filesystems can cause a problem. This
+feature is already an enhancement to the original Zope 3 resource
+implementation where, unless running in debug mode, changes in the resource
+files will require a restart to become visible in the result.
+
+The attribute "caching", when set to "memory", will result that the cooked
+resource will be cached in memory and looked up from them as long as the
+files are unchanged. This, especially with compress options, can cause a
+speedup in rendering the resources. However, in normal operation this is
+not necessary at all, since if caching is set up properly, the browser and
+the upstream cache asks via the "If-Modified-Since" headers if the resource
+has been changed recently, and the resource itself is queried only when
+needed, independently of the setup of this option. While debugging,
+however, when browser caching is forced to switch off, without this option
+the resource would be cooked each time the browser reloads the dependent
+page, so in this case setting "caching" to "memory" causes a significant
+speedup in these cases. In production however, is not only unnecessary but
+also causes an additional memory consumption.
+
+Debug setup
+-----------
+
+To summarize with an example, the following settings are advisable while
+debugging:
+
+ <browser:concatresource
+ name="test.js"
+ files="test1.js
+ test2.js"
+ compress_level="none"
+ caching="memory"
+ lmt_check_period="10.0"
+ />
+
Release notes
-------------
-In Zope 2.9.2 there is Five 1.3.3 included. This contains a but that
+In Zope 2.9.2 there is Five 1.3.3 included. This contains a bug that
the resources will never be looked up from the
application root.
To fix this, you need to update Five to version 1.3.5, or update Zope
-to version 2.9.3 (not available of the time of writing this).
+to version >= 2.9.3.
Modified: z3/jsonserver/branch/merge/concatresource/cachingadapter.py
==============================================================================
--- z3/jsonserver/branch/merge/concatresource/cachingadapter.py (original)
+++ z3/jsonserver/branch/merge/concatresource/cachingadapter.py Fri Sep 1 17:10:36 2006
@@ -8,23 +8,19 @@
'Adapts a ContextFile to a cached resource'
implements(ICachedResource)
- # this is a period in secs within what the resource
- # modification time is never checked.
- # (if 0, always checked)
- # XXX actually this should be kept 0 for debugging and like a minute
- # XXX for production
- lmt_check_period = 60.0
- ##lmt_check_period = 0
-
def __init__(self, context):
self.context = context
self.lmt_last_checked = 0
+ self.data_last_fetched = 0
def _fetchdata(self):
try:
result = self._contents
+ ##print "*****Resource from cached"
except AttributeError:
result = self._contents = self.context.getContents()
+ self.data_last_fetched = time()
+ ##print "*****Resource kooked"
return result
def _deldata(self):
@@ -59,3 +55,6 @@
lmt = property(lambda self: self._fetchlm()['lmt'])
lmh = property(lambda self: self._fetchlm()['lmh'])
+
+ caching = property(lambda self: self.context.caching)
+ lmt_check_period = property(lambda self: self.context.lmt_check_period)
Modified: z3/jsonserver/branch/merge/concatresource/concatfileresource.py
==============================================================================
--- z3/jsonserver/branch/merge/concatresource/concatfileresource.py (original)
+++ z3/jsonserver/branch/merge/concatresource/concatfileresource.py Fri Sep 1 17:10:36 2006
@@ -24,7 +24,7 @@
'''
implements(IContextFile)
- def __init__(self, pathlist, name, compress_level):
+ def __init__(self, pathlist, name, compress_level, caching, lmt_check_period):
# Path is now a list.
assert isinstance(pathlist, (list, tuple))
# check all files, just to raise error if don't exist
@@ -34,6 +34,8 @@
self.pathlist_base = pathlist
self.__name__ = name
self.compress_level = compress_level
+ self.caching = caching
+ self.lmt_check_period = lmt_check_period
# markers for pathlist modification
self.pathlist = []
self.fileslist_changed = None
Modified: z3/jsonserver/branch/merge/concatresource/directives.py
==============================================================================
--- z3/jsonserver/branch/merge/concatresource/directives.py (original)
+++ z3/jsonserver/branch/merge/concatresource/directives.py Fri Sep 1 17:10:36 2006
@@ -1,7 +1,7 @@
from zope.interface import Interface
from zope.configuration.fields import GlobalObject, Tokens, Path, \
PythonIdentifier, MessageID
-from zope.schema import TextLine, Text, Id, Choice
+from zope.schema import TextLine, Text, Id, Choice, Float
from zope.app.security.fields import Permission
from fields import PathList
from zope.app.component.metadirectives import IBasicViewInformation
@@ -36,3 +36,21 @@
values=(u'none', u'safe', u'full'),
required=False,
)
+
+ caching = Choice(
+ title=u"Caching strategy",
+ description=u"Enables caching in memory for faster debugging, by default not enabled.",
+ values=(u'default', u'memory'),
+ required=False,
+ )
+
+ lmt_check_period = Float(
+ title=u"Last modification time checking",
+ description=u"""Sets a grace period in seconds, until which the last modification times
+ are never fetched again from the filesystem. In other words, the system will
+ react after this time for recent changes. For debugging, it is best
+ to set this to 0, for production it can be left to the default 60.0""",
+ required=False,
+ )
+
+
Modified: z3/jsonserver/branch/merge/concatresource/meta.py
==============================================================================
--- z3/jsonserver/branch/merge/concatresource/meta.py (original)
+++ z3/jsonserver/branch/merge/concatresource/meta.py Fri Sep 1 17:10:36 2006
@@ -39,7 +39,9 @@
},
}
-def concatresource(_context, name, files=None, compress_level='safe', layer=_layer, permission='zope.Public'):
+def concatresource(_context, name, files=None, compress_level='safe',
+ caching='default', lmt_check_period=60.0,
+ layer=_layer, permission='zope.Public'):
if not files:
raise ConfigurationError(
@@ -78,7 +80,8 @@
checker = NamesChecker(allowed_names, permission)
- factory = res_factory(res, name, compress_level, resource_factory=new_class, checker=checker)
+ factory = res_factory(res, name, compress_level, caching, lmt_check_period,
+ resource_factory=new_class, checker=checker)
if __pre_3_2__:
_context.action(
Modified: z3/jsonserver/branch/merge/concatresource/resource.py
==============================================================================
--- z3/jsonserver/branch/merge/concatresource/resource.py (original)
+++ z3/jsonserver/branch/merge/concatresource/resource.py Fri Sep 1 17:10:36 2006
@@ -57,6 +57,14 @@
request = self.request
response = request.response
+ # Control in-memory caching
+ cache_in_memory = self.context.caching == 'memory'
+ if cache_in_memory:
+ last_mod = file.lmt
+ if last_mod > file.data_last_fetched:
+ # force delete file contents
+ file.purgeData()
+
# HTTP If-Modified-Since header handling. This is duplicated
# from OFS.Image.Image - it really should be consolidated
# somewhere...
@@ -75,8 +83,9 @@
try: mod_since=long(timeFromDateTimeString(header))
except: mod_since=None
if mod_since is not None:
- last_mod = file.lmt
- if last_mod > 0 and last_mod <= mod_since:
+ if not cache_in_memory:
+ last_mod = file.lmt
+ if last_mod > 0 and int(last_mod) <= mod_since:
response.setStatus(304)
return ''
@@ -85,8 +94,10 @@
# Cache for one day
response.setHeader('Cache-Control', 'public,max-age=86400')
data = file.data
- # force delete file contents
- file.purgeData()
+
+ if not cache_in_memory:
+ # force delete file contents
+ file.purgeData()
return data
@@ -104,10 +115,13 @@
factory = None
resource = None
- def __init__(self, path, name, compress_level, resource_factory=None, checker=None):
+ def __init__(self, path, name, compress_level, caching, lmt_check_period,
+ resource_factory=None, checker=None):
self.__name = name
self.__path = path
self.__compress_level = compress_level
+ self.__caching = caching
+ self.__lmt_check_period = lmt_check_period
if resource_factory is not None:
self.resource = resource_factory
# z3 only
@@ -118,7 +132,8 @@
rsrc = self.__rsrc
except AttributeError:
# Delayed creation. That assures that registry is set up by this time.
- rsrc = self.__rsrc = ICachedResource(self.factory(self.__path, self.__name, self.__compress_level))
+ rsrc = self.__rsrc = ICachedResource(self.factory(self.__path, self.__name,
+ self.__compress_level, self.__caching, self.__lmt_check_period))
resource = self.resource(rsrc, request)
# z3 only
resource.__name__ = self.__name
More information about the z3-checkins
mailing list