MedusaRequestLifeCycle
Creation of ZRendezvous? threads
ZRendezvous? is a class which spawns off multiple threads to handle Zope requests :
z2.setNumberOfThreads(NUMBER_OF_THREADS) ZServer.PubCore._n = NUMBER_OF_THREADS def PubCore.handle(): _handle = ZRendezvous.ZRendevous(_n)
initializes ZRendevous? with NUMBER_OF_THREADS.
Creation of a Request object
Requests are created and enqueued in ZServer?.HTTPServer?, which in turn passes it to ZServer?.PubCore?.handle. The request gets queued up here and gets handled by one of the available threads in the thread pool:
ZServer.HTTPServer.py zrequest=HTTPRequest(sin, env, zresponse) ZServer.HTTPServer.py zhttp_channel.work calls ZServer.PubCore.handle handle(module_name, request, response)
PubCore?.handle is an alias for ZRendezvous?.handle, it doesn't do very much except to put the request in a queue :
requests.append((name, request, response))
A Zope object is located for the Request and published
ZServerPublisher? is placed in an infinite loop (see ZServerPublisher?.__init__) and calls accept() which gets another request to publish.
ZPubliser?.Publish.publish_module() obtains the root object of the ZODB using get_module_info(), then traverses the ZODB using PATH_INFO, until it arrives at the object to publish:
def ZPublisher.publish(...): (bobo_bef..., object, ...)= get_module_info(module_name) request['PARENTS']=parents=[object] object=request.traverse(path, validated_hook=validated_hook) def get_module_info(module_name, ...): if hasattr(module,'bobo_application'): object=module.bobo_application
Where is bobo_application set
Refer to Zope/App/startup.py:
# Set up the "app" object that automagically opens # connections app = ZODB.ZApplication.ZApplicationWrapper( DB, 'Application', OFS.Application.Application, (), Globals.VersionNameName) Zope.bobo_application = app
We can see how the connection is opened in ZODB.ZApplication?.ZApplicationWrapper?:
def __bobo_traverse__(self, REQUEST=None, name=None): : : conn=db.open(version) v=conn.root()[aname] return v
and also here:
def __call__(self, connection=None): db, aname, version_support = self._stuff if connection is None: connection=db.open() elif type(connection) is StringType: connection=db.open(connection) return connection.root()[aname]
Point of note
If you call:
import Zope root = Zope.app()
You still can close the connection to the database, as you haven't completely lost the reference to the connection. :
root._p_jar.close()
So up to this point there are NUMBER_OF_THREADS instances of ZServerPublisher?, which in turn ZODB.