Run queue:work for Laravel and Lumen in shared hosting

Laravel and Lumen is very popular web development framework. It’s a very powerful tool to build a complete system from a to z. Though these frameworks are written in php it is designed to be run in dedicated server/vps. But still you can run it in your shared hosting.

Today we will learn how to run background queue work for laravel and lumen.

Requirement:

We need to send email asynchronously. So that any http request does not need to be waiting for the email to be sent. Therefore we need to queue the email and execute it from background process. This way we can make sure that our laravel application won’t get stuck.

Laravel .env:

First we need to define the queue driver in our .env file. Laraval supports multiple types of queue mechanism but today we will use a very simple and default one. Open your .env file and change QUEUE_CONNECTION=sync to QUEUE_CONNECTION=driver. Then open your terminal and run:

php artisan queue:table
php artisan migrate

It will create required tables in your database automatically.

Laravel Dispatch job:

Now it time to queue the job. Whenever you need to do the heavy and time consuming task you have to do it in job class like below:

use App\Mail\RecoverPinMail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class MailJob extends Job{
    use InteractsWithQueue, Queueable, SerializesModels;

    protected $details;

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

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle() {
        $email = new RecoverPinMail($this->details);
        Mail::to($this->details['email'])->send($email);
    }
}

Thanks to laravel’s Mailable and Job class. Dispatch will automatically insert the queue in job table in your database.

Cron Job:

We need to run the below command to start the background process so that laravel can keep executing the job simultaneously.

php artisan queue:work

But the problem is if your server gets restarted or your laravel app get crashed, it will stop the process. On the other hand you won’t be able to install Supervisor like library too because shared hosting does not provide you the root user permissions.

At this point we have only one options left and it is Cron job. We can use our cron job with Laravel’s Schedule . Open Kernel.php located in App/Console/. Here we will run command in the schedule.

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('queue:work --daemon')->everyMinute()->withoutOverlapping();
    }
}


Look at the withoutOverlapping(). Actually this start the queue:work process in background and withoutOverlapping() will prevent it from creating multiple instances of same process.

And lastly create your cron job like below:

*/5	*	*	*	*	/usr/local/bin/php /home/username/path_of_artisan schedule:run

Now it will start executing all the job in background process one by one without freezing the laravel application and also it won’t be clogging your server’s memory.