Ich schreibe eine App, mit der der Benutzer Daten in eine Datei hochladen kann; Die App wird diese Daten verarbeiten und die Ergebnisse per E-Mail an den Benutzer senden. Die Verarbeitung kann einige Zeit in Anspruch nehmen, daher möchte ich dies separat in einem Python-Skript behandeln, anstatt in der Ansicht darauf zu warten, dass sie abgeschlossen wird. Das Python-Skript und die Python-Ansicht müssen nicht kommunizieren, da das Skript die Daten aus einer Datei aufnimmt, die von der Ansicht geschrieben wurde. Die Ansicht wird nur eine Nachricht wie "Vielen Dank für das Hochladen Ihrer Daten - die Ergebnisse werden Ihnen per E-Mail gesendet werden"
Was ist der beste Weg, dies in Django zu tun? Einen separaten Prozess erzeugen? Etwas in eine Warteschlange stellen?
Ein Beispielcode würde sehr geschätzt werden. Danke.
Die einfachste mögliche Lösung besteht darin, benutzerdefinierte Befehle zu schreiben, die nach allen suchen die nicht verarbeiteten Dateien, verarbeitet sie und sendet dann eine E-Mail an den Benutzer. Die Verwaltungsbefehle laufen innerhalb des Django-Frameworks, so dass sie Zugriff auf alle Modelle, Datenbankverbindungen usw. haben, aber Sie können sie von überall aufrufen, zum Beispiel crontab.
Wenn Sie sich über den Zeitraum zwischen dem Hochladen der Datei und dem Start der Verarbeitung Gedanken machen, können Sie ein Framework wie Sellerie verwenden Hilfsbibliothek für die Verwendung einer Nachrichtenwarteschlange und Ausführen von Arbeitern, die die Warteschlange überwachen. Dies wäre eine ziemlich niedrige Latenz, aber auf der anderen Seite könnte Einfachheit für Sie wichtiger sein.
Ich rate dringend davon ab, Threads oder Launch-Prozesse in Ihren Ansichten zu starten, da die Threads innerhalb des django-Prozesses laufen und Ihren Webserver (abhängig von Ihrer Konfiguration) zerstören könnten. Der untergeordnete Prozess erbt alles vom Django-Prozess, den Sie wahrscheinlich nicht möchten. Es ist besser, dieses Zeug getrennt zu halten.
Ich habe derzeit ein Projekt mit ähnlichen Anforderungen (nur komplizierter ^^).
Erzeuge niemals einen Subprozess oder einen Thread aus deiner Django-Ansicht. Du hast keine Kontrolle über die Django-Prozesse und es könnte vor dem Ende der Aufgabe getötet, pausiert usw. werden. Es wird vom Webserver gesteuert (z. B. Apache über WSGI).
Was ich tun würde, wäre ein externes Skript, das in einem separaten Prozess laufen würde. Sie haben zwei Lösungen, die ich denke:
Nun müssen Sie wahrscheinlich auf die Informationen in Django-Modellen zugreifen, um den Benutzer am Ende per E-Mail zu erreichen. Hier haben Sie mehrere Lösungen:
Ich würde für einen externen Prozess gehen und die Module oder POST-Anfrage importieren. Auf diese Weise ist es viel flexibler. Sie könnten zum Beispiel das Multiprocessing-Modul verwenden, um mehrere Dateien gleichzeitig zu verarbeiten (und so effizient Multicore-Maschinen zu verwenden).
Ein einfacher Workflow wäre:
Mein Projekt enthält eine wirklich CPU-intensive Verarbeitung. Ich verwende derzeit einen externen Prozess, der einem Pool von Worker-Prozessen Verarbeitungsjobs gibt (das ist im Grunde das, was Sellery für Sie tun kann) und meldet den Fortschritt und die Ergebnisse über POST-Anfragen an die Django-Anwendung zurück. Es funktioniert wirklich gut und ist relativ skalierbar, aber ich werde es bald ändern, um Sellerie auf einem Cluster zu verwenden.
Sie könnten einen Thread erstellen, um die Verarbeitung durchzuführen. Es hätte nicht viel mit Django zu tun; Die View-Funktion müsste den Worker-Thread starten und das war's.
Wenn Sie wirklich einen separaten Prozess wünschen, benötigen Sie das Modul Unterprozess . Aber müssen Sie die Standard-E / A wirklich umleiten oder eine externe Prozesssteuerung zulassen?
Beispiel:
%Vor% Ich habe kein Programm erstellt, bei dem ich den Fortschritt der Threads nicht verfolgen wollte, also weiß ich nicht, ob das funktioniert, ohne das Thread
-Objekt irgendwo zu speichern. Wenn Sie das tun müssen, ist es ziemlich einfach:
Sie können Threads aus der Liste entfernen, wenn thread.is_alive()
False
zurückgibt:
Sie könnten Multiprocessing verwenden. Ссылка
Im Wesentlichen
%Vor%