0

I have a Laravel Notification class that sends email to a group of recipients. Without ShouldQueue, this works perfectly using a $request object that I pass in to the constructor of the Notification class:

class MassNotification extends Notification {
     public function __construct($request)
     {
        $this->request = $request;
     }

This comes from the controller like this:

\Notification::send($emps, new MassNotification($request));

I need to queue these emails up to free the user to move on, so I implement ShouldQueue:

class MassNotification extends Notification implements ShouldQueue {}

At this point, the messages fail with the following error:

Serialization of 'Closure' is not allowed

Doing a little SO search, and here tells me this is due to not being able to serialize the $request object. OK, I follow the advice and change the constructor to pull in the array of data that I need:

public function __construct($request)
 {
    $this->request = $request->all();
 }

I change the code in my toMail() to meet the array notation vs object notation, and it fails every time before it gets to the toMail() method with:

Call to a member function has() on null at /vagrant/app/Notifications/MassNotification.php:44

However, this points to my code - but I don't have has() in my code anymore, it never gets to that line - it fails in Illuminate\\Notifications\\Channels\\MailChannel->send() I believe.

I've tried to take the request array out completely and just use variables (e.g. $this->message, $this->subject, etc), but Notification seems to be looking for an object to use has() upon every time.

I'm guessing I'm missing something very basic, because it can't be broken both ways. I would be grateful for any light on this.

Watercayman
  • 7,970
  • 10
  • 31
  • 49
  • what is line 44 of `MassNotification`? were you at some point calling `$request->has(...)` ? if you didn't restart the queue workers they are still using the code at the time they were started – lagbox Dec 22 '19 at 17:26
  • Line 44 is `if(array_key_exists('link_button', $this->request))`. But, the code breaks *before* it gets to that method. If I try to `dd($something)` it breaks before seeing the dump. I **was** calling `$request->has()` when I was originally using the object `$request`, but the error is the same even if I remove ALL code from the `toMail()` method after changing to `$request->all()`. I'm damned if I do, damned if i don't. – Watercayman Dec 22 '19 at 17:31
  • if you didn't restart the workers, they are still using the original code ... so the payloads are different, but the code for the job is still the same – lagbox Dec 22 '19 at 17:31
  • 1
    Man - it had to be something ridiculously simple like that. Thanks a million for pointing this out @lagbox. Please - add this as an answer for anyone else in future, and I will accept. – Watercayman Dec 22 '19 at 17:35

1 Answers1

1

If you are running into a situation where it looks like your code updates aren't in place and your errors aren't matching up to your current code and you are using Queued jobs then the workers need to be restarted. The queue workers are running in a daemon mode and keep the booted state of the application in memory. They will not see the changes you make to the code.

"Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers." - Laravel 6.x Docs - Queues - Running The Queue Worker

lagbox
  • 48,571
  • 8
  • 72
  • 83
  • Man if I could upvote this again I would. Stupid problem bit me in the backside again for 10 minutes before I remembered this. I think I will add `php artisan queue:restart` to composer post update. Thanks again a few months later! – Watercayman Mar 26 '20 at 22:50