Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

wagnerdracha's avatar

How can I cancel/stop a running job

Hi, how are you?

I am new here, so thanks in advance!

So, when a user create a new register, my application save the data on mysql and dispatch a job.

However, a user can cancel/stop this job, becase it's not necessary any more.

So, how can I cancel/stop a running job on Laravel?

1 like
6 replies
danwah's avatar

I've needed to stop or delete a job myself in the past and kinda went down a rabbit hole trying to see if it was possible, but i think there's a better way to think about it. Instead of trying to cancel or stop the job from running. Just make the job do nothing if a certain condition is met.

In your example with a "Register" add a new column to your register table called status where you can set the status to be active or cancelled etc.

If a user decides the register isn't needed anymore. Let them delete / cancel it, but then update the status column to be = cancelled.

And then in your job code have a check for the status. If its set to cancelled, just return early.

public function handle()
{
    // First check if register has been cancelled
    if ($this->register->status == 'cancelled') {
        return false;
    }

    // Continue with whatever your job does.
    $this->register->user->notify();

So the job still runs, but it never executes any of the logic inside of it if the cancelled condition is met. This to me is a much simpler way of "cancelling" a job.

I got this idea from the https://learn-laravel-queues.com/ Ebook by Mohamed Said - Ex Laravel employee. Its well worth the money if you want to level up your queue knowledge.

Hope this helps you out!

wagnerdracha's avatar

Thanks for your ansewer, but I think it is don't helped-me.

Another exemple: I create a new report register on database for future search and after this I will dispatch a job to execute this report, but it will consume so much time to execute and I think about this when the report is executing. So I want cancel/stop.

Code exemple:

  • Controller:
  • JOB:
wagnerdracha's avatar

"""<?php namespace App\Http\Controllers; ......

Class MyReport extends Controller { public function newReport(Request $request) { $validator = \Validator::make([...], $this->validation(), $this->validationMessage());

    if(!$validator->fails())
    {
        try {
			DB::beginTransaction();
			//Save report
            $ns = ReportExampleModel::create([
						......
            ]);

			//Execute job
            dispatch(new \App\Jobs\ReportExampleJob([
							.......,
							'report' => $ns
            ]));

            return $this->responseReturn(array(
                'return'     => 'success', 
                'type'       => 'created', 
                'title'     => '...!', 
                'message'    => '.......!',
            ), 200);
        }catch(\Exception $e){
            DB::rollback();

            return $this->responseReturn(array(
                'return'         => 'error', 
                'type'           => 'not_created', 
                'title'         => 'Ops, deu ruim!', 
                'message'        => '.....!',
                'system_message' => $e->getMessage()
            ), 500);
        }
    }

    return $this->responseReturn(array(
        'return'  => 'error', 
        'type'    => 'not_created', 
        'titulo'  => 'Ops, deu ruim!', 
        'message' => '...',
        'validate_error' => $validator->messages()
    ), 422);
}

} ...... ?>"""

wagnerdracha's avatar

class ReportExampleJobimplements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

private $data;

public $cancellable = true;

public $tries = 3;

//public $timeout = 60;

/**
 * Create a new job instance.
 */
public function __construct($data)
{
    $this->data= $data;
}

/**
 * Execute the job.
 */
public function handle(): void
{
    set_time_limit(0);

    try {
        DB::beginTransaction();

        //Salvar o ID do job
        $this->data['report']->jobs_id = $this->job->getJobId();
        $this->data['report']->save();

        $this->dados['result'] = shell_exec('report_program.exe '  . $this->data['filters']);

        $this->dados['report']->result = $this->dados['result'];
        $this->dados['report']->executed = 1; 		//1 - true
        $this->dados['report']->save();

        DB::commit();
    }catch(\Exception $e){
        DB::rollback();

        $this->dados['report']->executed  = 2; 				//2 - fail
        $this->dados['report']->save();
    }
}

.....

Snapey's avatar

You cannot cancel a job unless it is listening if it needs to be cancelled.

If its waiting for a long SQL query then its not even in control any more - its waiting for the database server to reply.

Better if your attention was directed towards making that report quicker.

1 like
wagnerdracha's avatar

Hello everyone. So I winned this challenge. So, when I call the method that will cancel the job, I verify if the job is running or not. To verify what job is that report, when I create a new report I get the id and pass to the ReportExemploJob as a parameter. The parameter is saved on payload column, where I will search later. So, when I will cancel the job, I search for the job that has report:id on the payload. So, if the job isn't running, I delet it. But if the job is running, on the job I get the job id and save on job_id report column. After that, I cancel the service (running queue:work), get the job_id on the report table and delete the job and, after that I start the job again.

Please or to participate in this conversation.