How to give priority in laravel jobs? - laravel

I am trying to send daily newsletters to my users using laravel Queue jobs. everything is working fine. now the problem is, as I have 50K subscribers so it may take more than one hour to process newsletter jobs. and at the same time, some users registered, but they won't get a confirmation email. they will get the confirmation email only if the newsletter job is completed. how can do solve this problem? I am trying to do this as follows to use onQueue("low").
$job = (new SnippetsnewsletterJob())
->onQueue("low");
dispatch($job);
but the problem not solved!

You split to jobs across different queues.
This way you'll be able to categorize and prioritize them.
Specify wich queue a job belongs to
$this->dispatch((new JobOne())->onQueue('queue1');
$this->dispatch((new JobTwo())->onQueue('queue2');
Now you will be able to spawn multiple queue workers to processs jobs separately:
php artisan queue:work --queue=queue1
php artisan queue:work --queue=queue2

I find it! if you are trying to run long term task then use runInBackground() in kernel.php file.
$schedule->command('snippets:newsletter')
->dailyAt('16:10')->runInBackground();

Related

Recently added json language file values are not updated in email blade

I send mail as a cron job with Laravel. For this, when I want to use the last value I added in my resources/lang/de.json file in the mail blade template file(resources/views/mails/...blade.php), it gives an output as if such a value is not defined. However, if I use the same key in a blade file I created before, it works without any errors. In addition, the keys that I added to the same file (de.json) in the first time work without errors in the same mail blade file.
Thinking it's some kind of cache situation, I researched and found out that restarting the queue worker might fix the problem. However, both locally and on the server with ssh.
'php artisan queue:restart'
Even though I ran the command, there was no improvement.
Do you have any ideas?
Since queue workers are long-lived processes, they will not notice changes to your code without being restarted. So, the simplest way to deploy an application using queue workers is to restart the workers during your deployment process. https://laravel.com/docs/9.x/queues#queue-workers-and-deployment
but php artisan queue:restart will instruct all queue workers to gracefully exit after they finish processing their current job so that no existing jobs are lost. And I see a lot of issues with this command not to solve restart and deploy the worker.
So, Simplest way,
try to stop the worker manually (ctrl+C)
start the worker again with php artisan queue:work again.
might this help.

Running commands from Controller async

There is a migration task. User uploads file to the server, then it should be saved and migration command should be run async. The first path works well, there is an issue with the second part.
I've tried to put all code to console command and run it with
Artisan::call('user:migrate', ['user_id' => $userId]);
or
Artisan::queue('user:migrate', ['user_id' => $userId]);
the script works, but not async, controller's function waits for the end.
Also I've tried to create a Job and call it via:
$this->dispatch(new UserMigration($user));
and had the same result, script works but not async. Please help to realize how queues work and that approach is better for my task.
I've not created any queue migrations and configuration, because need this step just async calling.
In order to run tasks asynchronous, the general idea in Laravel is to push jobs to a queue (database table for instance) and have a background process pick them up.
See https://laravel.com/docs/8.x/queues for information directly from the source.
You can start a queue worker using:
php artisan queue:work
Note that this is an ongoing process that doesn't stop unless it's told to do so. This means that any changes you make to the code, will only be reflected once you restart that queue worker. It is therefore important to run php artisan queue:restart (or kill and start the running task) when you deploy your code.
So now your queue worker is running, you can for instance queue an email to be sent (like upon registration), and your controller will respond immediately instead of having to wait for the email to be sent.
Most if not all info can be found in the link above. If you are going to have lots and lots of background tasks, take a look at Laravel Horizon.

Laravel 5.5 listen dynamically generated queues

My application requires to have dynamically generated queues with some prefix like "process_user_1", "process_user_2", "process_user_n"
The main idea is to separate execution of some jobs depends on model ID.
To run watcher I need execute command php artisan queue:work --queue process_user_1
I didn't find possibility to put pattern like
php artisan queue:work --queue process_user_*
And only one way what I found it is to run them manually each time before job is sent. But it's so dirty...
Maybe someone know another way?
EXAMPLE:
I have 10 users. Each user has 100 jobs to process in queue.
If I put them to one queue like "process_user_job" users will wait a
lot of time when jobs will be finished.
So I want to separate queues to speed up result returning

Laravel queue worker with cron

I am trying to get my website to send confirmations emails every time someone new register.
i did it like following after reading about it, but i am still not convinced that this is the best way to do it.
in my cron runs every minute and calls php artisan schedule:run
in my console/Kernel
protected function schedule(Schedule $schedule)
{
$schedule->command('queue:work --once')->everyMinute()->withoutOverlapping();
}
i added the --once parameter because the queue worker is not existing when finished, and i do not want to have many new processes running every minute.
is there a way to make the queue worker finish all the jobs and exit and then start it after one minute again so that i do not have many instances , or is it just one instance ??
i read that i can return null to exit the worker, but if this can be done, then how can i return null only after the last job is done?
for any one still looking for a solution, in laravel 5.7 they added support to run all jobs in the queue and then stop the queue worker when all jobs are done.
Your cronjob should run this: php /path/to/laravel/artisan queue:work --stop-when-empty
Queue worker command source code on Github
plus there is a package available for older versions of laravel
orobogenius/sansdaemon

How to fire Laravel Queues with beanstalkd

I'm pretty new to the whole Queue'd jobs thing in Laravel 4. I have some process heavy tasks I need the site to run in the background after being fired by the user doing a particular action.
When I was doing the local development for my site I was using this:
Queue::push('JobClass', array('somedata' => $dataToBeSent));
And I was using the local "sync" driver to do it. (The jobs would just automatically fire, impacting on the user experience but I assumed when going into the production phase I could switch it to beanstalkd and they would then be run in the background)
Which brings me to where I'm at now. I have beanstalkd set up with the dependencies installed with composer and the beanstalkd process listening for new jobs. I installed a beanstalk admin interface and can see my jobs going into the queue, but I have no idea how to actually get them to run!
Any help would be apprieciated, thanks!
This is actually a really badly documented feature in Laravel.
What you actually need to do is have the JobClass.php in a folder that is auto-loaded, I use app/commands, but they can also be in app/controllers or app/models if you like. And this function needs to have a fire event that takes the $job and $data argument.
To run these, simply execute php artisan queue:listen --timeout=60 in your terminal, and it will be busy emptying the queue, until it's empty, or it's been running for longer then 60 seconds. (Small note: The timeout is the time-limit to start a queue, so it may run for 69 seconds if 1 job takes 10 seconds.
If you only want to run 1 job (perfect for testing), run php artisan queue:work
There are tools like Supervisord that make sure your job handlers keep running, but I recommend to just make a Cron task that starts every X minutes based on how fast the data needs to be processed, and on how much data comes in.
Keep in mind you need to path your artisan.
php /some/path/to/artisan queue:work

Resources