Getting Job Id in a Laravel queue with Database driver - php

I have a laravel job which I create from a controller and some times i want to delete those jobs as the timings will be rescheduled
It is a notification job which sends notification one hour before a class and if the class is rescheduled i need to delete the jobs and insert new ones
my controller code is as below
$job = (new OnlineClassRemainderJob($remainder_data))->delay($value);
$id = dispatch($job);
array_push($job_ids, $id);
and the Job class is as shown below
<?php
namespace App\Jobs;
use App\Mail\OnlineClassRemainderMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mail;
class OnlineClassRemainderJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $details;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($details)
{
$this->details = $details;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Mail::to($this->details['email'])
->send(new OnlineClassRemainderMail($this->details));
}
}
Kindly show light how I can get the Job id so that i can save it in a database and in case of a reschedule i can remove all job ids related to that class and then dispatch new schedules
I can layout the scenario here
I am scheduling classes for example
I have a class on every day from 20th Jan to 25th Jan at 10 AM and I am scheduling a remainder mail sending job which will fire 1 hour before the class
But at certains scenario the Classes will be rescheduled and for that purpose i need to reschedule the remainders or delete and redispatch the jobs

you need to retrun job id from job with this function $this->job->getJobId();
class OnlineClassRemainderJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Mail::to($this->details['email'])
->send(new OnlineClassRemainderMail($this->details));
retrun $this->job->getJobId();
}
}
then
$job = (new OnlineClassRemainderJob($remainder_data))->delay($value);
$id = dispatch($job);
array_push($job_ids, $id);
ref link https://laravel.com/api/8.x/Illuminate/Contracts/Queue/Job.html#method_getJobId

To take the id of a job before executing it, e.g. to dequeue it before executing it.
$log = UpdateLog::create();
UpdateProduct::dispatch($log)->delay(now()->addMinutes(10));
$regex = 'UpdateLog.*?id\\\\";i:'.$log->id.';';
//delete or get job before start
DB::table('jobs')->where('payload','REGEXP',$regex)->delete();
my job example
//...
class UpdateProduct implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* #var UpdateLog
*/
protected $log;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct(UpdateLog $log)
{
$this->log = $log;
}
//...
}

Related

Handle Method not being called in Laravel Redis Queue

When adding an item to the queue, for some reason the handle method is not being called.
The Log entry in __construct is appearing but when attempting to log in handle(), nothing appears.
The method i'm using to dispatch is ProcessImport::dispatch($path, $task->task_id);
My queue service is configured to use Redis, and redis is storing all the data accordingly.
I am using Laravel 8. What could be wrong?
<?php
namespace App\Jobs;
use App\Models\Tasks;
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\Controllers\Products\Products;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Queue;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Events\JobProcessed;
use Throwable;
class ProcessImport implements ShouldQueue, ShouldBeUnique
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $file_path;
protected $response;
protected $task;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($path, $task_id)
{
Log::info("Importing products (construct)");
$this->task = Tasks::where('task_id', $task_id)->first();
$this->file_path = $path;
Log::info('Importing ' . $path);
}
private function getFilePath() {
return $this->file_path;
}
/**
* Handle a job failure.
*
* #param \Throwable $exception
* #return void
*/
public function failed(Throwable $exception)
{
$this->task->failed($exception->getMessage());
}
/**
* Get the cache driver for the unique job lock.
*
* #return \Illuminate\Contracts\Cache\Repository
*/
public function uniqueVia()
{
return Cache::driver('redis');
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Log::info("Importing products (handle)");
$this->task->start();
$products = new Products();
$products->importProductsFromCSV($this->getFilePath());
$this->task->success();
Log::info("End of importing products..");
}
}
You've just pushed the jobs onto the queue but haven't started a worker to process them. You can run the worker with:
php artisan queue:work

Laravel "^6.18.35" “Target [Illuminate\Contracts\Bus\Dispatcher] is not instantiable.”

