Creating and running jobs and worker queues in Laravel 10

Laravel jobs and worker queues are for doing tasks that are too long or intensive to do during a typical web request such as processing or parsing an uploaded file.

These jobs can then be processed through a queue in the background without slowing down your web application and its users.

The driver

There are several choices for what driver you want to use for your queues. For the straightforward database driver, in the .env file set as:

QUEUE_CONNECTION=database

Then pull the jobs queue table migration and migrate it.

php artisan queue:table
php artisan migrate

This creates the table called jobs.

Creating a job

Use artisan to create the job ProcessUpload

php artisan make:job ProcessUpload

This will create /app/jobs/ProcessUpload.php

In this file the Media resource gets passed in with the constructor and the handle() function is what gets called when it is run from the worker queue.

namespace App\Jobs;

use App\Models\Media;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class ProcessUpload implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        public Media $media,
    )
    {
    }

    public function handle(): void
    {
        //Process upload functions in here...
        Log::debug("Called ProcessUpload job for {$media->id}");
    }
    
}

Dispatching the job

Dispatching the job means sending it to the queue for it to be eventually called

//Example upload
$media = new Media();
$media->original_filename = $file->getClientOriginalName();
$media->type = $file->getClientMimeType();
$media->save();

$file = $file->storeAs("uploads", "{$media->id}.{$file->extension()}", 'private'); 

//Send to the queue
ProcessUpload::dispatch($media);//The App\Jobs\ProcessUpload file

You can also define a queue type:

ProcessUpload::dispatch($media)->onQueue('uploads');

This can also be done in the job’s constructor with:

$this->onQueue('uploads');

There can also be conditions for the job to dispatch:

ProcessUpload::dispatchIf($user_verified, $media);
 
ProcessUpload::dispatchUnless($user_banned, $media);

The job can also be delayed and not available in the worker queue:

ProcessUpload::dispatch($media)->delay(now()->addMinutes(20));

Dispatch and run the job immediately, skipping the queue:

ProcessUpload::dispatchSync($media);

Running the queue

Start the queue worker and process any jobs in it with this artisan command:

php artisan queue:work

This will run until you stop it or close the terminal.

You can also keep the queue worker continuously listening for new jobs to be published. This is said to not be efficient.

php artisan queue:listen

Process just one job:

php artisan queue:work --once

Process a maximum of 20 jobs:

php artisan queue:work --max-jobs=20

Process all jobs and exit:

php artisan queue:work --stop-when-empty

Process jobs for an 1 hour and exit:

php artisan queue:work --max-time=3600