gmanish's avatar

Queues Working Without Running `queue:listen`

I just stated using madrill to send welcome emails to just registering users. I followed the official docs. Needless to say, setting everything up, was a cinch, really. Once I verified everything was working as expected, I decided to implement a job for sending the emails.

That too was a breeze. I'm using database driver and trying this in my homestead box. Here's what my Job's handle method looks like:

public function handle(Mailer $mailer)
{
    $mailer->send(
        'emails.welcome', [
            'user' => $this->user
        ],
        function($message){
            $message->to($this->user->email, $this->user->name)
                    ->from('123@abc.com', 'Welcome')
                    ->subject('Welcome');

            var_dump(sprintf(
                "Sent Welcome Email to: %s (%s)",
                $this->user->name,
                $this->user->email
            ));
        }
    );
}

This is also working as expected. I receive the welcome email in seconds. What I don't understand is, it seems to be working even if I do not run php artisan queue:listen on my homestead box.

I've created the necessary database tables, using:

queue:table
php artisan queue:failed-table

If I run php artisan queue:listen and watch the terminal, the mail arrives, but the message I'm trying to print from the handle function using var_dump never shows up in the console:

var_dump(sprintf(
    "Sent Welcome Email to: %s (%s)",
    $this->user->name,
    $this->user->email
));

Also, I do not see any entries in the jobs and failed_jobs table in my database.

Could someone shed a light on this please. I guess there's something crucial I'm missing.

0 likes
7 replies
donkfather's avatar

it shouldn.t work without having a terminal to listen on the queue ?.. i mean.. that.s my problem .. it doesn.t work if i don.t artisan queue:listen

jekinney's avatar

Keep in mind using mandrill's API it queues the email for you. You send the request and your respond should be 202 and success. This shows they recieved the data and is processing the request.

In short you don't really need to queue the mail being sent. In effect your queuing it twice.

Also is your driver set in conf or env? And using ShouldBeQueued trait? By default queues are sync which doesn't queue at all.

StormShadow's avatar

@gmanish is 'database' in your .env for QUEUE_DRIVER? If so that's weird ... perhaps Laravel defaults to sync driver for local dev? Sorry haven't looked into this yet.

gmanish's avatar

@StormShadow That was the problem. The QUEUE_DRIVER in my .env was set to sync. I fixed that and now if I run queue:listen, I do see the message I'm var_dumping from my job. Also, I see "volatile" records in my jobs table. However, I now get two emails.

@jekinney Please see above note. Perhaps, you are right (messages are being queued twice), and we do not need to queue madrilll messages. Could you please elaborate if that would work in a production server?

The docs seem to suggest we need to use a service like beanstalkd in production servers for running queues.

StormShadow's avatar

@gmanish Good that you got it sorted. I'm using beanstalkd on a forge server for queues, works great and all my mails are queued with Mail::queue to Mandrill

jekinney's avatar

@gmanish I think I might have campaign monitor and mandrill confused. I know for a 100% fact campaign monitor queue the email. I don't have time to look at mandrill's API docs to verify.

gmanish's avatar

@jekinney No worries. Thanks a bunch.

I got everything to work flawlessly. As it turns out mandrill api has it's own job, so we don't need to implement a separate job for sending emails. We just need to use Mail::queue to queue our emails.

On the development machine, we still need to run queue:listen and in production, we can use beanstalkd.

@StormShadow Thanks for your guidance.

1 like

Please or to participate in this conversation.