Recursive queue job, 100% CPU usage - laravel

I'm trying to create a queue job that runs continuously, i.e. runs a new job after the previous job has finished.
I've created a skeleton job just to test out the performance of doing this:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Page;
class PageParser extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $page;
public function __construct(Page $page)
{
$this->page = $page;
}
public function handle()
{
$this->delete();
dispatch(new PageParser($this->page));
}
}
I ran the queue listenener, and immediately my CPU usage jumped to 100% and stayed at that level indefinitely.
Why is it using 100% of my CPU? Is there any way to fix this? Does ShouldQueue have anything to do with this?

Related

Laravel 8 jobs not dispatching

I have this Job
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Http\Traits\CreateTrait;
class CreateJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, CreateTrait;
protected $contactForm;
public function __construct($contactForm)
{
$this->contactForm = $contactForm;
}
public function handle()
{
//This connects to SSH and takes 5-10s
$this->CreateOnetime($this->contactForm->room_id, $this->contactForm->company_id, $this->contactForm->id);
}
}
Then I try in controller
use App\Jobs\CreateJob;
class ContactFormController extends Controller
{
public function save(StoreContactFormRequest $request, $cid, $rid){
$validated = $request->validated();
$validated['room_id'] = $rid;
$validated['company_id'] = $cid;
$contactForm = ContactForm::create($validated);
CreateJob::dispatch($contactForm);
return back();
}
}
Nothing written in the DB, though I have QUEUE_DRIVER=database in the .env file.
The function runs synchronously, so it does not create the Job somehow, just runs it.
Problem was I had QUEUE_CONNECTION=sync somewhere after QUEUE_DRIVER=database

Class 'Mpdf\Mpdf' not found (Laravel Job)

I have the following code for a laravel Job. It works just fine when in the Controller, but once I transferred it to a job, it fails with the error
Class 'Mpdf\Mpdf' not found
I have imported the class at the top of the job as I did with the controller so can't figure out why it can't find it.
<?php
namespace App\Jobs;
use Mpdf\Mpdf;
use App\DocumentRequest;
use Illuminate\Bus\Queueable;
use Intervention\Image\Facades\Image;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ProcessUploads implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $uuid;
public function __construct($uuid)
{
$this->uuid = $uuid;
}
public function handle()
{
$mpdf = new Mpdf();
$mpdf->WriteHTML($this->uuid);
$mpdf->Output('Output.pdf', 'F');
}
}
Steps to do for this type of errors:
Check composer that this package is already installed
Use the composer dump-autoload command to update autoload classes.
Check the documentation of this package for the valid class call
Restart the queue (because queue and tinker cache the code)
My supervisor job was running in the background and hadn’t been restarted to reflect the changes.

How to push the Laravel job to the queue

I have a class XYJob which was created by artisan command and implements the ShouldQueue class.
The QUEUE_DRIVER=redis in the .env file.
The problem is that when i dispatch the job, it runs as a simple php function. The queue listener is not running, but the job runs as a simple function.
It is laravel 5.8 application with predis/predis: ^1.1.
I have tried to clear the cache and the config. I have tried to use composer dump-autoload.
namespace Modules\ModuleName\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class XYJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
\Log::info('Job is running');
}
}
Laravel documentation says:
The generated class will implement the ShouldQueue interface, indicating to Laravel that the job should be pushed onto the queue to run asynchronously.
BUT my job is definitely running.
Laravel 5.8 application should has QUEUE_CONNECTION in the .env file.
How are you dispatching the job? Have you followed the example on the Laravel doscs site at https://laravel.com/docs/5.8/queues#dispatching-jobs i.e.
\App\Jobs\ProcessPodcast::dispatch($podcast);
or dispatch(new \App\Jobs\ProcessPodcast($podcast);
dispatch(new \App\Jobs\ProcessPodcast($podcast);
If the job is not dispatched in this manner (i.e. you're simply newing up the job class), it will not be pushed to the queue.

Laravels 'Should Queue" resets mail text to default

i have a problem woth combining notifications and queue in laravel...
if i dont use queue and write notification like this
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class InterestingOfferPosted extends Notification
{
public $offer;
public function __construct($offer)
{
$this->offer = $offer;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('New Offer')
->line("You have new offer: ".$this->offer->name }
}
this works fine, i get correct text at the end, however if i get this class to implement "Illuminate\Contracts\Queue\ShouldQueue" class and use "Illuminate\Bus\Queueable" trait users are receiving default laravels "The introduction to the notification." mail.
queues are working nice in any other cases, so i think i got that right, but in this particular case it alters final result.
Any ideas?
I think you are not implementing queue interface here
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class InterestingOfferPosted extends Notification implements ShouldQueue{
use Queueable;

How to set Max Attempts For Queued Notifications in Laravel

In laravel queue system when working with jobs I can set max tries for each job with adding a public field $tries = n in job class itself
is it possible and How to do the same thing in notification implementing shouldQueue ?
It is possible in Laravel 5.7.14:
https://github.com/laravel/framework/pull/26493
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
class TestNotification extends Notification implements ShouldQueue
{
use Queueable;
public $tries = 3; // Max tries
public $timeout = 15; // Timeout seconds
}

Resources