Im trying to test a job in laravel but with no success, when the job is called from a method inside a controller i get the following error:
“Target [Illuminate\Contracts\Bus\Dispatcher] is not instantiable.”
I already tried AltThree Bus command as an alternative.
Controller method where thw job is called
public function onOpen(ConnectionInterface $conn) {
// Store the new connection to send messages to later
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
Updates::dispatch();
}
Job Class
<?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 Updates 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()
{
echo "this is a update";
}
}

How can i pass a closure function to a laravel queue dispatch method

I want to pass a closure function to job dispatch method of Laravel queue. But i am getting "Serialization of 'Closure' is not allowed" exception. Can anyone please tell me how i can be able to pass closure function to the dispatch method?
Here are the controller codes:
public function syncProductByQueue($id){
$syncCallback=function() use($id){
$this->syncProduct($id);
};
ProcessSyncImport::dispatch($syncCallback);
}
And here is the job class:
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 ProcessSyncImport implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
private $syncCallBack;
public function __construct($syncCallBack)
{
$this->syncCallBack= $syncCallBack;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$syncCallBack();
}
}

Laravel scheduler run queue

Hello i have a laravel queue for save operations to do later
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;
use SumoCoders\Teamleader;
use Illuminate\Notifications\Messages\SlackMessage;
use Monolog\Handler\Slack;
use Illuminate\Support\Facades\Mail;
/**
* Class ProcessNotifications
*
* #package App\Jobs
* Worker for send the notifications slack / mail / teamleader in asincr way
*/
class ProcessNotifications implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $arrayDataNotification ;
protected $typeNotification;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($arrayDataNotification , $typeNotification)
{
$this->typeNotification = $typeNotification;
$this->arrayDataNotification = $arrayDataNotification;
\Log::debug('createNotif',$arrayDataNotification);
}
/**
* Execute the job.
*
* #return void
*/
public function handle($arrayDataNotification , $typeNotification)
{
//first get type of notification
\Log::debug('debug handle ',$this);
\Log::info('into handle '.$this->typeNotification);
if($this->typeNotification=='mail'){
//mail internal
}
if ($this->typeNotification=='slack'){
//notifications slack
}
if($this->typeNotification=='teamleader'){
//teamleader connection
}
}
}
For send a a new job to the queue i am using dispatch method :
$this->dispatch(new ProcessNotifications(['data1', 'data2', 'data3'], 'slack'));
I have all in ddbb in the job table , then params are ok
i setted my crontab by run schedule:run each 5 minutes, is launched ok , but on method schedule , when the method handle is called , the params are lost , and i have this in the function scheduler:
protected function schedule(Schedule $schedule)
{
Log::debug('running scheduler '.date("d-m-Y H:i:s"));
$schedule->job(ProcessNotifications::dispatch());
}
Then , the params in this point is lost, same if i run in console php artisan queue work i have :
Too few arguments to function App\Jobs`\ProcessNotifications::__construct()`
in my ddbb i have all params, but i dont know how recover or if this is the good way to call the queue ?
Ok i found, parameters under function handle not need parameters, this is serialized / unserialized automatically for the queue

Laravel [5.3|5.4] testing dispatch of job within a job

I'm struggling to understand how I could test a dispatch of a job within another job. I'll provide a code sample.
This is my main job class, we can call it father
final class FatherJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*/
public function __construct()
{
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
\Log::info("Hello World, I'm the father.");
dispatch(new ChildJob());
}
}
Then we have the child job
final class ChildJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*/
public function __construct()
{
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
\Log::info("I'm the child");
}
}
The test has been set as following
final class JobTest extends TestCase
{
/** #test */
public function it_has_been_dispatched()
{
$this->expectsJobs(ChildJob::class);
dispatch(New FatherJob ());
}
}
This test fails, of course that's the whole point of the question, but why?
I've done some digging and I presume that the problem relies on the call withoutJobs() inside expectsJobs(), it seems that withoutJobs() distrupt the current queue thus it doesn't allow to call the rest of the jobs but maybe I am totally off track.
If this logic is intended, how can I create a test suite that allows me to check if the job within a job has been called?
Thank you in advance.
expectsJobs mock all jobs engine. You can't use dispacth().
$this->expectsJobs(ChildJob::class);
$job = new FatherJob();
$job->handle();

Categories