Laravel Queued Job, führen Sie ihn vor seiner Ausführungszeit aus

8

Ich habe einen Laravel-Job erstellt, der an einem bestimmten Datum und zu einer bestimmten Uhrzeit (z. B. morgen) ausgeführt werden soll. Ich möchte eine manuelle Schaltfläche hinzufügen, die die Zeit überschreibt und den in der Warteschlange befindlichen Job vor der festgelegten Ausführungszeit ausführt. Durch Klicken auf die Schaltfläche wird ein Ajax-Aufruf erstellt und eine Job-ID an den Server gesendet. Dies führt dann dazu, dass der Auftrag heute statt morgen ausgeführt wird.

Wir können fehlgeschlagene Jobs mit dem folgenden Befehl manuell wiederholen: php artisan queue:retry JOBIDHERE

Ich bin nicht sicher, was ich zum Ausführen eines Jobs in der Warteschlange verwenden soll.

Ich kann die Job-ID abrufen, weiß aber nicht, ob es möglich ist, den Laravel-Job vor der festgelegten Ausführungszeit auszuführen.

Ich habe bei Google gesucht, aber niemanden mit einem solchen Problem und einer solchen Lösung gefunden.

Ich benutze Laravel Ver 5.8. Verwenden von MySQL 5.7


Aktualisieren:

Im Folgenden finden Sie die Nutzdaten für den Job in der Warteschlange.

Ich habe versucht, Json Decode zu verwenden und habe es dekodiert, bin mir jedoch nicht sicher, ob ich den Befehl für diese Warteschlange aktualisieren kann, damit ich Datum und Uhrzeit für die Warteschlange aktualisieren und im Jobdatensatz in der Warteschlange speichern kann.

{"displayName":"App\\Jobs\\Payway\\UpdateCustomerInvestment","job":"Illuminate\\Queue\\CallQueuedHandler@call","maxTries":null,"delay":null,"timeout":null,"timeoutAt":null,"data":{"commandName":"App\\Jobs\\Payway\\UpdateCustomerInvestment","command":"O:40:\"App\\Jobs\\Payway\\UpdateCustomerInvestment\":17:{s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000transactionType\";s:7:\"payment\";s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000principalAmount\";d:9999;s:56:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000customerNumber\";s:4:\"BR-2\";s:50:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000currency\";s:3:\"aud\";s:58:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000singleUseTokenID\";N;s:55:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000payway_helper\";O:29:\"App\\Http\\Helpers\\PaywayHelper\":0:{}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000impodenceKey\";s:36:\"afedfc34-d08e-4831-a4aa-29de930d6b98\";s:49:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000headers\";a:0:{}s:60:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000localInvestmentObj\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:33:\"App\\Models\\Investment\\Investments\";s:2:\"id\";i:374;s:9:\"relations\";a:2:{i:0;s:8:\"investor\";i:1;s:13:\"investor.user\";}s:10:\"connection\";s:5:\"mysql\";}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000paywayTotals\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:38:\"App\\Models\\Banking\\Payway\\PaywayTotals\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:5:\"mysql\";}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";s:6:\"payway\";s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";O:13:\"Carbon\\Carbon\":3:{s:4:\"date\";s:26:\"2019-11-12 23:35:22.752222\";s:13:\"timezone_type\";i:3;s:8:\"timezone\";s:16:\"Australia\/Sydney\";}s:7:\"chained\";a:0:{}}"}}

Update 2:

Als ich den Payload-Befehl deserialisierte, erhielt ich die folgenden Informationen.

Geben Sie hier die Bildbeschreibung ein

Ich versuche also, dieses Verzögerungsdatum zu aktualisieren, hoffentlich funktioniert es.

Aber nach der Antwort von "Julian Stark" muss ich möglicherweise auch "available_at" aktualisieren.

Meine Theorie ist, wenn die Warteschlange ausgeführt wird, wird nach Jobs gesucht, die auf basieren available_at. Wenn der Job jedoch ausgeführt wird und eine Verzögerung aufweist, wird er möglicherweise zu diesem bestimmten Zeitpunkt nicht ausgeführt. Diese Theorie muss noch getestet werden.

Ich werde diese beiden dateTimes aktualisieren und prüfen, ob alles reibungslos funktioniert.

Brutzelnder Code
quelle

Antworten:

11

In einem ähnlichen Anwendungsfall habe ich gerade die Jobzeit aktualisiert available_at, damit der queue:listenBefehl den Job so schnell wie möglich ausführt.

