Laravel Notification System with Queue
Enrico Bellanti
Posted on June 20, 2022
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 )
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
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
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.
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
November 30, 2024
November 30, 2024