3 Stimmen

subprocess blockiert Django-Ansicht

Ich habe ein Problem mit dem Aufruf von subprocess.Popen aus einer Ansicht: Die Ansicht, die subprocess.Popen aufruft, wird nicht angezeigt, bis der Subprozess beendet ist. Der Server sendet sofort "200 OK", aber nicht den Inhalt der Seite.

Meine Frage ist: Ist dies eine Einschränkung von Djangos Entwicklungsserver oder mache ich es falsch?

Der Server bleibt nicht vollständig hängen, da in der Zwischenzeit andere Ansichten bearbeitet werden können.

Es gibt bereits ein paar Fragen zu diesem Thema und Google gibt ein paar andere Themen aber ich kann keine klare Antwort auf meine Frage finden.

Ich glaube nicht, dass dies ein Python-Problem ist, da diese Befehle sofort beendet werden:

python -c 'import subprocess; print subprocess.Popen(["/bin/sleep", "10"]).pid'

Wie man sich vervielfältigt

Testprojekt und Anwendung erstellen:

cd /tmp
django-admin.py startproject django_test
cd django_test
./manage.py startapp subprocess_test

Ersetzen Sie urls.py & subprocess_test/views.py durch:

  • urls.p

    from django.conf.urls.defaults import *

    urlpatterns = patterns('',
      (r'^hello$', 'subprocess_test.views.hello'),
      (r'^start$', 'subprocess_test.views.start'),
    )

  • subprocess_test/views.py

    from django.http import HttpResponse

    importieren subprocess

    def hallo(Anfrage):
      return HttpResponse('Hallo Welt!')

    def start(Anfrage):
      subprocess.Popen(["/bin/sleep", "10"])
      return HttpResponse('start done')

Testen Sie es:

./manage.py runserver 0.0.0.0:8000

Aller à http://127.0.0.1:8000/hello et http://127.0.0.1:8000/start

Testergebnis

"start" braucht 10s zum Laden und "hello" kann während dieser Zeit geladen werden. Ich erhalte zum Beispiel ein solches Protokoll:

[01/Feb/2011 07:20:57] "GET /hello HTTP/1.1" 200 12
[01/Feb/2011 07:21:01] "GET /start HTTP/1.1" 200 10
[01/Feb/2011 07:21:01] "GET /hello HTTP/1.1" 200 12
[01/Feb/2011 07:21:02] "GET /hello HTTP/1.1" 200 12

Mit wget:

wget http://127.0.0.1:8000/start
--2011-02-01 14:31:11-- http://127.0.0.1:8000/start
Verbindung zu 127.0.0.1:8000... hergestellt.
HTTP-Anfrage gesendet, erwarte Antwort... 200 OK
Länge: nicht spezifiziert [text/html]
Speichern in: `Start'

[           <=>                           ] 10          --.-K/s   in 9,5s    

2011-02-01 14:31:21 (1,05 B/s) - " start " gespeichert [10]

3voto

Kekoa Punkte 26946

Es sieht so aus, als wäre es Ihnen egal, was das Ergebnis des Systemaufrufs ist, also würde ich annehmen, dass Sie versuchen, eine Art von Offline- (oder Hintergrund-) Verarbeitung durchzuführen.

Ich würde einen saubereren Weg vorschlagen, als ein Programm direkt auszuführen. Verwenden Sie ein Warteschlangensystem wie Gepäckträger um Verarbeitungsaufgaben in eine Warteschlange zu stellen und dann einen separaten Worker zu haben, der Elemente aus der Warteschlange konsumiert.

Dies hat den Vorteil, dass Ihr Server bei großen Datenverkehrsspitzen geschützt ist, so dass Sie nicht jedes Mal einen Prozess abspalten müssen, wenn eine Anfrage an diese Ansicht gestellt wird. Sie können Elemente so langsam oder so schnell konsumieren, wie Sie wollen, unabhängig vom Datenverkehr.

Der Verkehr ist vielleicht kein Problem, aber ich persönlich halte es auch für eine saubere Entscheidung.

2voto

DominiCane Punkte 1242

Ich stieß auf das gleiche Problem mit Django mit nginx + uwsgi. Oft ist die Sollbruchstelle das Modul des Web-Servers, in meinem Fall war es uwsgi . Hinzufügen von <close-on-exec/> dieses Problem gelöst. Von der anderen Seite der fastcgi Modul nicht dazu führt, dass die Ansicht bei Hintergrundprozessen hängen bleibt.

Ich weiß nicht, welchen Server Sie verwenden, so können Sie dieses Verhalten mit verschiedenen Modulen (uwsgi, mod_wsgi, fastcgi) überprüfen und sehen, was für Sie besser geeignet ist.
Und versuchen Sie, im Hintergrund auszuführen:

subprocess.Popen(["/bin/sleep", "10", "&"])

-1voto

ramdaz Punkte 1677

Versuchen Sie dies

import subprocess

x = subprocess.Popen(["/bin/sleep", "10"])
x.wait()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X