Laufender Job im Hintergrund von Perl OHNE Warten auf Rückgabe

8

Der Haftungsausschluss

Zunächst einmal weiß ich, dass diese Frage (oder enge Variationen) tausend Mal gestellt wurde. Ich habe wirklich ein paar Stunden damit verbracht, in die offensichtlichen und nicht so offensichtlichen Orte zu schauen, aber vielleicht gibt es etwas Kleines, das mir fehlt.

Der Kontext

Lassen Sie mich das Problem klarer definieren: Ich schreibe eine Newsletter-App, in der der eigentliche Sendeprozess asynchron sein soll. Wenn der Benutzer auf "Senden" klickt, wird die Anfrage sofort zurückgegeben und anschließend kann der Fortschritt auf einer bestimmten Seite überprüft werden (z. B. über AJAX). Es ist in Ihrem traditionellen LAMP-Stack geschrieben.

In dem speziellen Host, den ich verwende, sind PHPs exec () und system () aus Sicherheitsgründen deaktiviert, aber Perls Systemfunktionen (exec, system und backticks) sind nicht. Meine Workaround -Lösung bestand also darin, ein "Trigger" -Skript in Perl zu erstellen, das den eigentlichen Absender über die PHP-CLI aufruft und auf die Fortschrittsseite umleitet.

Wo ich stecke

Genau die Zeile, die die Absender anrufen, ist ab sofort:

%Vor%

Das Problem ist, dass es nicht sofort zurückkehrt, sondern darauf wartet, dass das Skript beendet wird. Ich möchte, dass es im Hintergrund läuft und das System sich selbst zurückrufen lässt. Ich habe auch versucht, ein ähnliches Skript in meinem Linux-Terminal laufen zu lassen, und die Eingabeaufforderung wird erst angezeigt, wenn das Skript beendet ist, obwohl meine Testausgabe nicht läuft und anzeigt, dass sie wirklich im Hintergrund läuft.

Was ich schon probiert habe

  • Perls exec () -Funktion - dasselbe Ergebnis von system ().
  • Ändern des Befehls in: "php -q sender.php | at now"), in der Hoffnung, dass der "at" -Daemon zurückkehren würde und der PHP-Prozess selbst nicht an Perl angehängt würde.
  • Ausführen des Befehls 'indirekt': "/ bin / sh -c 'php -q sender.php & amp;'" - wartet immer noch, bis sender.php mit dem Senden fertig ist.
  • fork () den Prozess ausführen und den Systemaufruf im Kind ausführen (hoffentlich abgelöster Prozess) - dasselbe Ergebnis wie oben

Meine Testumgebung

Um sicher zu sein, dass ich nichts Offensichtliches verpasse, habe ich ein sleeper.php-Skript erstellt, das nur fünf Sekunden schläft, bevor es beendet wird. Und ein test.cgi-Skript, das folgendermaßen lautet: wörtlich:

%Vor%

Was soll ich jetzt versuchen?

    
Rafael Almeida 15.04.2010, 15:32
quelle

5 Antworten

9

Im Wesentlichen müssen Sie einen Prozess "dämonisieren" - ein Kind abzweigen und es dann vollständig vom Eltern trennen, damit das Elternteil sicher beendet werden kann, ohne das Kind zu beeinflussen.

Sie können dies einfach mit dem CPAN-Modul Proc :: Daemon durchführen:

%Vor%     
Ether 15.04.2010, 16:42
quelle
7

Manchmal können STDERR und STDOUT auch das System sperren ... Um beides zu bekommen, benutze ich (für die meisten Shell-Umgebungen (bash, csh, etc), die ich verwende ...):

%Vor%     
SirGCal 01.06.2010 18:59
quelle
5

Verwenden Sie fork() und rufen Sie dann system im untergeordneten Prozess auf.

%Vor%     
mob 15.04.2010 16:14
quelle
1

Eine andere Option wäre, einen gearman -Server und einen Arbeitsprozess (oder Prozesse) einzurichten, die das E-Mailing durchführen. Auf diese Weise steuern Sie, wie viel E-Mail gleichzeitig läuft und keine Forking erforderlich ist. Der Client (Ihr Programm) kann dem GearMan-Server eine Task hinzufügen (im Hintergrund, ohne auf ein Ergebnis zu warten, falls dies gewünscht wird), und die Jobs werden in die Warteschlange gestellt, bis der Server den Job an einen verfügbaren Worker übergibt. Es gibt Perl und PHP-APIs für Gearman, also ist es sehr praktisch.

    
runrig 15.04.2010 21:15
quelle
-1

Verwaltet, um das Problem zu lösen. Offenbar war es das, was es davon abhielt zurückzukommen, dass das Aufrufen des Absenders auf diese Weise den stdout nicht löste. Also änderte die Lösung einfach den Systemaufruf zu:

%Vor%

Danke allen für die Hilfe. In der Tat war es beim Lesen der ganzen Geschichte über das "Daemonisieren" eines Prozesses, dass ich die Idee hatte, die stdout zu trennen.

    
Rafael Almeida 15.04.2010 17:05
quelle

Tags und Links