No, I'm trying to run it as a dev server. I use mod_python in production. However, I use the dev server in a shared environment so that a few other programmers and testers in the office can view the site.
In any case, sending a TERM signal to the parent process should cause the child to die. There is no reasonable justification for the current behavior, IMHO. On Mar 24, 2:45 pm, graham_king <gra...@gkgk.org> wrote: > It looks like you're trying to run the dev server as a real web > server, which is a very bad idea (it's only serves one request at a > time, for starters). As it says here: > > http://docs.djangoproject.com/en/dev/ref/django-admin/#runserver-opti... > > "DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone > through security audits or performance tests. (And that's how it's > gonna stay. We're in the business of making Web frameworks, not Web > servers, so improving this server to be able to handle a production > environment is outside the scope of Django.)" > > Is there a reason you can't use Apache, or a different server with a > WSGI or FCGI setup? If you're not running it in production, why do you > need daemontools? > > Best regards, > Graham > > On Mar 24, 11:13 am, Dave Benjamin <dave.benja...@gmail.com> wrote: > > > Hello, > > > I run the Django development server (manage.py runserver) under > > Daemontools on Linux. Daemontools is a server management framework > > that runs a foreground process as a daemon and automates the tasks of > > starting, restarting, signal handling, and logging. I use a run script > > that looks like the following: > > > #!/bin/sh > > exec 2>&1 > > exec setuidgid www-data envdir ./env myapp/manage.py runserver -- > > adminmedia=/usr/local/myapp/media/ 0.0.0.0:8000 > > > This has been working well for me for awhile except for one problem. > > The usual way of causing a Daemontools service to exit, either to > > terminate the service or to do a full restart, is to type the > > following: > > > svc -t /service/myapp > > > This sends a TERM signal to the parent process. Due to the way that > > Django's autoreloader module (django.utils.autoreload) is written, > > there are actually two processes, a monitoring parent process and a > > child process exits whenever a reload is necessary. Sending a TERM > > signal to the parent process leaves the child process running, and > > this causes an orphan process that never exits and hogs the socket. > > > If the --noreload argument is passed to manage.py runserver, this > > problem goes away because there is only one process running. > > Unfortunately, this disables the autoreload functionality. > > > I have written a modification to my manage.py script that > > monkeypatches the autoreload module so that it keeps a set of child > > PIDs and sends them TERM signals when the parent process receives one. > > I changed the call to spawnve so that it sends P_NOWAIT instead of > > P_WAIT, causing the call to return a PID instead of an exit code. I > > then stash this code in the set and do the os.waitpid() call myself. > > The code is a modified version of the spawn* wrappers in os.py, and > > handles the exit code processing and removal of exited/signalled PIDs > > from the set. > > > I haven't tested this change on anything besides Linux, so at the very > > least I'd imagine it causes some problems under Windows. I'm posting > > it here in hope that it will be useful to someone else, and possibly > > with some tweaking be integrated into the autoreload module. > > > The following is what my manage.py script looks like now: > > > #!/usr/bin/python > > from django.core.management import execute_manager > > try: > > import settings # Assumed to be in the same directory. > > except ImportError: > > import sys > > sys.stderr.write("Error: Can't find the file 'settings.py' in the > > directory containing %r. It appears you've customized things.\nYou'll > > have to run django-admin.py, passing it your settings module.\n(If the > > file settings.py does indeed exist, it's causing an ImportError > > somehow.)\n" % __file__) > > sys.exit(1) > > > import os, sys, signal > > from django.utils import autoreload > > > def restart_with_reloader(): > > reloader_pids = set() > > > def kill_reloaders(signum, frame): > > try: > > while True: > > pid = reloader_pids.pop() > > os.kill(pid, signal.SIGTERM) > > except KeyError: > > pass > > > signal.signal(signal.SIGTERM, kill_reloaders) > > > while True: > > args = [sys.executable] + sys.argv > > if sys.platform == "win32": > > args = ['"%s"' % arg for arg in args] > > new_environ = os.environ.copy() > > new_environ["RUN_MAIN"] = 'true' > > pid = os.spawnve(os.P_NOWAIT, sys.executable, args, > > new_environ) > > reloader_pids.add(pid) > > while True: > > try: > > wpid, sts = os.waitpid(pid, 0) > > except OSError: > > continue > > if os.WIFSTOPPED(sts): > > continue > > elif os.WIFSIGNALED(sts): > > exit_code = -os.WTERMSIG(sts) > > if wpid in reloader_pids: reloader_pids.remove(wpid) > > break > > elif os.WIFEXITED(sts): > > exit_code = os.WEXITSTATUS(sts) > > if wpid in reloader_pids: reloader_pids.remove(wpid) > > break > > else: > > raise error, "Not stopped, signaled or exited???" > > if exit_code != 3: > > return exit_code > > > autoreload.restart_with_reloader = restart_with_reloader > > > if __name__ == "__main__": > > execute_manager(settings) > > > Thanks, > > Dave --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---