Asynchronous treat in Laravel

0

Previous week I got a issue from my friend about how he is getting difficulty in managing tons of record in laravel. On daily basis his laravel application process lot of data and files.About 7000 database insert, updates and deletes and couple of images download and uploaded S3. As it is taking too much time for processing I give him the advice to use the async programming pattern in laravel and he was unaware of such amazing thing in laravel.

So I decided to share this amazing asynchronous feature laravel starting form QUEUE.

What is queue ?

Queues in Laravel are used to make a smooth sailing application cycle by stacking heavy tasks to be handled as jobs and dispatching these jobs when it is asked to or when it does not disrupt the user’s experience.

There is real life example of queue by Chris Nwamba (scotch.io) which I like most

Let’s assume you have a 12 year old kid named Bill and you decide to send him to a store across the road. At the same time Uncle A is asking him to get him some water and Uncle B is requesting a pen from him. That’s not all; his dog Spike wants some food urgently. Bill has to complete all these tasks.

As Bill’s dad/mum, if you let Bill run off to those tasks at once, he might leave some stones un-turned, get heavily exhausted or end up in an ugly mood. The best thing to do is to give him a list of those tasks and let him check them off one after the other according to priority which is obviously better.

This scenario is the concept behind queues and it is good for handling heavy and tasking jobs like social media posting, email sending, heavy logging, etc.

So in laravel you create jobs of your task which you want to be execute asynchrously and dispatch it and add to that particular queue.

Next Question exactly how many queue is possible in laravel or what is the standard of the queues in laravel application.
there is no defined number of queue that can be made in laravel but standard is to make queue as many as possible and assign jobs to multiple queues for code recompilation.

Lets start by a simple example :

  1. To get started with queue you need to set your database credentials in your .env file for me its :
    DB_DATABASE=AsyncProg
    DB_USERNAME=root
    DB_PASSWORD=

    You can set your own database credentials

  2. Next thing is to enable queue in your project you can set it by going into .env file and change your
    QUEUE_DRIVER=sync to QUEUE_DRIVER=database

    laravel support different types of queue driver like beanstalk, redis but for now we will use database

    There is a question is your mind that what QUEUE_DRIVER=sync do ?
    Honestly sync is for immediate response if you want your application to respond to your job after 5 second or 5 minute you cant do this with sync.

  3. First of create a queue table that will hold the job by using artisan command
    php artisan queue:table    // this will create the jobs table 
    php artisan queue:failed_table     //it will hold the failed jobs 
    php artisan migrate

    it will generate the table in your database.

  4. Now create your first job
    php artisan make:job NotifyMe

    The generated class will implement the Illuminate\Contracts\Queue\ShouldQueue interface, indicating to Laravel that the job should be pushed onto the queue to run asynchronously.

    Job classes are very simple, normally containing only a handle method which is called when the job is processed by the queue. To get started, let’s take a look at an example job class. In this example, we’ll pretend we manage a podcast publishing service and need to process the uploaded podcast files before they are published:

    <?php
    namespace App\Jobs;
    use App\Podcast;
    use App\AudioProcessor;
    use Illuminate\Bus\Queueable;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    class NotifyMe implements ShouldQueue
    {
     use InteractsWithQueue, Queueable, SerializesModels;
     protected $notify;
     public function __construct(Podcast $podcast)
     {
     $this->podcast = $podcast;
     }
     public function handle(AudioProcessor $processor)
     {
     // Process uploaded podcast...
     }
    }

    Once you have written your job class, you may dispatch it using the dispatch helper. The only argument you need to pass to the dispatch helper is an instance of the job:

    <?php
    namespace App\Http\Controllers;
    use App\Jobs\NotifyMe;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    class NotificationController extends Controller
    {
     public function store(Request $request)
     {
     dispatch(new NotifyMe($podcast));
     }
    }
  5. Delaying DispatchIf u want to delay your dispatch it can be done by using the delay method in your dispatch instance
    $job = (new NotifyMe($podcast))->delay(Carbon::now()->addMinutes(10));
    dispatch($job);

     

  6. Dispatching To A Particular Queue
    $job = (new NotifyMe($podcast))->onQueue('processing');
    dispatch($job);
  7. Queue PrioritiesYou can prioritize how your queues are processed. For example, in your config/queue.php you may set the default queue for your redis connection to low. However, occasionally you may wish to push a job to a high priority queue like so:
    dispatch((new Job)->onQueue('high'));

    If your job cancel due to some reason then what will happen ??
    When creating the queue job table we also created the failed_jobs table for holding the failed jobs now you have ability to delete or retry with failed jobs

  8. Failed jobs Delete:
    You just need to make failed function in your job class for failed jobs :

    public function failed(Exception $exception)
     {
     // Send user notification of failure, etc...
     }

     

  9. Retrying with failed jobsTo view all of your failed jobs that have been inserted into your failed_jobs database table, you may use the queue:failed Artisan command:php artisan queue:failed
    The queue:failed command will list the job ID, connection, queue, and failure time. The job ID may be used to retry the failed job. For instance, to retry a failed job that has an ID of 5, issue the following command:

    php artisan queue:retry 5

    To retry all of your failed jobs, execute the queue:retry command and pass all as the ID:

    php artisan queue:retry all

    If you would like to delete a failed job, you may use the queue:forget command:

    php artisan queue:forget 5

    To delete all of your failed jobs, you may use the queue:flush command:

    php artisan queue:flush

    You have seen by using queue and jobs async programming is so easy in laravel, In other framework async programming is not so easy but in laravel it is so easy to understand the async programming pattern in laravel by far laravel is the most easiest framework to work with.

Leave A Reply

Your email address will not be published.