LaravelPHP

Implement Queue in Laravel 7/8

Laravel gives us a built-in queue system that helps us to run tasks in the background and configure how the system should react in different situations. It allows you to delay a time-consuming task until a later time. By postponing the time-consuming task, you can improve the performance of the Laravel applications.

Step 1: Configure The Queue

Laravel allows the facility to configure queues with several drivers like database, Beanstalkd, Redis, Amazon, IronMQ, etc. Drives are used to store the list of tasks. The selection of the drives is based on the weight of your task list. If it is cumbersome, then you should consider Beanstalkd, Redis, Amazon, IronMQ, etc. But for a low-weight task list, you can use a database drive as well.

Let’s take an example for a better understanding. We will create an email queue using the Laravel Queue and store all the email sending jobs in the database driver.

Command “queue:table” helps you to use the database driver for the queue.

php artisan queue:table

It will create migration files to create database tables that can be used to store jobs and failed jobs. These files contain the table schema of the jobs and failed jobs table. You will find the code below in the jobs migration file and similar (with different schema) for the failed jobs migration file.

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('jobs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('queue')->index();
$table->longText('payload');
$table->unsignedTinyInteger('attempts');
$table->unsignedInteger('reserved_at')->nullable();
$table->unsignedInteger('available_at');
$table->unsignedInteger('created_at');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('jobs');
}

}

Run the “migrate” command once the migration files have been created. 

php artisan migrate

Once the “migrate” command is executed, you will find the “jobs” and “failed_jobs” tables in your database.

After the migration, the next step is updating the environment file to set a queue driver. You can open the “.env” file to set the value like below.

QUEUE_CONNECTION=database

Also, you need to check the config/queue.php file to ensure that the “QUEUE_CONNECTION” environment variable is used in it to set the default driver.

'default' => env('QUEUE_CONNECTION', 'sync')

Then you need to create a Queue Job, and for that, you need to run the “make:job” command like below with class name. In this example, we are using the “MatchSendEmail” class name.

php artisan make:job MatchSendEmail

The command is just like the make:controller command, and it will create a skeleton for use in the “app/Jobs” folder named “MatchSendEmail.php.” The file has just one method, “handle()” in it. We will implement our matching functionality and send email logic, and it will be added in Step 2.

The file contains the code like below:

<?PHP
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

       /**
       * Create a new job instance.
       *
       * @return void
       */
    public function __construct()
  {
               //
   }

       /**
       * Execute the job.
       *
       * @return void
       */
     public function handle()
     {
            //
      }
 }

Note: We can use the Eloquent model directly into the “_construct” method.

Step 2: Create An Email Template And Mailable

To create mailable, use the “make:mail” command with a mailable class name.

php artisan make:mail HelloEmail

Once this command is executed, the “Mail” folder will be created along with the “HelloEmail.php” file in the “app” folder.

<?php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class HelloEmail extends Mailable
{
use Queueable, SerializesModels;

/**
* Create a new message instance.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('view.name');
}
}

Now you need to create a folder called “emails” in the “resources/views” folder and create the file named “hello.blade.php” in the “email” folder. It will contain the simple HTML code below.Once this command is executed, the “Mail” folder will be created along with the “HelloEmail.php” file in the “app” folder.

<h1>Hello,</h1>
<p>Welcome to laravel platform.</p>

Now you need to change the “view.name” text with the newly created email view file name along with the folder name in “HelloEmail.php” like below.

return $this->view('emails.hello');

Also, you need to add the email sending logic in the “handle()” method in the “app/Jobs/MatchSendEmail.php” file. But first, we need to add “Mail” and “HelloMail” namespaces to use it in the logic.

<?php

namespace App\Jobs;

use Mail;
use App\Mail\HelloEmail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$email = new HelloEmail();
Mail::to('test@test.com')->send($email);
}
}

In the “handle()” method, we have used a simple “Mail” facade to send emails using an instance of “HelloMail.” Now the code is ready for testing Laravel Queue.

Step 3: Testing

For testing, you need to create one controller with the logic of dispatching the job, and also you need to create one route to run it. Let’s see how it will look like;
Add the below line in your “routes/web.php” file.

Route::get('send-test-email', 'EmailController@sendEmail');

Add a new controller file called the “EmailController.php” file in the “app/Http/Controllers/” folder. The Code of the file will look like this.

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Jobs\MatchSendEmail;

class EmailController extends Controller
{
public function sendEmail()
{
$emailJob = new MatchSendEmail();
dispatch($emailJob);
}
}

Visit the URL “HTTP:///send-test-email,” and it will add the job in the “jobs” table.

Dispatching/Delaying Jobs

You can use the below commands to dispatch the jobs from the controller methods.

/** Option 1 */
Queue::push(new MatchSendEmail($options));

/** Option 2 */
dispatch(new MatchSendEmail($options));

/** Option 3 */
(new MatchSendEmail($options))->dispatch();

/** Option 4 */
\App\Jobs\MatchSendEmail::dispatch($options);

If you would like to dispatch a job conditionally, you may use the dispatchIf and dispatch unless methods.

MatchSendEmail::dispatchIf($accountActive === true, $options);
MatchSendEmail::dispatchUnless($accountSuspended === false, $options);

Jobs can be dispatched at specific queues also.

MatchSendEmail::dispatch($options)->onQueue('Email');

You can also delay your Jobs to a given time.

MatchSendEmail::dispatch($options)->delay(now()->addMinutes(10));

We can also set tries and timeout properties to the job class, and the queue driver will use these values.

After Dispatching a job, you need to process this queue; for this, you have to start employment by using a straightforward command

php artisan queue:work

You can also specify queue connection, the queue’s priorities, length of time a job can run, sleep duration between two job executions, process all posts, or a single job.

Laravel also provides facilities to deal with failed jobs. You can specify the number of times a job can be attempted before a job will be added in the failed job table using the “–tries=5” (number defines the attempts) command with the “queue:work” command when you run the queue worker. You can also specify the delay time for every effort after the job will be failed using “–delay=5” (number defines the seconds).

For example:

php artisan queue:work –tries=5 –delay=5

Conclusion

Laravel Queue is very easy to implement in your existing or new project. In this blog, I have tried to make it more simple by explaining with an example. I hope it will help. Also, there are so many methods and parameters to fulfill your Laravel Queue-related requirements. Let me know if you have any questions in the comments section.

Shaiv Roy

Hy Myself shaiv roy, I am a passionate blogger and love to share ideas among people, I am having good experience with laravel, vue js, react, flutter and doing website and app development work from last 7 years.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button