Laravel Use different queue connection to dispatch Jobs - php

I am using laravel 5.1 and i am using the dispatch method to push the job onto the queue.
But there are two kind of jobs and i have created and two queues for that in sqs.
How should i achieve this?

In order to specify the queue you need to call onQueue() method on your job object, e.g.:
$job = (new SendReminderEmail($user))->onQueue('emails');
$this->dispatch($job);
If you want to send the job to a connection other than default, you need to do fetch connection manually and send the job there:
$connection = Queue::connection('connection_name');
$connection->pushOn('queue_name', $job)

This worked for me.
//code to be used in the controller (taken from #jedrzej.kurylo above)
$job = (new SendReminderEmail($user))->onQueue('emails');
$this->dispatch($job);
I think this dispatches the job on to the queue named "emails".
To execute the job dispatched on 'emails' queue:
//Run this command in a new terminal window
php artisan queue:listen --queue=emails

I'd suggest this:
app('queue')->connection('connection_name')->pushOn('queue_name', $job);
From here: In Laravel how to create a queue object and set their connection without Facade

Related

Laravel - queue job finished - how to use Queue::after?

I would like to modify a session variable when my queue job has finished. I found in laravel documentation, that Queue::after is created for my issue, but I can not find out how to use it.
I start the job from a controller: VideoController.php
$job = (new VideoConvertJob($newFileName))->delay(Carbon::now()->addSeconds(5)); dispatch($job);
There are some code in the job (VideoConvertJob.php) handle method:
public function handle() { ... }
But I do not know, where and how should I imlement the Queue::after method, to know that job has finished succesfully and update my session.

Dispatching a Laravel job in scheduler, pre-5.5

I'm used to Laravel 5.5+ where you can call $schedule->job(new ExampleJob); to fire jobs, which is not available in 5.4. I'm attempting to do something like this:
$schedule->call(function () {
dispatch(new AppointmentReminder);
})->dailyAt('08:00');
but the job is not firing. I've verified that this is being called at the correct time. I'm guessing the dispatch() method is not available in App\Console\Kernal.php? Does anyone know of the official way of dispatching jobs in 5.4's scheduler? This is a legacy code base and all of the jobs are inline in the Kernal.php which is a total mess. Not to mention this is a rather involved job.
I did try use Illuminate\Foundation\Bus\DispatchesJobs;/use DispatchesJobs; and then $this->dispatch(new AppointmentReminder()); in Kernal.php, but that did not seem to do the trick either. Also, (new AppointmentReminder())->dispatch(); does not work. Thanks!
You can create a new console command:
php artisan make:command CommandName
add it to App\Console\Kernal.php:
protected $commands = [
Commands\CommandName::class,
];
and make you schedual call it:
$schedule->command('CommandName')->dailyAt('08:00');
and inside your command in the "handle" function, dispatch the job.

Send response but keep long running script going to prevent timeout?

I am wondering how to deal with this. I have a webhook endpoint which responds to a webhook call from Github.
It starts a long running process in where it clones the repository from which the webhook call was made.
/**
* The webhook endpoint.
*
* #param Request $request
* #return mixed
* #throws \Exception
*/
public function webhook(Request $request)
{
// The type of GitHub event that we receive.
$event = $request->header('X-GitHub-Event');
$url = $this->createCloneUrl();
$this->cloneGitRepo($url);
return new Response('Webhook received succesfully', 200);
}
The problem with this is that Github gives an error when the response is not provided soon enough.
We couldn’t deliver this payload: Service Timeout
This is rightfully so because my cloneGitRepo method is simply blocking the execution of the response and it is taking too long.
How can I still deliver a response to acknowledge to Github that the webhook call has been made successfully and start my long running process?
I am using Laravel for all of this with Redis, maybe something can be accomplished there? I am open to all suggestions.
What you're looking for is a queued job. Laravel makes this very easy with Laravel Queues.
With queues, you setup a queue driver (database, redis, Amazon SQS, etc), and then you have one to many queue workers that are continuously running. When you put a job on the queue from your webhook method, it will be picked up by one of your queue workers and run in a separate process. The act of dispatching a queued job to a queue is very quick, though, so your webhook method will return quickly while the real work is being done by the queue worker.
The linked documentation has all the details, but the general process will be:
Setup a queue connection. You mention you're already using redis, I would start with that.
Use php artisan make:job CloneGitRepo to create a CloneGitRepo job class.
It should implement the Illuminate\Contracts\Queue\ShouldQueue interface so that Laravel knows to send this job to a queue when it is dispatched.
Make sure to define properties on the class for any data you pass into the constructor. This is necessary so the worker can rebuild the job correctly when it is pulled off the queue.
The queue worker will call the handle() method to process the job. Any dependencies can be type hinted here and they will be injected from the IoC container.
To dispatch the job to the queue, you can either use the global dispatch() helper function, or call the static dispatch() method on the job itself.
dispatch(new CloneGitRepo($url));
CloneGitRepo::dispatch($url);
So, your webhook would look like:
public function webhook(Request $request)
{
// The type of GitHub event that we receive.
$event = $request->header('X-GitHub-Event');
$url = $this->createCloneUrl();
CloneGitRepo::dispatch($url);
return new Response('Webhook received succesfully', 200);
}

