Setup Queue Job for Laravel 8

Software

Last time we configure our Laravel app to send email when an error exception is encountered. Let's enhance it by configuring the email sending into a queue job.

This tutorial teaches how to setup a queue job system in Laravel.

We will use the example from the last blog article to demonstrate.

First, we save the queue job in the database. In your .env.example and .env file, change the QUEUE_CONNECTION into database.

QUEUE_CONNECTION=database

Next, run the command php artisan queue:table to generate the necessary migration file.

Then, run the command php artisan migrate to migrate the database.

We need to create a job for sending the exception email. Run the command php artisan make:job SendExceptionEmail. The SendExceptionEmail.php file will be created in App\Jobs\ folder. In this file, add an $message private variable, set the variable in the constructor and send the email in the handler function. The file should look like this:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mail;
use App\Mail\ExceptionOccurred;

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

    private $message;

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

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $to = explode(',', env('ERROR_REPORTING_EMAIL', ''));
        Mail::to($to)->send(new ExceptionOccurred($this->message));
    }
}

To test if it is working, run the command php artisan queue:work. You will need to make some exception to see it in action.

However, in production, running php artisan queue:work is not the recommended action. The queue worker will stop if you logout from the terminal or if there is some error causing the process being killed. The recommended method is running it using Supervisor.

To run the queue worker using supervisor, first you have to install it by running sudo apt-get install supervisor, assuming you are using Debian based Linux environment.

Then, create a configuration file in the supervisor directory using sudo nano /etc/supervisor/conf.d/laravel-worker.conf. In the Nano editor, fill in the following:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/yourapp/artisan queue:work database --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/html/yourapp/worker.log
stopwaitsecs=3600

In the configuration file, change the path in command and stdout_logfile according to your server.

To save it using Nano editor, use control + o, then control + x to exit.

To start the supervisor for our queue worker, run these command accordingly:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start laravel-worker:*

There you have it. Now, your Laravel app should be sending the exception email using a queue job without obstructing the user experience.