[Zope] Re: Zope and mod_python
Tres Seaver
tseaver at zope.com
Fri Feb 4 11:39:53 EST 2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Pascal Peregrina wrote:
| Hi,
|
| I have successfully (I think) integrated Zope with Apache/mod_python, just
| to make some tests.
Wow! That is awesome.
| I would like to know if you think that this can be interesting in terms of
| performance (specially number of simultaneous requests being handled,
| compared to one "real" Zope instance, even with number of threads
| increased).
Good questions: we would need to do a fair amount of difficult testing
to know for sure. Certainly it is a big win for shops which are already
comfortable with managing large-scale dynamic Apache installations.
| Sorry in advance if I missed something important and if this is not
| interesting at all :)
Not a all.
| By now I have not been able to get the logging working,
Zope's logging relies on having a single "gateway" in the appserver
process which is used by the worker threads. I think your mod_python
child processes are like Zope worker threads without the "parent" (which
has the gateway). I wonder if configuring it to use syslog would Just
Work (TM)?
| and I am not
| completely sure about clean shutdown when Apache is stopped, but I will
| continue investigating...
Doesn't Apache / mod_python allow you to register a "graceful shutdown"
callback?
| Software :
| + httpd-2.0.52
| + mod_python-3.1.3
| + Python-2.3.4
| + psyco-1.4 (only to use Zope Speedpack product)
| + Zope 2.7.4
| + Several Zope products (Localizer, CMF 1.5.0, ...)
|
| Architecture :
| + One Zeo instance
| + Apache / mod_python
| and that's all :)
|
| I created a zhandler package (very first draft) containing :
| + __init__.py : Zope init
| + zhandler.py : the handler itself (it uses ZPublisher)
|
| Then, from standard build/install/configuration of all the software above,
| this is the configuration changes I did :
| + Created a Zeo instance
| + httpd.conf (global settings) :
| SetHandler mod_python
| PythonInterpreter zinterpreter
| PythonHandler zhandler.zhandler
| PythonDebug On
| + and this is the zope.conf file (I called it zhandler.conf) I used
| (basically it only consisted in removing all <server> occurences) :
|
############################################################################
| ###
| # Welcome to Zope 2.
|
############################################################################
| ###
| #
| # This is the Zope configuration file. The Zope configuration file
| # shows what the default configuration directives are, and show
| # examples for each directive. To declare a directive, make sure that
| # you add it to a line that does not begin with '#'. Note that comments
| # are only allowed at the beginning of a line: you may not add comments
| # after directive text on the same line.
|
| # ZConfig "defines" used for later textual substitution
|
| %define INSTANCE /export/home/pperegri/20050203/instances/zope_rw
| %define ZOPE /export/home/pperegri/20050203/opt/Zope-2.7.4-0
|
| instancehome $INSTANCE
| products /export/home/pperegri/20050203/opt/Products
| debug-mode off
| zeo-client-name zcmd
|
| <eventlog>
| level all
| <logfile>
| path $INSTANCE/log/cmdline_event.log
| level info
| </logfile>
| </eventlog>
|
| <logger access>
| level WARN
| <logfile>
| path $INSTANCE/log/cmdline_Z2.log
| format %(message)s
| </logfile>
| </logger>
|
| <zodb_db temporary>
| mount-point /temp_folder
| <temporarystorage>
| name sessions
| </temporarystorage>
| container-class Products.TemporaryFolder.TemporaryContainer
| </zodb_db>
|
| <zodb_db remote>
| mount-point /
| cache-size 40000
| <zeoclient>
| cache-size 256MB
| server 192.168.11.163:9001
| read-only off
| storage 1
| name zeostorage
| var $INSTANCE/var
| </zeoclient>
| </zodb_db>
|
|
| + __init.py__
| __all__ = ['zhandler']
|
|
zope_pythonpath='/export/home/pperegri/20050203/opt/Zope-2.7.4-0/lib/python'
| zope_conf='/export/home/pperegri/test/conf/zhandler.conf'
|
| import sys
| if not zope_pythonpath in sys.path:
| sys.path.append(zope_pythonpath)
|
| import Zope
| if not Zope._began_startup:
| Zope.configure('/export/home/pperegri/test/conf/zhandler.conf')
| Zope.app()
|
|
| + zhandler.py
| import mod_python.apache
| import os
| import sys
|
| # this will save memory
| #os.environ = {}
|
| import ZPublisher
|
| class ZopeStdout(mod_python.apache.NullIO):
|
| """
| Class that allows writing to the socket directly for Zope.
| """
|
| def __init__(self, req):
| self.req = req
| self.pos = 0
|
| def write(self, result):
| if not result or self.pos: return
| pos1=result.find('\r\n\r\n')
| pos2=result.find('\n\n')
| if pos1!=-1 and pos2!=-1 and pos1>pos2:
| ss = result.split('\n\n', 1)
| else:
| ss = result.split('\r\n\r\n', 1)
| if len(ss) < 2:
| ss = result.split('\n\n', 1)
| ss[0]=ss[0].replace('\r\n', '\n')
| for line in ss[0].split('\n'):
| if line.find(':')!=-1:
| h,v=line.split(':',1)
| if h.lower() == "status":
| status = int(v.split()[0])
| self.req.status = status
| elif h.lower() == "content-type":
| self.req.content_type = v
| self.req.headers_out[h] = v
| else:
| self.req.headers_out.add(h, v)
| if len(ss)==2:
| self.req.write(ss[1])
| self.pos+=len(ss[1])
|
| def tell(self): return self.pos
|
| def handler(req):
| save_env, si, so = mod_python.apache.setup_cgi(req)
| sys.stdout = ZopeStdout(req)
| if 'REQUEST_URI' in os.environ:
| os.environ['PATH_INFO']=os.environ['REQUEST_URI'].split('?')[0]
| os.environ['PATH_TRANSLATED']=os.environ['PATH_INFO']
| if 'HTTP_CONNECTION' in os.environ:
| os.environ['CONNECTION_TYPE']=os.environ['HTTP_CONNECTION']
| os.environ['SCRIPT_NAME']=''
| names=os.environ.keys()
| for name in names:
| if not name.startswith('HTTP_') and not
name.startswith('PATH_') and
| not name.startswith('SERVER_') and not name in
|
['CONNECTION_TYPE','GATEWAY_INTERFACE','REQUEST_METHOD','REMOTE_ADDR','SCRIP
| T_NAME','QUERY_STRING']:
| del os.environ[name]
| try:
| ZPublisher.publish_module('Main', stdin=sys.stdin,
| stdout=sys.stdout, stderr=sys.stderr,
| environ=os.environ)
| finally:
| mod_python.apache.restore_nocgi(save_env, si, so)
| return mod_python.apache.OK
Very impressive work.
Tres.
- --
===============================================================
Tres Seaver tseaver at zope.com
Zope Corporation "Zope Dealers" http://www.zope.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFCA6VZGqWXf00rNCgRAkhcAJ4m6pDA5q6CkKeYyg2IkXUNLgBc0wCfWWy0
npGh1X7k3Q8kqLmJLfq8q6w=
=zdNn
-----END PGP SIGNATURE-----
More information about the Zope
mailing list