rabbitmq and php - Process multiple queues with one worker (broker)

I have 1000 queues with specific names. so I want to process these queues with one broker. is it possible?
the queue names is stored in mysql db so I should fetch theme and run the broker for each one. and of course it should run asynchronously and should be able to pass the queued item to a idle broker. is this possible? or I should make 1000 files with specific queue names as brokers?
Update:
this is a picture of my queues. the queues should run in a parallel manner not a serial one. so the users are producer and the worker is consumer that runs the send_message() method;
I can show you how to it with enqueue library. I must warn you, there is no way to consume messages asynchronously in one process. Though you can run a few processes that serve a set of queues. They could be divided into groups by the queue importance.
Install the AMQP transport and consumption library:
composer require enqueue/amqp-ext enqueue/enqueue
Create a consumption script. I assume that you have an array of queue names already fetched from DB. They are stored in $queueNames var. The example bound the same processor to all queues but you can set different ones, of course.
<?php
use Enqueue\AmqpExt\AmqpConnectionFactory;
use Enqueue\Consumption\QueueConsumer;
use Enqueue\Psr\PsrMessage;
use Enqueue\Psr\PsrProcessor;
// here's the list of queue names which you fetched from DB
$queueNames = ['foo_queue', 'bar_queue', 'baz_queue'];
$factory = new AmqpConnectionFactory('amqp://');
$context = $factory->createContext();
// create queues at RabbitMQ side, you can remove it if you do not need it
foreach ($queueNames as $queueName) {
$queue = $context->createQueue($queueName);
$queue->addFlag(AMQP_DURABLE);
$context->declareQueue($queue);
}
$consumer = new QueueConsumer($context);
foreach ($queueNames as $queueName) {
$consumer->bind($queueName, function(PsrMessage $psrMessage) use ($queueName) {
echo 'Consume the message from queue: '.$queueName;
// your processing logic.
return PsrProcessor::ACK;
});
}
$consumer->consume();
More in doc

Delete a queue job outside of a worker in Laravel 4?

I understand the listener passes a Job instance to my worker and i can use that instance to delete the job, but how can i delete a job outside of worker?
Consider this scenario:
$job_id=Queue::push('DoTheJob', array('data'=>array(1,2,3)));
If(!someotherjobdone){
// delete job from Queue with job_id
?
}
Thank you
I'm not certain if this is correct, but I think you want to 'pop' the job off the queue:
$job_id=Queue::push('DoTheJob', array('data'=>array(1,2,3)));
If(!someotherjobdone){
Queue::pop($job_id);
}
If that doesn't work you could try:
$queue=Queue::getQueue($job_id);
Queue::pop($queue);
In my case, I am implementing SQS Queue. If I have the 'ReceiptHandle' of the message (an ID associated with a specific instance of receiving the message), I can delete it by accessing the SqsClient object through the SQSManager, because the manager is accessible by the IoC container.
$queue_manager = App::make("queue");
$sqs_queue = $queue_manager->connection('sqs');
$sqs_client = $sqs_queue->getSqs();
$sqs_client->deleteMessage(['QueueUrl' => $queue_url, 'ReceiptHandle' => $receipt_handle]);

Categories