Cómo Cancelar o Detener un Job en Laravel

Antes de continuar con este tutorial o solución, debemos mencionar que esta solución funciona únicamente para jobs almacenados en la base de datos, más no para queues alojadas en otros servicios como redis.

Por lo que, si haces uso de la base de datos para alojar tus jobs lo que debes hacer para cancelar o detener un job es obtener el id del job y luego eliminarlo o aplazar la ejecución directamente en la base de datos.

Si no sabes como obtener el id te recomiendo leer ¿Cómo obtener el id de un job en laravel?.

Detener o Cancelar un Job

Si lo que quieres es detener un job para posteriormente volver a ejecutarlo, deberás cambiar el tiempo de ejecución en segundos (available_at) de la siguiente manera.

<?php namespace App\Services; use Carbon\Carbon; use Illuminate\Support\Facades\DB; class JobService { ... public int $cancel_years = 50; public function update_available_at(int $job_id, $callback_available_at) { $jobs_table = DB::table('jobs'); $job = $jobs_table->where('id', $job_id)->first(); $available_at = Carbon::createFromTimestamp($job->available_at); $jobs_table ->where('id', $job_id) ->update(['available_at' =>$callback_available_at($available_at)->timestamp]); } public function cancel(int $job_id) { $this->update_available_at($job_id, function ($available_at) { return $available_at->addYears($cancel_years); }); } public function resume(int $job_id) { $this->update_available_at($job_id, function ($available_at) { return $available_at->subYears($cancel_years); }); } }
Servicio para Cancelar o Resumir un Job

Esto hará que el job no se ejecute hasta en 50 años, simulando que el job se ha cancelado o detenido de manera que volviendo a cambiar la variable a una fecha actual en segundos, este "volvería a estar disponible" para su ejecución.

Como puedes ver, no estamos cancelando el job ya que esto no es posible actualmente en Laravel pero estamos prolongando el tiempo de ejecución a 50 años, por lo que el job no se ejecutará hasta ese momento.

Eliminar un Job

Por otro lado, si lo que quieres es eliminar el job, entonces deberás eliminarlo directamente de la base de datos usando una query o el query builder de laravel de la siguiente manera.

<?php namespace App\Services; use Illuminate\Support\Facades\DB; class JobService { ... public function delete(int $job_id) { DB::table('jobs')->where('id', $job_id)->delete(); } }
Servicio para Eliminar un Job

Sugerencias

Si lo que quieres es tener un mejor control del job, te recomiendo guardar el ID en una columna de tu tabla o relacionarlos a un modelo mediante una relación belongsTo o belongsToMany.