I'm creating an application which generates a video. This is a quite intensive function and takes a few minutes to generate. So I want to create a async process for this. After some research I've read about Jobs and Queues in Laravel.
But now my jobs don't get inserted in the jobs table. I can't find out what I've done wrong.
My function which starts the job:
public function generate() {
$id = Auth::user()->id;
GenerateJob::dispatch($id);
}
My Job
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Auth;
class GenerateJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct($dossierId)
{
$this->dossierId = $dossierId;
}
public function handle()
{
sleep(5);
}
}
.ENV QUEUE_DRIVER=database
I did run php artisan clear:config but nothing seems to help.
Nothing I try seems to work. The jobs table remains empty and the job is executed synchronously instead of asynchronously. What am I missing here?
After hours of debugging I finally found a solution to my problem. Adding ->onConnection('database'); to GenerateJob::dispatch($dossier_id); solved it all..
I wish I could say why this was necessary, but I have no clue since I already put that in my .env file. Hope this helps for someone else in this situation. :-)
Related
Using lumen 8.2.3 I am only trying to dispatch a unique job to a queue. In app/Console/Kernel I have sent a schedule to $schedule->job(new myJob(), 'high')->everyMinute(); this runs every minutes.
In the job itself I have added the ShouldBeUnique interface class in myJob class I even added
public function uniqueId() {
return $this->process->id();
}
when my cron job runs for php artisan schedule:run, this is still creating multiple jobs in the queue causing my 3 workers to pick up both jobs at the same time and causing issues.
https://laravel.com/docs/8.x/queues#unique-jobs clearly says
"Sometimes, you may want to ensure that only one instance of a
specific job is on the queue at any point in time. You may do so by
implementing the ShouldBeUnique interface on your job class. This
interface does not require you to define any additional methods on
your class:"
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Throwable;
class myJob implements ShouldQueue, ShouldBeUnique
{
use InteractsWithQueue, Queueable, SerializesModels;
private $process;
public function __construct($process){
$this->process=$process;
}
public function uniqueId() {
return $this->process->id();
}
public function handle()
{
//some code here
}
public function failed(Throwable $exception)
{
// Send user notification of failure, etc...
}
}
Is the no way to prevent this? thank you
The code provided barely reflects what you are writing; there's no job at all.
The declaration should look like this:
class SomeJob implements ShouldQueue, ShouldBeUnique
{
use InteractsWithQueue, Queueable, Dispatchable;
...
}
odd how this got fixed but what I did was change the version from 8.2.4 to 8.3.4 and shouldBeUnique work looks like a bug was introduced in 8.3.4
now im doing laravel project and i want to run a command exec() on queue jobs. the Question is, do i really can run the command exec() on queue jobs?
this what i've done, i create a jobs file call app/Jobs/GetData.php and create a simple code.
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class GetData implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct()
{
//
}
public function handle()
{
$csvFileName = public_path("csv/nintendo.csv");
$process = exec('facebook-scraper --filename '.$csvFileName.' --pages 1 '.$this->record->facebook_id);
}
}
but not success to run the exec().. if i implement this code on controller file. i can success to run the command and download the .CSV file.
before i tried to use this
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
-----
$csvFileName = public_path("csv/nintendo.csv");
$process = new Process("facebook-scraper --filename ".$csvFileName." --pages 5 nintendo");
$process->run();
// executes after the command finishes
if (!$process->isSuccessful()) {
//execute failed code
}else{
//execute success code
}
$process->getOutput();
but this also not working.. please help how to execute the command inside the queue jobs on laravel.
To solve the issue of non working command you have to either create env variables which points to Facebook-scraper or use the full path(absolute not relative) of facebook scraper package.
So the process construction should be something like
$process = new Process("/full-path/of/facebook-scraper --filename ".$csvFileName." --pages 5 nintendo");
$process->run();
I am implementing Queue JOBS, in my Laravel Project for the first time. But I am facing some difficulties on it, as after php artisan queue:work, noting is showing on the terminal.
Let Me describe, the procedure I have tried.
My Controller Function, from where I am trying to fire the Job Queue:
use App\Jobs\InitiateRecharge;
/
/*** Other Codes are here....
/
public function testQueueJob(){
InitiateRecharge::dispatch(1)->onQueue('initrecharge');
return 1;
}
My JOB Queue Class:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class InitiateRecharge implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $reportid;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($reportid)
{
$this->reportid = $reportid;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
sleep(10);
\Log::info('hello....');
}
}
I have also migrated the jobs table, and rows are also getting inserted on that.
It's is not giving any error, but the Job expected output is also not coming .. and in the terminal noting getting changed.
Please, anyone, help me
Thank You in advance :)
try php artisan queue:listen --tries=1
I would like to send mail to user after creating account on my website and I would like to use queues to send them. I'm using PHP Laravel framework.
My controller handles the request after clicking on "Create account":
class LoginController extends Controller
{
...
public function register(Request $request) {
...
$mail = (new RegisterRequest($user))->onConnection("database")->onQueue("emailsQueue");
Mail::queue($mail);
...
}
}
Then I have this RegisterRequest (mailable) class:
class RegisterRequest extends Mailable
{
use Queueable, SerializesModels;
protected $user;
public function __construct($user)
{
$this->user = $user;
}
public function build()
{
return $this->from('user#example.com')
->to($this->user->email)
->subject("Confirm your Email Address")
->view('emails.register.request')
->with("registration_token", $this->user->registration_token);
}
}
As you can see, I am using relational database to store jobs. And really, after calling LoginController's register method, a job is saved to database. But it can't be processed. I also start php artisan queue:work but nothing is done with jobs in database. Any help?
EDIT:
So I just found out that picking jobs from queue is done by SQL selecting the 'default' queue name. But I'm sending mails to queue 'emailsQueue'. So I'm now running Queue Worker like this: php artisan queue:work --queue=emailsQueue and everything's working fine for now. But how can I pick jobs from every queue in database? It's probably not the best attempt, right? It wouldn't make any sense to have named queues, right? But let's say I have one queue for processing register account requests, another queue for changing password requests and so on... So I think it does make sense to process every queue. So how can I do this? Can it be done just by listing the queues like this?
php artisan queue:work --queue=registerAccountEmailQueue,changePasswordEmailQueue...
What exactly does running php artisan queue:work? I thought it's the command to run all queues.
Use queue driver database.
In controller you should write
$this->dispatch(new SendNotifyMail($data));
This will pass your $data to queue. here SendNotifyMail is used as Job Class. So you should also use this in Controller like use App\Jobs\SendNotifyMail;.
Then create a file in Folder Jobs, named SendNotifyMail
<?php
namespace App\Jobs;
use App\Jobs\Job;
use DB;
use Mail;
use Artisan;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendNotifyMail extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
public $timeout = 300; // default is 60sec. You may overwrite like this
protected $data;
public function __construct($data)
{
$this->data = $data;
}
public function handle(Mailer $mailer)
{
$data = $this->data; // retrieve your passed data to variable
// your mail code here
}
}
In your command you need to write
php artisan queue:listen
or
php artisan queue:work
Then execute the code.
For dispatching a single job I usually do one of these:
Queue::push(new ExampleJob);
or
dispatch(new ExampleJob);
https://lumen.laravel.com/docs/5.5/queues
According to the Laravel Docs a certain Job chain, where one Job depends upon the previous is done like this:
ExampleJob::withChain([
new OptimizePodcast,
new ReleasePodcast
])->dispatch();
https://laravel.com/docs/5.5/queues#job-chaining
However this does not workin in Lumen (similar problem here: How to dispatch a Job to a specific queue in Lumen 5.5).
How do I chain Jobs in Lumen 5.5?
I don't think that will work given that in Laravel 5.5 documentation, in their example under creating jobs under the Queues documentation page, it shows that it requires several traits to able use all the features:
<?php
namespace App\Jobs;
use App\Podcast;
use App\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $podcast;
Most notably is this one:
use Illuminate\Foundation\Bus\Dispatchable; which appears to be a trait that is missing from the Lumen 5.5 framework altogether.
The rest of the Illuminate\... traits seem to be included.