Jack Diederich
jack_diederich at email.com
Mon Sep 16 13:19:25 EST 2002
I just threw some of the python_handler() code into python_init() and it works! This means that it is possible to do all the imports etc only once, instead of once per child. I mentioned the possibility here http://www.modpython.org/pipermail/mod_python/2002-July/002246.html and compared it to the mod_perl handler here http://www.modpython.org/pipermail/mod_python/2002-July/002248.html Basically, we currently do more work than we have to because each child does the same work to initalize the interpreter. In the easy case where we are using the PythonInterpreter directive to force everyone to use the same name for the interpreter (in the below example 'MAIN') we can just do the one initilization in python_init() and the children inherit a clone of the result. I'm not aware of any problems this might cause (wierd shared file handles or something) but I haven't tested it very extensively. I do some calculations in the main of several of my modules, so having this done once is a decent speed boost at apache startup. below is my replacement python_init(), it only works if you have PythonInterpreter 'MAIN' in your httpd.conf modified python_init follows, based on ver 2.7.8 GLYPHS AND WARNINGS! this is just a proof-of-concept, I don't do lots of neccessary error checking and I've hard coded all my strings instead of reading the apache configuration. After initializing the MAIN interpreter, it loads my module your_python_module_here.py and calls its setup function do_our_one_time_global_setup(). The children then get all the calculated stuff that was done in do_our_one_time_global_setup(). enjoy, -jack void python_init(server_rec *s, pool *p) { char buff[255]; PyObject *m; PyObject *obCallBack = NULL; interpreterdata *idata; PyThreadState *tstate; /* pool given to us in ChildInit. We use it for server.register_cleanup() */ pool *child_init_pool = NULL; /* mod_python version */ ap_add_version_component(VERSION_COMPONENT); /* Python version */ sprintf(buff, "Python/%s", strtok((char *)Py_GetVersion(), " ")); ap_add_version_component(buff); /* initialize global Python interpreter if necessary */ if (! Py_IsInitialized()) { /* initialze the interpreter */ Py_Initialize(); #ifdef WITH_THREAD /* create and acquire the interpreter lock */ PyEval_InitThreads(); #endif /* Release the thread state because we will never use * the main interpreter, only sub interpreters created later. */ PyThreadState_Swap(NULL); /* create the obCallBack dictionary */ interpreters = PyDict_New(); if (! interpreters) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, "python_init: PyDict_New() failed! No more memory?"); exit(1); } /* NEW STUFF FROM HERE */ idata = get_interpreter_data("MAIN", s); tstate = PyThreadState_New(idata->istate); PyThreadState_Swap(tstate); m = PyImport_ImportModule("your_python_module_here"); if (!m) { fprintf(stderr, "Couldn't import module\n"); } else { obCallBack = PyObject_CallMethod(m, "do_our_one_time_global_setup", NULL); if (!obCallBack) fprintf(stderr, "CallFunc failed\n"); else fprintf(stderr, "I think it succeeded?\n"); } PyThreadState_Swap(NULL); PyThreadState_Delete(tstate); /* TO HERE */ #ifdef WITH_THREAD /* release the lock; now other threads can run */ PyEval_ReleaseLock(); #endif } } -- __________________________________________________________ Sign-up for your own FREE Personalized E-mail at Mail.com http://www.mail.com/?sr=signup
|