subprocess.Popen calling httpd reload never finishes
ringemup at gmail.com
Wed Aug 18 15:58:27 CEST 2010
On Aug 17, 8:14 pm, Albert Hopkins <mar... at letterboxes.org> wrote:
> On Tue, 2010-08-17 at 12:55 -0700, Nan wrote:
> > Hi folks --
> > I have a Python script running under Apache/mod_wsgi that needs to
> > reload Apache configs as part of its operation. The script continues
> > to execute after the subprocess.Popen call. The communicate() method
> > returns the correct text ("Reloading httpd: [ OK ]"), and I get a
> > returncode of 0. But the python script (Django) that calls Popen
> > never seems to complete (by returning an HTTP response.
> > Any other Popen call I've tried exits properly. Here's some sample
> > code:
> > args = ['sudo /etc/init.d/httpd reload']
> > proc = subprocess.Popen(args, stdin=subprocess.PIPE,
> > stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True,
> > close_fds=True)
> > (stdout_txt, stderr_txt) = proc.communicate("")
> > proc.wait()
> > logging.debug('%d %s<hr />%s' % (proc.returncode, stdout_txt,
> > stderr_txt))
> > logging.debug('still executing')
> > return HttpResponse('done')
> > The logging statements are output, but the script doesn't exit. If
> > you substitute "sudo ls -l" or "sudo /etc/init.d/httpd configtest" for
> > "sudo /etc/init.d/httpd reload", the exits properly.
> > Any idea what I might be doing wrong?
> > Thanks!
> Django runs inside apache. It's kinda weird to have an apache process
> restart itself and expect it to return to the caller.
> If the init script does like mine, "reload" executes "apachectl -k
> graceful" What that instructs apache to do is to restart, but only
> kill the process(es) when there are no more connections. So apache is
> waiting for your connection to close, but you are inside an HTTP request
> waiting for apache to restart. So you have a race condition here.
> It's not advisable to have apache kill itself and expect it to send a
> status back to you telling you it's dead.
> See the apache docs for a better explanation.
Ah, I'd been told that there would be no conflict, and that this was
just reloading the configuration, not restarting Apache.
I do need the web app to instruct Apache to reload because just before
this it's creating new VirtualHosts that need to be recognized. Is
there a better way to do this (e.g. to say "start doing this once I'm
I'm getting a status code and output from the call before the Django
script stops executing... Is there a way to stop waiting for the
process to complete once I have those?
More information about the Python-list