Trabajo en cola de Laravel, ejecútelo antes de su tiempo de ejecución

8

Creé un trabajo de Laravel para ejecutarlo en una fecha y hora específicas (por ejemplo, mañana). Quiero agregar un botón manual que anule el tiempo y ejecute ese trabajo en cola antes de su tiempo de ejecución establecido. Al hacer clic en el botón, se crea una llamada ajax y se envía una identificación de trabajo al servidor. Esto lleva a que el trabajo se ejecute hoy en lugar de mañana.

Podemos volver a intentar manualmente los trabajos fallidos con el siguiente comando: php artisan queue:retry JOBIDHERE

No estoy seguro de qué usar para ejecutar un trabajo en cola.

Puedo obtener la ID del trabajo, pero no sé si es posible ejecutar el trabajo de Laravel antes de su tiempo de ejecución establecido.

Busqué en Google pero no encontré a nadie con ese problema y solución.

Estoy usando Laravel Ver 5.8. Usando Mysql 5.7


Actualizar:

A continuación se muestra la carga útil para el trabajo en cola.

Intenté usar Json Decode y lo decodifiqué, pero no estoy seguro de si puedo actualizar el comando para esa cola para poder actualizar la fecha y la hora de la cola y guardarla nuevamente en el registro de trabajo en cola.

{"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:{}}"}}

Actualización 2:

Cuando deserialicé el comando payload, obtuve la siguiente información.

ingrese la descripción de la imagen aquí

Así que estoy tratando de actualizar esa fecha de retraso, espero que funcione.

Pero a partir de la respuesta de "Julian Stark", es posible que tenga que actualizar el available_at también.

Mi teoría es que cuando se ejecuta la cola, buscará trabajos basados ​​en available_at. Sin embargo, cuando el trabajo se está ejecutando y tiene un retraso, es posible que no se ejecute en ese momento específico. Esta teoría aún no se ha probado.

Actualizaré ambos dateTimes y comprobaré si todo funciona sin problemas.

Código chisporroteante
fuente

Respuestas:

11

En un caso de uso similar, acabo de actualizar el available_attiempo de trabajo , por lo que el queue:listencomando ejecuta el trabajo lo antes posible.

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

No sé si esta es la forma correcta de hacerlo, pero funcionó para mí.

Julian S
fuente
Actualicé mi pregunta con nuevos hallazgos. Por favor revisa eso. Gracias por mencionar sobre el disponible_at.
Código chisporroteante
Probé mi ejemplo en laravel 5.8 sin modificar el payloadretraso y el trabajo se ejecuta, por lo que su teoría mencionada en la Actualización 2 es incorrecta
Julian S
Cambiaría time()a DB::raw('NOW()')solo para estar seguro.
Styx
4

Para lograr esto, todo lo que tiene que hacer es primero decodificar su carga útil, que será

{
   "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:{}}"
   }
}

Cuando haya decodificado su carga útil, verá que el "comando" está serializado, por lo que luego debe deserializar el "comando" .

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

Después de eso, puede actualizar la fecha en el nodo de retraso y, ya sea usando la fecha Carbon o PHP, actualice la fecha según su necesidad. Después de hacer eso, solo necesita serializar el nodo "comando" nuevamente y luego json_encodetoda la carga útil y guardarla.

También deberá seguir la respuesta de @Julian Stark, es decir, modificar el available_attrabajo.

Espero que esto ayude.

Fahad Ali
fuente
1
Ya seguí el mismo proceso y actualicé ambas fechas. Ya trabajando a la perfección.
Código chisporroteante
1

actualizar la hora del trabajo en cola será una mala práctica, en lugar de eso, puede eliminar el trabajo programado y ejecutar la función de despacho ahora.

Furqan Ansari
fuente
1
Eso también puede funcionar. ¿No estoy seguro de por qué el otro método es una mala práctica? Ambos métodos me parecen bien, actualizar la fecha directamente o eliminar los existentes y crear trabajo nuevamente. Pero quería ver cómo podemos actualizar la fecha / hora del trabajo existente.
Código chisporroteante