How to create laravel background job?
Let's first understand the concept of background jobs. Say that you have a blog website where you have millions of subscribers. You have to notify your subscribers each time a new post has been published.
Sending batch emails to that much subcribers might take a long time however when you publish a new post you do not want to wait but you do want to notify your subscribers.
You can make use of laravel background jobs basically it runs in the background without holding http request. By default when you install laravel framework and look at your .env file you will see following line:
QUEUE_DRIVER=sync
Above line means that we are using sync driver which holds your http request until your job is done. However to run background job we will use database driver.
Setting up laravel supervisor
In order to keep laravel background jobs running we will use supervisor linux based monitoring tool. Checkout below link to set it up on your linux machine.
How to setup laravel supervisor?
How to enable database queue worker in laravel?
Once you have supervisor setup with laravel task you can run following command to migrate database queue driver related tables:
# create database migration script
php artisan queue:table
# run our new migration
php artisan migrate
Once we imported necessary tables enable database driver in your .env file as shown below:
QUEUE_DRIVER=database
Now, our background job will run through database and you can monitor failed jobs in jobs table.
Creating a new background job
Let's create a sample job class that deals with sending batch emails when a new post has been published on our blog.
Run following command using your terminal to create a new job:
php artisan make:job SendEmails
When you run above command it will create a new job class in app/Jobs/SendEmails.php. Let's open this file and add some additional logic to it.
In our constructor we will take a newly created post object and using this new object we will notify our users about this new post via email.
<?php
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class SendEmails implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $post = null;
/**
* SendEmails constructor.
* @param Post $post
*/
public function __construct(Post $post)
{
$this->post = $post;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$subscribers = User::all()->toArray();
foreach ($subscribers as $subscriber)
{
\Mail::send('emails.blog', ['post' => $this->post, 'subscriber' => $subscriber], function ($m) use($subscriber) {
$m->to($subscriber['email'], $subscriber['name']);
$m->subject('A new article has been published.');
});
}
}
}
Once, we added logic to our job class in our controller class where we create our new post we will add following code to dispatch a new job that we created.
<?php
namespace App\Http\Controllers;
use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller
{
/**
* Store a new podcast.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// Create post here ..
SendEmails::dispatch($post);
}
}
What steps we followed to run background job?
In this tutorial we followed following steps to successfully run background jobs using laravel queues:
- we created a new job
- added business logic to it
- dispatched this new job from our controller class
- changed driver to databse in .env file
- setup supervisor to run background jobs
- start the supervisor worker
I hope you liked this tutorial if you have any issues with this tutorial please have some comments below and I will update this tutorial to match your requirements.