Starting other processes in a view gives me some weird results.

77 views
Skip to first unread message

Ino Pua

unread,
Mar 12, 2007, 10:03:57 PM3/12/07
to Django users
Quick way of reproducing:

1. Start a new project
2. Replace urls.py with:

from django.conf.urls.defaults import *
from django.http import HttpResponse
import subprocess


def start(request):
cmdname = request['cmd']
p = subprocess.Popen([cmdname, 'start'], stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
return HttpResponse(stdout or stderr)

def stop(request):
cmdname = request['cmd']
p = subprocess.Popen([cmdname, 'stop'], stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
return HttpResponse(stdout or stderr)

urlpatterns = patterns('',
(r'start/$', start),
(r'stop/$', stop),
)

3. Start the django server (python manage.py runserver 8080)
4. Access an url like: http://localhost:8080/start/?cmd=/etc/init.d/exim4,
or any cmd= that starts a service (anything that daemonizes). You'll
notice that the loading bar (in my firefox at least) never stops
loading, even though the django web server is done with the request,
and the page has been rendered.
5. If you now stop the server and try to start it again, it wont be
able to bind to its port:

Validating models...
0 errors found.

Django version 0.96-pre, using settings 'starter.settings'
Development server is running at http://127.0.0.1:8080/
Quit the server with CONTROL-C.
Error: (48, 'Address already in use')

However, at this time, Im not sure whats causing this to happen. Any
ideas would be appreciated.

Shutting the started service down manually, or accessing the /stop/?
cmd= url before stopping the django server fixes the problem.

akonsu

unread,
Mar 12, 2007, 10:37:38 PM3/12/07
to Django users
hello,

i do not know what causes this.

i am curious what happens if you replace

return HttpResponse(stdout or stderr)

with

return HttpResponse('hello world')

this is how i would debug
konstantin

> Development server is running athttp://127.0.0.1:8080/

Ino Pua

unread,
Mar 13, 2007, 8:46:24 AM3/13/07
to Django users
On Mar 13, 3:37 am, "akonsu" <ako...@gmail.com> wrote:
> hello,
> i do not know what causes this.
> i am curious what happens if you replace
> return HttpResponse(stdout or stderr)
> with
> return HttpResponse('hello world')

If I do that, 'hello world' is printed in the web browser, but its
still stuck on loading and the same issues with not being able to
restart the web server persists.

Joe

unread,
Mar 13, 2007, 9:57:09 AM3/13/07
to Django users
We had a similar problem when a process you start tries to send a
signal to python indicating a warning or something similar. There is
a know version in older versions of python that causes it to ignore
these signals and hang the process. Try upgrading python.

akonsu

unread,
Mar 13, 2007, 9:57:45 AM3/13/07
to Django users
i am using freebsd. i do not have exim4. i tried this with 'ls'
command.

it gives me the error below. if i output hello world instead, the
browser seems to download the page correctly and does not appear to be
stuck. i use './manage runserver'.

Traceback (most recent call last):

File "/usr/local/lib/python2.4/site-packages/django/core/servers/
basehttp.py", line 273, in run
self.finish_response()

File "/usr/local/lib/python2.4/site-packages/django/core/servers/
basehttp.py", line 312, in finish_response
self.write(data)

File "/usr/local/lib/python2.4/site-packages/django/core/servers/
basehttp.py", line 383, in write
assert type(data) is StringType,"write() argument must be string"

AssertionError: write() argument must be string

On Mar 13, 8:46 am, "Ino Pua" <ino...@gmail.com> wrote:

Ino Pua

unread,
Mar 13, 2007, 11:10:00 AM3/13/07
to Django users
Using just 'ls' or something similar does not trigger the bug. You
have to start a daemon from django in order to trigger it. The
attached views assume cmd to be a command that takes 'start' as a
parameter in order to daemonize it, so for freebsd you might have to
customize the " p = subprocess.Popen([cmdname, 'start'],
stdout=subprocess.PIPE) " line in order to start your daemon.

Malcolm Tredinnick

unread,
Mar 14, 2007, 4:28:22 AM3/14/07
to django...@googlegroups.com
On Tue, 2007-03-13 at 08:10 -0700, Ino Pua wrote:
> Using just 'ls' or something similar does not trigger the bug. You
> have to start a daemon from django in order to trigger it. The
> attached views assume cmd to be a command that takes 'start' as a
> parameter in order to daemonize it, so for freebsd you might have to
> customize the " p = subprocess.Popen([cmdname, 'start'],
> stdout=subprocess.PIPE) " line in order to start your daemon.

I suspect this really a Django problem. It sounds like, despite the
attempt to daemonize the process, the init script isn't properly
shutting down or something and so the process that is executing
mod_python and that particular view hasn't finished yet (it still has a
child process).

One way to check this out would be to check out the state
of /proc/<pid>/fd and the like (it sounds like you're on a Linux system)
to see if there are file handles to your subprocess command still open.
Basically, you need to investigate at the sytsem level and work out why
the python function does think its work is done yet. There is nothing
really Django specific going on here that I can see, but deeper
investigation may prove otherwise.

Regards,
Malcolm


Ino Pua

unread,
Mar 14, 2007, 11:36:42 AM3/14/07
to Django users

On Mar 14, 9:28 am, Malcolm Tredinnick <malc...@pointy-stick.com>
wrote:


> On Tue, 2007-03-13 at 08:10 -0700, Ino Pua wrote:
> > Using just 'ls' or something similar does not trigger the bug. You
> > have to start a daemon from django in order to trigger it. The
> > attached views assume cmd to be a command that takes 'start' as a
> > parameter in order to daemonize it, so for freebsd you might have to
> > customize the " p = subprocess.Popen([cmdname, 'start'],
> > stdout=subprocess.PIPE) " line in order to start your daemon.
>
> I suspect this really a Django problem. It sounds like, despite the
> attempt to daemonize the process, the init script isn't properly
> shutting down or something and so the process that is executing
> mod_python and that particular view hasn't finished yet (it still has a
> child process).

Writing the same service using twisted works just fine, so at the
moment Im using
a really dirty workaround by making an xmlrpc-call to the twisted
server telling it
to execute my command instead. Shutting down/restarting the twisted
server works
without a problem even while starting any amount of services (be it
any in /etc/init.d
or my custom services).

> One way to check this out would be to check out the state
> of /proc/<pid>/fd and the like (it sounds like you're on a Linux system)
> to see if there are file handles to your subprocess command still open.
> Basically, you need to investigate at the sytsem level and work out why
> the python function does think its work is done yet. There is nothing
> really Django specific going on here that I can see, but deeper
> investigation may prove otherwise.

Judging from /proc/pid/fd everything is as I would assume it was: just
a config file,
a log file and three sockets open (in my case, the program listens on
three ports), And
three references (Im assuming stdin, stdout, stderr) to /dev/null.
Same with any other
daemon I've looked at. Since it works ok from the command line or from
a twisted
service, I can only assume its not where the problem lies.


UPDATE:

Ive tried getting it to work with mod_python, but all kinds of
permission issues and
environment issues came biting me when I did, so Ive decided to stick
with the
xmlrpc-server solution for the time being.

Reply all
Reply to author
Forward
0 new messages