I upgrade from Laravel 4.1
to 5.4
. Queue migration is difficult.
Firstly, I commented out iron
route from routes:
Route::post('queue/receive', function()
{
return Queue::marshal();
});
Then, I configured database driver and migrated jobs
table:
php artisan queue:table
php artisan migrate
I changed Mail::queue
codes to the Mailables like this:
Mail::to('person@gmail.com')->send(new ForgotPassword($user->first_name));
I succeeded to send mails synchronously (without queue). Then, I switched to queue:
Mail::to('person@gmail.com')->queue(new ForgotPassword($user->first_name));
And lastly, I run this command from console:
php artisan queue:listen
When a Mail::to
line is executed, a row is inserted to the Jobs
table but mail isn't sent. How can I solve this problem?
Note: ForgotPassword
is a Mailable
class (should be a Job
class?).
You may have to edit the existing .env file on the project folder on your machine. Look for the .env file, open it through sublime text and edit it.
Edit with the email id and password with which you are going to send the mails.
The main difference between the synchronous
send()
and the asynchronousqueue()
, as far as yourForgotPassword
object is concerned, is that when you queue the object for sending, it must be serialized to be sent to the queue, and unserialized when the queue worker processes it.Since
send()
works fine, but an error is occurring withqueue()
, and we can see that the queued job is fired and being attempted to be processed, there is most likely an error in the serialization/unserialization.Your
ForgotPassword
class is probably using theSerializesModels
trait, since that is how the artisan command generates a new mailable object. This trait defines__sleep()
and__wakeup()
methods, which modify how serialization and unserialization work.When the
__sleep
method is implemented, PHP will only serialize the variables that are returned by the__sleep
method. In this case, the implementation provided by theSerializesModels
trait uses Reflection to go through the properties defined on the class to provide a special way to serialize Eloquent models and collections.Because of this, this means that any variables on your
ForgotPassword
class that are not specifically defined as a property on the class will not get serialized, and it will not be available when the queued job is processed and the class is unserialized. This is the most likely reason for your issue. When your job is being attempted, your unserialized mailable instance doesn't have the data it needs, and is failing.There are two ways to resolve this. First, if your
ForgotPassword
does not actually need to serialize any models, you can remove theSerializedModels
trait. This will remove the__sleep()
definition from the class, and then all variables assigned on the class, not just those actually defined, will be serialized, and will also be available when the class is unserialized.The second option, which is more appropriate and more explicit, is to actually define the properties you need on your
ForgotPassword
class.If you define the properties on your class, you could leave the
SerializesModels
trait on your class. However, if you aren't actually serializing models, I'd go ahead and remove it. No need for the extra serialization overhead if you don't need it.You can send Mail using laravel queue, see the example,
Define Job
Call the job
.env
Note