Laravel queue - how to use & how they work

Post Details

Laravel queue - how to use & how they work

Laravel queue - how to use & how they work

Queue is a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the queue will be the first one to be removed i.e. once a new element is added, all elements that were added before have to be removed before the new element can be removed.


In Laravel one of the most interesting feature I found is queue, it allows you to defer the processing of time consuming task which can drastically speed up web requests to your application. Though if you have a very simple application you may not even need to touch this functionality but like always what’s wrong in learning something new!

Laravel queue process-flow


First you need to configure the connection for the queue driver(s). In

config/queue.php

you will find connection configurations for each of the queue drivers that are included with the framework: database, Beanstalkd, Amazon SQS, Redis. Setting this connections up will allow you to set different queues to different connections or may be you can simply use just one connection throughout your app for the queues, it depends upon the complexity of your app. Sounds awkward? It’s completely natural for now but won’t be after you go this article through.


If you dispatch a job without explicitly defining which queue it should be dispatched to, the job will be placed on the queue that is defined in the queue attribute of the connection configuration:


**we call a queued task as a job which Is actually a class, we push this jobs into queue

 
// This job is sent to the default queue...
dispatch(new Job);

// This job is sent to the "emails" queue...
dispatch((new Job)->onQueue('emails'));


database driver is the slowest but for testing we can use it for now, there is an artisan command for creating required table migrations :

 
php artisan queue:table
php artisan migrate


Laravel has queue workers they just process this queued tasks/jobs, worker allows you to specify which queues it should process by priority. You can prioritize your multiple jobs as high, low, default etc. & the jobs will be executed by the workers as per the set priority. If you don’t specify a job’s priority then it will be assumed as default job by the workers.


There is actually no naming convention for prioritizing the jobs like high or low cause its upto you to set their priority. In cli if you run this:

 
 php artisan queue:work --queue=default,high

Now priority of the default jobs are higher than the high flagged jobs i.e. the default jobs will be processed before the high ones.


1. Create Job Classes:

As I told before all the jobs / tasks are classes and this classes can be found in app/Jobs path, this artisan command can create you new job class

 
 php artisan make:job ClassName

or if you choose to create the class without using artisan cli make sure to use

Illuminate\Contracts\Queue\ShouldQueue

as this interface tells larvael that the job should be pushed onto the queue to run behind the scene.


In the job class there basically should be one handle method which is called when the job is processed. If you’ve generated the class by artisan command then you’ll find the handle method is written already for you inside the class


2. A very basic example:

We’ll use a basic database table that consist only a ip_address field & lets assume corresponding eloquent model is Formtable

 
namespace App\Jobs;

use App\Formtable;

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

use Illuminate\Http\Request;

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

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

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $frm_data = new Formtable();
        $frm_data ->ip_address = $this->form_data;
        $frm_data ->save();
    }
}


**when a new job is passed onto a queue the job is first serialized, you can check it after dispatching a job in the jobs table

so make sure your job consist simple data otherwise for raw data like image content pass it through base64_encode


To dispatch the job we need a controller

 
namespace App\Http\Controllers;
use App\Jobs\EntryForm;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class TestJobController extends Controller
{
    public function store(Request $request)
    {
        dispatch(new EntryForm ($request));
        return response()->json(‘job dispatched to default queue’);
    }
}


Now set proper route for the store method of the

TestJobController

and access the route and you’ve successfully dispatched your job. To check goto the jobs table now you can see a new entry in the default queue is placed and stored in the table


This job will be processed by the laravel queue workers & for that use the artisan command

 
php artisan queue:work


now as long as the terminal or command prompt is open the queue workers are waiting for any dispatched task to process, now as we already have a dispatched job you’ll see the job will be processed instantly by the workers and now check the new table you just created to store ip_address from the request you can find a new entry.


When should I use queue?

This was just a basic example but now you can understand where you can take the advantage of the queue to speed up your application. Like in an e-commerce website after online payment suppose you have to store necessary data from the webhook to your application in the mean time you have to send sms and email in both way one for the admin one for the customer and maybe some other analytical entries you want your app to catch so as you can see this is a very lengthy process which can slow your app’s performance but with the help of queue you can dispatch as many job as you want and can prioritize them the way you want them to be executed.


To process the jobs should I leave the terminal open all the times?

This is a very common question and the answer is of course not, you have two choices to make the workers run all the time behind the scene. 1. Use supervisor and create a .conf file and set the artisan command 2. or you can use Laravel Task Scheduling to run the artisan queue:work command with necessary priority setup in every minute or maybe five minutes

Leave a comment

Search
~ By Lord Buddha

Peace comes from within. Do not seek it without.