Laravel Notification System with Queue

enrico_dev86

Enrico Bellanti

Posted on June 20, 2022

Laravel Notification System with Queue

Why Laravel Queue?

As i explain in previus posts i really suggest when you are using notification to implement also a queue system to avoid that failed notifications never get delivered.
Reading the queue notification for first time seems to be something complicated to be implemented but it isn't so hard.
I'll try to help you with this tutorial to make it easier as possible.

Let's start
In order to use Queue you need to migrate table jobs with laravel command

php artisan queue:table

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

and then set the .ENV file with database

QUEUE_CONNECTION=database
Enter fullscreen mode Exit fullscreen mode

Let's now create a notification example and see how to implement interface and trait

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\BroadcastMessage;

class RealTimeNotification extends Notification implements ShouldBroadcast
{
    use Queueable;

    public string $message;

    public function __construct(string $message)
    {
        $this->message = $message;
    }

    public function via($notifiable): array
    {
        return ['broadcast'];
    }

    public function toBroadcast($notifiable): BroadcastMessage
    {
        return new BroadcastMessage([
            'message' => "$this->message"
        ]);
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'message' => "$this->message",
        ];
    }
}

Enter fullscreen mode Exit fullscreen mode

with the method toArray we can specify how the notification must be formatted to be saved in the queue. Also this method is used to save the notification in notifications database table (I have already explained this feature in the post Notification System with websocket )

One you add in notification class the interfrace "ShouldBroadcast" and the trait "Queueable" you can automatically send to job table all the notifications and in case they fail you can continue to manage without loosing forever, i will show you forward in this tutorial how to do that.

Artisan queue:work
From now you will have two table in database jobs and failed_jobs ones you trigger a notification it will be delivered firstly on jobs table and managed in queue if one of these fails it will be moved to failed_jobs table avoid to be get lost.

To manage all these processes you need to start the artisan command

php artisan queue:work
Enter fullscreen mode Exit fullscreen mode

after this command you can specify several configurations to be set at most but for this i would suggest to have a look at laravel docs
laravel-queue-doc

The artisan queue:work get one by one your notifications and send them according to your needs.
you have here an example of configs

php artisan queue:work --sleep=3 --tries=3 --backoff=3 --max-time=3600 --max-jobs=5 --stop-when-empty****
Enter fullscreen mode Exit fullscreen mode

As you can see i just set --tries 3, for example, in this way you can make the system tries 3 times to send notification before it get failed and move to failed_jobs table.

Sometimes jobs can fail for a variety of resons, such as an exceeded worker timeout, in these case you can manage these in a different time, you can do that just running the command

php artisan queue:retry 
Enter fullscreen mode Exit fullscreen mode

in this way you just pull back your jobs to the jobs table and make queue:work reprocess for a second time and give it a second chance.

!attention: all these processes are run manually in this tutorial but should be managed by your server, i would suggest to install a supervisor and just add the configuration that laravel provide in its documentation
supervisor configuration

installing supervisor is not so difficult and after that you will have a supervisor.conf file where to add some settings like this

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --backoff=3 --max-time=3600 --max-jobs=5 --stop-when-empty
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
startretries=3
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/worker.log
stderr_logfile=/var/www/html/storage/logs/worker-error.log
stopwaitsecs=3600
Enter fullscreen mode Exit fullscreen mode

Hope this tutorial would be helpful but if i missed something or you have some ideas to refactor please contact me at twitter-personal-link.

💖 💪 🙅 🚩
enrico_dev86
Enrico Bellanti

Posted on June 20, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related