summaryrefslogtreecommitdiff
path: root/repoze/bfg/registry.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-07-13 10:21:59 +0000
committerChris McDonough <chrism@agendaless.com>2008-07-13 10:21:59 +0000
commit3fd91222c6fb46bc2d5838229d7c54130619d73a (patch)
tree0de22c7b5f576e72c7feff4ce7248b9a5e382ef5 /repoze/bfg/registry.py
parent04376ed2f05ecac4a4d20c2780a42764c76fa4ac (diff)
downloadpyramid-3fd91222c6fb46bc2d5838229d7c54130619d73a.tar.gz
pyramid-3fd91222c6fb46bc2d5838229d7c54130619d73a.tar.bz2
pyramid-3fd91222c6fb46bc2d5838229d7c54130619d73a.zip
Use an application-local component registry.
Diffstat (limited to 'repoze/bfg/registry.py')
-rw-r--r--repoze/bfg/registry.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/repoze/bfg/registry.py b/repoze/bfg/registry.py
new file mode 100644
index 000000000..acb5a4abc
--- /dev/null
+++ b/repoze/bfg/registry.py
@@ -0,0 +1,70 @@
+import threading
+import zope.component
+
+from zope.component import getGlobalSiteManager
+from zope.component.interfaces import ComponentLookupError
+from zope.component.interfaces import IComponentLookup
+from zope.component.registry import Components
+from zope.component import getSiteManager as original_getSiteManager
+
+from zope.configuration import xmlconfig
+
+class ThreadLocalRegistryManager(threading.local):
+ registry = getGlobalSiteManager()
+ def set(self, registry):
+ self.registry = registry
+
+ def get(self):
+ return self.registry
+
+ def clear(self):
+ self.registry = getGlobalSiteManager()
+
+registry_manager = ThreadLocalRegistryManager()
+
+def setRegistryManager(manager): # for unit tests
+ global registry_manager
+ old_registry_manager = registry_manager
+ registry_manager = manager
+ return old_registry_manager
+
+def makeRegistry(filename, package, lock=threading.Lock()):
+ # This is absurd and probably not worth it. We want to try to
+ # push our ZCML-defined configuration into an app-local component
+ # registry in order to allow more than one bfg app to live in the
+ # same process space without one unnecessarily stomping on the
+ # other's component registrations (although I suspect directives
+ # that side effects are going to fail). The only way to do that
+ # currently is to override zope.component.getGlobalSiteManager for
+ # the duration of the ZCML includes. We acquire a lock in case
+ # another make_app runs in a different thread simultaneously, in a
+ # vain attempt to prevent mixing of registrations. There's not
+ # much we can do about non-make_app code that tries to use the
+ # global site manager API directly in a different thread while we
+ # hold the lock. Those registrations will end up in our
+ # application's registry.
+ lock.acquire()
+ try:
+ # Do I actually want a globalregistry.BaseGlobalComponents?
+ registry = Components(package.__name__)
+ registry_manager.set(registry)
+ original_getSiteManager.sethook(getSiteManager)
+ zope.component.getGlobalSiteManager = registry_manager.get
+ context = xmlconfig.file(filename, package=package)
+ return context, registry
+ finally:
+ lock.release()
+ zope.component.getGlobalSiteManager = getGlobalSiteManager
+ registry_manager.clear()
+
+def getSiteManager(context=None):
+ if context is None:
+ return registry_manager.get()
+ else:
+ try:
+ return IComponentLookup(context)
+ except TypeError, error:
+ raise ComponentLookupError(*error.args)
+
+from zope.testing.cleanup import addCleanUp
+addCleanUp(original_getSiteManager.reset)