Laravel implements Shouldqueue different queue - php

In laravel you can call the ShouldQueue interface like so
class ProfileWasCreated extends Event implements ShouldQueue
By default this will queue the event on the default queue, but I can't seem to figure out how to queue this event on a different queue with the name email.

$this->onQueue('emails');
Add the line above in your constructor for the email class. It would set the queue name. Then you can just use the Mail::send() function and it would queue on the "emails" queue.

You can specify the queue where a job should be sent by calling onQueue() on the job object, e.g.:
$job = new MyJob();
$job->onQueue('queue_name');
$this->dispatch($job);
onQueue method is provided by Queueable trait - it should be already included in your base App\Jobs\Job class by default.
dispatch() method is provided by ** DispatchesJobs** trait that you should include in the class that you want to dispatch jobs.
Have a look here for more details on how to use jobs and queues: http://laravel.com/docs/5.1/queues#dispatching-jobs-from-requests

Related

Laravel mailable subject not working if I queue the mailable

I'm working with laravel 7.0 and for some reason when I write subject in my build method of a mailable and queue it by calling the queue method of the Mail facade the subject isn't changing, it is taking the mailable classname and setting it as the subject. If I hard code the $subject variable in the mailable class it works and if I don't queue it then the subject gets set. Anybody knows how to solve this? I'm using database driver to handle the queue.
Mailable build method
public function build()
{
return $this->subject(config('app.name') . ' OTP')
->markdown('emails.otp');
}
How I'm queuing up the mail to send
\Illuminate\Support\Facades\Mail::to($this->user->email)
->queue(new \App\Mail\Otp($generatedOtp));

Laravel Not able to dispatch job from crontab

if i use this code in a controller queuing works well
$job=(new ReProcessShipment($single_data->request_data))->delay(2);
$this->dispatch($job);
but using same code in crontab error throws
Method App\Console\Commands\AddPreProcess::dispatch does not exist. {"exception":"[object] (BadMethodCallException(code: 0):
Method App\Console\Commands\AddPreProcess::dispatch does not exist.
tried to use it like
$job=(new ReProcessShipment($single_data->request_data))->delay(2);
ReProcessShipment::dispatch($job);
then get error
Object of class App\Jobs\ReProcessShipment could not be converted to string {"exception":"[object] (ErrorException(code: 0): Object of class App\Jobs\ReProcessShipment could not be converted to string at
am not able to process job queue from a cronjob any suggestion would be great.
You can dispatch a job by calling static dispatch method on the job class and passing the job's constructor arguments to the dispatch method, like this:
ReProcessShipment::dispatch($single_data->request_data)->delay(2);
Ensure that you are using the Illuminate\Foundation\Bus\Dispatchable trait to be able to call dispatch on the job class, e.g.:
use Illuminate\Foundation\Bus\Dispatchable;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, ...
If you have a look at the source you'll see that the static dispatch function creates the job for you using the job's parameters, so you don't need to create the job before you dispatch it. This is the source of the dispatch function:
public static function dispatch()
{
return new PendingDispatch(new static(...func_get_args()));
}
So it essentially transforms this:
ReProcessShipment::dispatch($single_data->request_data);
into this:
new PendingDispatch(new ReProcessShipment($single_data->request_data));

how to execute events asynchronously in laravel

Pls I'm still new to laravel and I have used events in laravel a couple of times but I'm curious and would like to know if it's possible to execute an event in laravel asynchronously. Like for instance in the code below:
<?php
namespace mazee\Http\Controllers;
class maincontroller extends Controller
{
public function index(){
Event::fire(new newaccountcreated($user)) ;
//do something
}
Is it possible for the block of code in the event listener of the "newaccountcreated" event to be executed asynchronously after the event is fired ?
Yes of course this is possible. You should read about Laravel Queues. Every driver (only not sync driver) are async. The easiest to configure is the database driver, but you can also want to try RabbitMQ server , here is Laravel bundle for it.
You can also add to your EventListener: newaccountcreated trait Illuminate\Queue\InteractsWithQueue (you can read about him here) which will helps you to connect it with Laravel Queue.
Filip's answer covers it all. I will add a bit more to it. If you push an event it will goto the default queue. You can specify a queue name as well. Have the listener class implements ShouldQueue and just include the queue method in the listener class like below.
/**
* Push a new job onto the queue.
**/
public function queue($queue, $job, $data)
{
return $queue->pushOn('queue-name', $job, $data);
}

Specify queue to push on in an Event Class

I'm working with multiple queues and want to push an event to another queue than the default one.
I have a standard event class that implements ShouldQueue, but how can I specify the queue this event will be pushed to?
I have tried with
class NewMessageArrived extends Event implements ShouldQueue
{
use SerializesModels;
protected $queue = 'redis';
....
but that doesn't do what I want. Is there a way to do this?
On Listener:
public $queue = 'notifications'; //Queue Name
public function queue(QueueManager $handler, $method, $arguments)
{
$handler->push($method, $arguments, $this->queue);
}
be happy =)
After spending some quality time with the Laravel source code, I'm fairly sure this isn't possible.
Events/Dispatcher.php's createClassCallable checks if your class has implements ShouldQueue, and if so, calls Dispatcher's createQueuedHandlerCallable() method, when in turn queues your event with a call to $this->resolveQueue()->push().
The problem is that push's third argument is what queue to push onto, and that argument is not passed. So it will always use the default queue, so you have no way of specifying an alternate default one.
I recommend queueing the event yourself with something like:
Queue::push(
function() {
event(new NewMessageArrived());
},
'',
'my-queue'
);
public function __construct()
{
$this->queue = 'high';
}
I tried to override $queue because it public but, laravel 5.6 return errors.
So, set the queue in the class construct is the shortest working solution i found.

Is it possible to prevent Laravel running Model Events when the database is being Seeded?

Laravel's seeder runs a variety of Model Events on my models which trigger New Order notification emails, among other things, from the Product::saved() Model Event.
This significantly slows down database seeding. Is it possible to detect whether a Seed is being ran and if so, tell Laravel not to run the Model Events?
There are functions on the Model class which will allow you to ignore events.
Before using a model to seed, you will need to do something like this...
YourModel::flushEventListeners();
I recommend to remove the Dispatcher in this Case from the Eloquent Model.
For example.
// Check Dispatcher
Model::getEventDispatcher()
// Remove Dispatcher
Model::unsetEventDispatcher()
// Add Dispatcher
Model::setEventDispatcher(new \Illuminate\Events\Dispatcher);
Add WithoutModelEvents Trait to your seeder
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
use WithoutModelEvents;
public function run(): void
{
// Silent eloquent queries ...
}
}

Categories