i got a problem when execute my queue. Job doesnt work.
.env:
QUEUE_CONNECTION=database_name
Job:
use App\Models\ProfessorSuscriptionHistory;
class CheckSuscription implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct()
{
}
public function handle()
{
$suscription_history = new ProfessorSuscriptionHistory();
$suscription_history->user_id = 13;
$suscription_history->type = 'trimestral';
$suscription_history->pdf = 'test.pdf';
$suscription_history->ended_at = Carbon::now()->addMonth(3);
$suscription_history->save();
}
}
My controller what dispatch a Job
use App\Jobs\CheckSuscription;
class TestController extends Controller
{
public function index()
{
CheckSuscription::dispatch()->onQueue('processing');
}
}
i used command php artisan queue:work and php artisan queue:listen but nothing appear in cmd. i migrated jobs to my db using php artisan queue:table and nothing appear in jobs table or failed_jobs table too. How can i fix that? thx!!
Put your QUEUE_CONNECTION=database_name to just QUEUE_CONNECTION=database you dont put the database name you just tell Laravel to use a certain queue. database, redis ...
Queue Connection
Related
I currently registered php artisan schedule:run in cronjob in cpanel and the schedule method is:
protected function schedule(Schedule $schedule)
{
$schedule->command('queue:work --stop-when-empty')
->cron('* * * * *')
->withoutOverlapping(5);
}
But for my purpose it is necessary to run the jobs immediately,
How can I run php artisan queue:work immediately after a job added to queue(jobs table) and not after one minute?
For Laravel > 7.x We can dispatch anonymosly
use App\Mail\WelcomeMessage;
use Illuminate\Support\Facades\Mail;
dispatch(function () {
Mail::to('taylor#laravel.com')->send(new WelcomeMessage);
})->afterResponse();
The WelcomeMessage should implement/use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
For Laravel 6.x
Instead of dispatching a job class to the queue, you may also dispatch a Closure. This is great for quick, simple tasks that need to be executed outside of the current request cycle:
$podcast = App\Podcast::find(1);
dispatch(function () use ($podcast) {
$podcast->publish();
});
for more you can read laravel docs https://laravel.com/docs/7.x/queues
the solution is to call queue:work on destruct() method of each class that I want to run it's job immediately.
use Illuminate\Support\Facades\Artisan;
class ProductShopObserver implements ShouldQueue
{
public function __destruct()
{
Artisan::call('queue:work --stop-when-empty');
}
}
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
I am using Laravel 5.8, I configured an email containing the invoice sent to user after they place an order.
Email is delivered when set QUEUE_DRIVER=sync but when I set it to redis/database and I run the php artisan queue:work redis --tries=5 it shows the queue is processed
Processing: Modules\Checkout\Mail\Invoice
Processed: Modules\Checkout\Mail\Invoice
succesfully and no entry in the failed_jobs either.
CODE:
Modules\Checkout\Jobs\SendInvoiceEmail.php
class SendInvoiceEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $order;
public function __construct(Order $order)
{
$this->order = $order;
}
public function handle()
{
Mail::to($this->order->customer_email)
->send(new Invoice($this->order));
}
}
And this is the Modules\Checkout\Mail\Invoice.php
class Invoice extends Mailable
{
use Queueable, SerializesModels;
public $order;
public function __construct($order)
{
$this->order = $order;
}
public function build()
{
return $this->subject('New order: ', ['id' => $this->order->id]))
->view("emails.invoice");
}
}
Then I am dispatching it in the Controller after Order created
SendInvoiceEmail::dispatch($order);
Can anyone point out if I've missed anything and what I am doing wrong?
I've done the php artisan config:cache and clear:cache restarted the server.
This works just as expected if I set QUEUE_DRIVER=sync in .env instead of QUEUE_DRIVER=redis or database
I had that problem too and solve it putting a key in the config/mail.php file
in mailers['smtp'] I add local_domain equals to my domain (example.com)
The reason is the Swift Mailer class can use this key to put in the HELO field of the email. If you use QUEUE=sync the framework uses the domain in env file, but when you use a different queue it doesn't cache the domain.
Thing is .env or config.php both configurations should work normally.
My main issue was the application would save these settings from .env or config.php to database. then for the next time it looked in database for these smtp configs and anything other than sync tends to fail.
I don't know why it was configured so I removed and the issue was resolved
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.
I'd like to use Schedule in Laravel on Mac. This is my crod file:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/local/sbin:~/bin:/usr/bin:/bin:/usr/sbin:/sbin
* * * * * php /Applications/MAMP/htdocs/xxxy/xxyyy/artisan schedule:run >> $run >> /dev/null 2>&1
This is Kernel.php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected $commands = [
//Commands\Inspire::class,
];
protected function schedule(Schedule $schedule)
{
$schedule->command(function () {
dispatch(new \App\Jobs\sendPush);
})->everyMinute();
}
}
Anything I type into the terminal with artisan gives this error :
[ErrorException] Object of class Closure could not be converted to string
Have you any idea how to make Artisan work?
sendPush.php
class sendPush extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
public function __construct()
{
//
}
public function handle(MessageController $MessageController)
{
$MessageController->sendDefault();
}
I've never used these before, but a quick skim of the docs seems to highlight your problem:
You may define all of your scheduled tasks in the schedule method of the App\Console\Kernel class. To get started, let's look at an example of scheduling a task. In this example, we will schedule a Closure to be called every day at midnight. Within the Closure we will execute a database query to clear a table:
and
In addition to scheduling Closure calls, you may also schedule Artisan commands and operating system commands. For example, you may use the command method to schedule an Artisan command using either the command's name or class:
It seems instead of using the command method you need to use the call method as you are passing in a Closure and not a commands name or class.
So I believe you simply need to update your code to the below:
protected function schedule(Schedule $schedule) {
$schedule->call(function () {
dispatch(new \App\Jobs\sendPush);
})->everyMinute();
}