DB::table('jobs')->where('id', $jobId)->update(['available_at' => time()]);

Ich weiß nicht, ob dies der richtige Weg ist, aber es hat bei mir funktioniert

Julian S.
quelle
Meine Frage wurde mit neuen Erkenntnissen aktualisiert. Bitte überprüfen Sie diese. Vielen Dank für die Erwähnung des verfügbaren_at.
Sizzling Code
Ich habe mein Beispiel in Laravel 5.8 getestet, ohne die payloadVerzögerung zu ändern, und der Job wird ausgeführt. Daher ist Ihre in Update 2 erwähnte Theorie falsch
Julian S
Ich würde zu wechseln time(), DB::raw('NOW()')nur um sicherzugehen.
Styx
4

Um dies zu erreichen, müssen Sie zunächst nur Ihre Nutzlast dekodieren

{
   "displayName":"App\\Jobs\\Payway\\UpdateCustomerInvestment",
   "job":"Illuminate\\Queue\\CallQueuedHandler@call",
   "maxTries":null,
   "delay":null,
   "timeout":null,
   "timeoutAt":null,
   "data":{
      "commandName":"App\\Jobs\\Payway\\UpdateCustomerInvestment",
      "command":"O:40:\"App\\Jobs\\Payway\\UpdateCustomerInvestment\":17:{s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000transactionType\";s:7:\"payment\";s:57:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000principalAmount\";d:9999;s:56:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000customerNumber\";s:4:\"BR-2\";s:50:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000currency\";s:3:\"aud\";s:58:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000singleUseTokenID\";N;s:55:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000payway_helper\";O:29:\"App\\Http\\Helpers\\PaywayHelper\":0:{}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000impodenceKey\";s:36:\"afedfc34-d08e-4831-a4aa-29de930d6b98\";s:49:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000headers\";a:0:{}s:60:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000localInvestmentObj\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:33:\"App\\Models\\Investment\\Investments\";s:2:\"id\";i:374;s:9:\"relations\";a:2:{i:0;s:8:\"investor\";i:1;s:13:\"investor.user\";}s:10:\"connection\";s:5:\"mysql\";}s:54:\"\u0000App\\Jobs\\Payway\\UpdateCustomerInvestment\u0000paywayTotals\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:38:\"App\\Models\\Banking\\Payway\\PaywayTotals\";s:2:\"id\";i:1;s:9:\"relations\";a:0:{}s:10:\"connection\";s:5:\"mysql\";}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";s:6:\"payway\";s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";O:13:\"Carbon\\Carbon\":3:{s:4:\"date\";s:26:\"2019-11-12 23:35:22.752222\";s:13:\"timezone_type\";i:3;s:8:\"timezone\";s:16:\"Australia\/Sydney\";}s:7:\"chained\";a:0:{}}"
   }
}

Wenn Sie Ihre Nutzdaten dekodiert haben, wird der "Befehl" serialisiert. Als Nächstes müssen Sie den "Befehl" unserialisieren .

[delay] => Array
        (
            [date] => 2019-11-12 23:35:22.752222
            [timezone_type] => 3
            [timezone] => Australia/Sydney
        )

Danach können Sie das Datum unter dem Verzögerungsknoten aktualisieren und entweder mithilfe des Carbon- oder PHP-Datums das Datum gemäß Ihren Anforderungen aktualisieren. Danach müssen Sie nur noch den "Befehl" -Knoten und dann json_encodedie gesamte Nutzlast serialisieren und speichern.

Sie müssen auch die Antwort von @Julian Stark befolgen, dh den available_atJob ändern .

Ich hoffe das hilft.

Fahad Ali
quelle
1
Ich habe den gleichen Prozess bereits befolgt und beide Daten aktualisiert. Funktioniert bereits einwandfrei.
Sizzling Code
1

Das Aktualisieren der Zeit des in die Warteschlange gestellten Jobs ist die schlechte Praxis. Stattdessen können Sie den geplanten Job leeren und die Versandfunktion jetzt ausführen.

Furqan Ansari
quelle
1
Das kann auch funktionieren. Du bist mir nicht sicher, warum die andere Methode eine schlechte Praxis ist? Beide Methoden scheinen mir in Ordnung zu sein, das Datum direkt zu aktualisieren oder vorhandene zu löschen und erneut einen Job zu erstellen. Aber ich wollte sehen, wie wir das Datum und die Uhrzeit des bestehenden Jobs aktualisieren können.
Sizzling Code