Laravel Notification System with Queue
Published: 2022-06-20 13:10:00

**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
```
and then set the .ENV file with database

```
QUEUE_CONNECTION=database
```
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",
        ];
    }
}

```
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 [](url))

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
```
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](https://laravel.com/docs/9.x/queues#the-queue-work-command)

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****
```

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 
```
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](https://laravel.com/docs/9.x/queues#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
```

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](https://twitter.com/enrico_dev86).