summaryrefslogtreecommitdiff
path: root/repoze/bfg/zcml.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-05-21 01:44:33 +0000
committerChris McDonough <chrism@agendaless.com>2009-05-21 01:44:33 +0000
commit42b75b897add6ab295c18dfc4ce9937e4a212b3e (patch)
treeaaba056c94b5af1af4c90d5c8ef8f884268e6fa9 /repoze/bfg/zcml.py
parent7f12438f7900cbb5a56233aa2ad832196fe4c249 (diff)
downloadpyramid-42b75b897add6ab295c18dfc4ce9937e4a212b3e.tar.gz
pyramid-42b75b897add6ab295c18dfc4ce9937e4a212b3e.tar.bz2
pyramid-42b75b897add6ab295c18dfc4ce9937e4a212b3e.zip
- Removed the pickling of ZCML actions (the code that wrote
``configure.zcml.cache`` next to ``configure.zcml`` files in projects). The code which managed writing and reading of the cache file was a source of subtle bugs when users switched between imperative (e.g. ``@bfg_view``) registrations and declarative registrations (e.g. the ``view`` directive in ZCML) on the same project. On a moderately-sized project (535 ZCML actions and 15 ZCML files), executing actions read from the pickle was saving us only about 200ms (2.5 sec vs 2.7 sec average). On very small projects (1 ZCML file and 4 actions), startup time was comparable, and sometimes even slower when reading from the pickle, and both ways were so fast that it really just didn't matter anyway.
Diffstat (limited to 'repoze/bfg/zcml.py')
-rw-r--r--repoze/bfg/zcml.py90
1 files changed, 3 insertions, 87 deletions
diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py
index 16e6d7012..7ea6eae8d 100644
--- a/repoze/bfg/zcml.py
+++ b/repoze/bfg/zcml.py
@@ -1,7 +1,3 @@
-import cPickle
-import os
-from os.path import realpath
-import time
import types
from zope.configuration import xmlconfig
@@ -28,8 +24,6 @@ from repoze.bfg.interfaces import IRoutesContext
from repoze.bfg.interfaces import IViewPermission
from repoze.bfg.interfaces import IView
-from repoze.bfg.path import package_path
-
from repoze.bfg.security import ViewPermissionFactory
import martian
@@ -132,93 +126,15 @@ class IViewDirective(Interface):
PVERSION = 1
-def pickle_name(name, package):
- path = package_path(package)
- basename = os.path.join(path, name)
- return os.path.join(path, basename + '.cache')
-
-def zcml_configure(name, package, load=cPickle.load):
- """ Execute pickled zcml actions or fall back to parsing from file
- """
- pckname = pickle_name(name, package)
-
- if not (os.path.isfile(pckname) or os.path.islink(pckname)):
- return file_configure(name, package)
-
- try:
- vers, ptime, actions = load(open(pckname, 'rb'))
- except (IOError, cPickle.UnpicklingError, EOFError, TypeError, ValueError,
- AttributeError, NameError, ImportError):
- return file_configure(name, package)
-
- if vers != PVERSION:
- return file_configure(name, package)
-
- try:
- ptime = int(ptime)
- except:
- return file_configure(name, package)
-
- if not hasattr(actions, '__iter__'):
- return file_configure(name, package)
-
- files = set()
- for action in actions:
- try:
- fileset = action[4]
- files.update(fileset)
- except (TypeError, IndexError):
- return file_configure(name, package)
-
- for file in files:
- if not(os.path.isfile(file) or os.path.islink(file)):
- return file_configure(name, package)
-
- mtime = os.stat(realpath(file)).st_mtime
-
- if mtime >= ptime:
- return file_configure(name, package)
-
- context = zope.configuration.config.ConfigurationMachine()
- xmlconfig.registerCommonDirectives(context)
- context.actions = actions
- context.cached_execution = True
- context.execute_actions()
- return True
-
-def remove(name, os=os): # os parameterized for unit tests
- try:
- os.remove(name)
- return True
- except:
- pass
- return False
-
-def file_configure(name, package, dump=cPickle.dump):
+def zcml_configure(name, package):
context = zope.configuration.config.ConfigurationMachine()
xmlconfig.registerCommonDirectives(context)
context.package = package
-
xmlconfig.include(context, name, package)
context.execute_actions(clear=False)
+ return context.actions
- actions = context.actions
- pckname = pickle_name(name, package)
-
- for action in actions:
-
- discriminator = action[0]
- if discriminator and Uncacheable in discriminator:
- remove(pckname)
- return False
-
- try:
- data = (PVERSION, time.time(), actions)
- dump(data, open(pckname, 'wb'), -1)
- except (OSError, IOError, TypeError, cPickle.PickleError):
- remove(pckname)
-
- return False
+file_configure = zcml_configure # backwards compat (>0.8.1)
def exclude(name):
if name.startswith('.'):