I’m using the Laravel queue through redis to send notifications. But whenever I pass models to the notifications, their properties are outdated when the notification is sent through the queue.
This is basically what I’m doing:
In controller (or somehwere else):
$thing = new Thing(); // Thing is a model in this case. $thing->name = 'Whatever'; $thing->save(); request()->user()->notify(new SomethingHappened($thing))
SomethingHappened.php:
<?php namespace AppNotifications; use AppThing; use IlluminateBusQueueable; use IlluminateContractsQueueShouldQueue; use IlluminateNotificationsMessagesMailMessage; use IlluminateNotificationsNotification; class SomethingHappened extends Notification implements ShouldQueue { use Queueable; public $thing; public function __construct(Thing $thing) { $this->thing = $thing; } public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { dump($this->thing->name); // null return (new MailMessage()) // ... // ... // ... ; } }
Now when I add a delay of a few seconds (i.e. (new SomethingHappened($thing))->delay(now()->addSeconds(5))
), the retrieved model is up-to-date. Also, before I deployed enough queue workers (and they were lagging behind on a filling queue), this issue didn’t exist. Therefore, it appears now that when queue job gets processed really quickly, it doesn’t retrieve the model from the database correctly or the model isn’t saved yet. I have no idea why this could be happening, since the save
call on the model is clearly executed (synchronously) before dispatching the notification, so there should be no way it isn’t saved yet when the job is processed.
I’m running on Kubernetes and using a MySQL database. Everything is on GCP (if this is relevant).
Does anyone have an idea? Adding a delay of a few seconds is not a great solution and shouldn’t be necessary.
Advertisement
Answer
It appears our database was using too much CPU, causing it to switch to the failover regularly. I think this was the cause of the issue. After implementing tweaks reducing the database load, the problem was resolved. A workaround for this issue would be to add a slight delay (as noted in my question).
I’m not sure why this only seemed to affect notifications, and not other queue jobs or requests. If anyone has a more detailed explanation, feel free to post a new answer.