Copterfly / modwsgi

Automatically exported from code.google.com/p/modwsgi
0 stars 0 forks source link

jcc.initVM() doesn’t return when mod_wsgi is configured as daemon mode #131

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I am using mod-wsgi with django, and in django I use pylucene to do full
text search.

While mod-wsgi is configured to be embedded mode, there is no problem at all.
But when mod-wsgi is configured to be daemon mode, the apache just gets stuck, 
and the browser just keep loading but nothing appears.

Then I identity the problem to be the jcc.initVM().
Here is my wsgi script:

    import os, sys, jcc
    sys.stderr.write('jcc.initVM\n')
    jcc.initVM()
    sys.stderr.write('finished jcc.initVM\n')
    ....

After I restart my apache, and make a request from my browser, I find that
/var/log/apache2/error.log 
only has:

    jcc.initVM

Meaning that it gets stuck at the line jcc.initVM(). (If the mod_wsgi is
configured as embedded mode, there is no problem.)

And here is my /etc/apache2/sites-available/default:

    WSGIDaemonProcess site user=ross group=ross threads=1
    WSGIProcessGroup site
    WSGIScriptAlias / /home/ross/apache/django.wsgi

    <Directory /home/ross/apache/>
      Order deny,allow
      Allow from all
    </Directory>

And finally, I find out that in the source code of jcc (jcc.cpp), it hangs
at the function:

    JNI_CreateJavaVM(&vm, (void **) &vm_env, &vm_args)

How to solve the problem?

Program versions:

    libapache2-mod-wsgi 2.3-1
    jcc 2.1
    python 2.5
    Apache 2.2.9-8ubuntu3
    Ubuntu 8.10

Original issue reported on code.google.com by ph.tc...@gmail.com on 14 Feb 2009 at 4:43

GoogleCodeExporter commented 9 years ago
Probably same as:

  http://code.google.com/p/modwsgi/issues/detail?id=87

No simple solution yet except use a wrapper program around your program that 
unblocks signals.

Original comment by Graham.Dumpleton@gmail.com on 14 Feb 2009 at 5:01

GoogleCodeExporter commented 9 years ago
I am sorry that I still don't know how to work around.

django.wsgi:
import os
os.system('/home/ross/apache/run.py')

run.py:
#!/usr/bin/env python
import os, sys
import jcc
sys.stderr.write('jcc.initVM\n')
jcc.initVM()
sys.stderr.write('finished jcc.initVM\n')
sys.path.append('/home/ross/voofie/')
sys.path.append('/home/ross/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'voofie.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

It won't work. Could you give me some suggestion?

Original comment by ph.tc...@gmail.com on 14 Feb 2009 at 8:17

GoogleCodeExporter commented 9 years ago
It isn't that simple unfortunately. The wrapper program needs to be a C program 
as Python doesn't have access to 
required functions. Specifically, calls need to be made to either of the C 
functions sigblock() or sigprocmask() to 
restore ability of the thread that exec'd the program to receive signals.

I'll have another look at whether there might be a fiddle that can be done in 
mod_wsgi to allow it to work, but don't 
think there is. The code in mod_wsgi has to be written a completely different 
way and I just haven't got to that yet.

Original comment by Graham.Dumpleton@gmail.com on 14 Feb 2009 at 9:07

GoogleCodeExporter commented 9 years ago
Thank you very much. 

With reference to Brennan's exec.c, I write the following code using cython and
compiled that.

cpyrun.pyx:

cdef extern from "signal.h":
        ctypedef struct sigset_t:
                pass
        int sigfillset(sigset_t *set)
        int sigprocmask(int __how, sigset_t *set, sigset_t *oset)
        int SIG_UNBLOCK

import os, sys
import jcc
from django.core.handlers.wsgi import WSGIHandler
def run_wsgi():
        cdef sigset_t set
        sigfillset(&set)
        sigprocmask(SIG_UNBLOCK, &set, NULL)
        sys.stderr.write('jcc.initVM\n')
        jcc.initVM()
        sys.stderr.write('finished jcc.initVM\n')
        sys.path.append('/home/ross/site/')
        sys.path.append('/home/ross/')
        os.environ['DJANGO_SETTINGS_MODULE'] = 'site.settings'
        application = WSGIHandler()

And my django.wsgi:

import sys
sys.path.append('/home/ross/site/apache')
import cpyrun
cpyrun.run_wsgi()

However, I still get the same error, that the program still can't pass 
jcc.initVM.
Does that mean that I used the sigprocmask() wrongly? (I don't have much idea 
about
that, I just copy that from the exec.c and change that to cython)

Original comment by ph.tc...@gmail.com on 14 Feb 2009 at 10:39

GoogleCodeExporter commented 9 years ago
I'd still have:

django.wsgi:
import os
os.system('/home/ross/apache/run.py')

run.py:
#!/usr/bin/env python
...

and have signal unblocking in separate run.py program rather than in mod_wsgi 
daemon process as signals still going to 
likely be captured by Apache/mod_wsgi and not end up being handled by your 
program.

This is all assuming it is the same problem with SIGPWR.

Original comment by Graham.Dumpleton@gmail.com on 14 Feb 2009 at 10:57