i am using postgresql as db, in .env i have set QUEUE_CONNECTION = database
I download from url, for example, a picture and transfer it to the queue for uploading in storage laravel
In web.php, I registered a route to the queue
Route::get('/job', function () {
App\Jobs\FileAdd::dispatch("https://www.example.com/example.jpg")->delay(now()->addMinute(25));
});
In job, I wrote the following:
<?php
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 Illuminate\Support\Facades\Storage;
class FileAdd implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $File;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($File)
{
$this->File = $File;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
info($data = $this->File);
$pos = strripos($data, '/');
$link = substr($data, 0 , $pos+1);
$filename = substr($data, $pos+1);
$expansion = substr($filename, -4);
$tempImageTwink = tempnam('..\storage\app\public', $filename);
$tempImage = substr($tempImageTwink, 0, -4) . $expansion;
copy($link . '/' . $filename, $tempImage);
Storage::delete('exa3BBD.tmp');
response()->download($tempImage, $filename);
unlink(($tempImageTwink ));
}
}
in the database I have two tables jobs, failed_jobs, for writing queues, but they are executed immediately without delay, what could be the problem?
Might be problem with cache if you just change it in .env file. Laravel cache your .env file and look at the cache if it is available not the .env file itself. So changes is not active, unless you will clear you cache or create new one. Try clear your cache with:
php artisan optimize:clear
or
php artisan cache:clear
so new data from .env file can be loaded.
Related
I am trying to send an email with a pdf file attached to it.
I checked and the file does exist at the path. I can open it aswell.
I tested if i can download the file with the download function of the storage facade and that also worked.
However when i try it in a queued email, it fails everytime after waiting about 20 seconds.
This is the error i got:
ValueError: fopen(): Argument #1 ($filename) must not contain any null bytes in C:\Users\Gebruiker\PhpstormProjects\FuegoWebsite\vendor\swiftmailer\swiftmailer\lib\classes\Swift\ByteStream\FileByteStream.php:129
Stack trace:
And my email code is:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Storage;
class PdfTestMail extends Mailable
{
use Queueable, SerializesModels;
public $orderId;
public $text;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($orderid, $text)
{
$this->orderId = $orderid;
$this->text = $text;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$file = Storage::disk('private')->get("factuur_order_".$this->orderId.'.pdf');
return $this->text('emails.notifyAdmin')
->subject('Orderbevestiging #'.$this->orderId)
->attach($file, [
'as' => 'factuur.pdf',
'mime' => 'application/pdf'
]);
}
}
I tried to attach the pdf in multiple ways, including the direct output of the barryvdh/dompdf package i use to generate a pdf.
nothing works and i have no idea why.
The attach method takes a filename for the file to attach, not data. You are probably looking for the attachData method:
public function attachData($data, $name, array $options = [])
To switch to attachData:
->attachData($file, 'factuur.pdf', ['mime' => 'application/pdf'])
Laravel 8.x Docs - Mail - Attachments - Raw Data Attachments attachData
I have an API REST built using Laravel 5.8 framework.
I have to get the data for my app from a public REST API. For this, i have to do a lot of requests. I made a seeder what do this, and it takes 2 minutes for the entire migration data process approximately (take from the public Api and insert in my application database).
I cant run the seeder by a cronjob because it does not work (it looks like need an user to execute the command to work). So, i created a job class what i call from my kernel file, the queue configuration was seted as database (QUEUE_CONNECTION=database), like a scheduled task (to execute with Supervisor: https://laravel.com/docs/5.8/queues#supervisor-configuration).
Despite this, the job fails, because it takes a long time to execute, so my data is not updated.
What i can do process my jobs by batch successfully?
This is my kernel.php
<?php
namespace App\Console;
use App\Jobs\Seed\ApiPlayerStatisticJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new ApiPlayerStatisticJob)->everyFiveMinutes();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
My ApiPlayerStatisticJob.php
<?php
namespace App\Jobs\Seed;
use App\ApiExternal;
use App\ApiPlayer;
use App\ApiTeam;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ApiPlayerStatisticJob 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()
{
$api_teams = ApiTeam::get();
foreach ($api_teams as $api_team) {
// echo 'TEAM: '.$api_team->id;
$api_external_players = ApiExternal::getTeamPlayerStatistics($api_team->id);
foreach ($api_external_players as $api_external_player) {
// echo PHP_EOL.'PLAYER: '.$api_external_player['id'];
$api_player = ApiPlayer::find($api_external_player['id']);
if ($api_player != null) {
$api_player->update($api_external_player);
// echo PHP_EOL.'> PLAYER UPDATED ';
} else {
// echo PHP_EOL.'X PLAYER DIDNT UPDATED ';
}
}
// echo PHP_EOL;
// echo PHP_EOL;
}
}
}
And my Seeder what i used for construct my job (by replication, excluding the print expressions):
<?php
use Illuminate\Database\Seeder;
use App\ApiExternal;
use App\ApiPlayer;
use App\ApiTeam;
class ApiPlayerStatisticsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$api_teams = ApiTeam::get();
foreach ($api_teams as $api_team) {
echo 'TEAM: '.$api_team->id;
$api_external_players = ApiExternal::getTeamPlayerStatistics($api_team->id);
foreach ($api_external_players as $api_external_player) {
echo PHP_EOL.'PLAYER: '.$api_external_player['id'];
$api_player = ApiPlayer::find($api_external_player['id']);
if ($api_player != null) {
$api_player->update($api_external_player);
echo PHP_EOL.'> PLAYER UPDATED ';
} else {
echo PHP_EOL.'X PLAYER DIDNT UPDATED ';
}
}
echo PHP_EOL;
echo PHP_EOL;
}
}
}
Finally, the static function ApiExternal::getTeamPlayerStatistics(int id) do all requests necessaries to get th data (like 30 requests), so what i can do to process this job (or the seeder directly) in background without it fails?
Did you configure the config/queue.php file correctly?
Quote from the documentation in the Job expirations paragraph:
In your config/queue.php configuration file, each queue connection defines a retry_after option. This option specifies how many seconds the queue connection should wait before retrying a job that is being processed.
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;
use Storage;
class UploadFiles extends Job implements SelfHandling
{
/**
* Create a new job instance.
*
* #return void
*/
protected $files;
public function __construct($files)
{
//
$this->files = $files;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
//
if(!empty($this->files)):
foreach ($this->files as $key => $file) :
# code...
Storage::put($file->getClientOriginalName(), file_get_contents($file));
endforeach;
endif;
}
}
Inside controller
$files = $request->file('file');
$job = (new UploadFiles($files))
->delay(Carbon::now()->addSeconds(15));
dispatch($job);
Queue does not respond m i doing something wrong please guide thanks a ton in advance. Also i can see no database entry inside job table neither response queue have data but image uploading stright forwardly
In your .env file, set QUEUE_DRIVER=database
and check your queue.php config file in config folder
set 'default' => env('QUEUE_DRIVER', 'sync'),
after that run comand
php artisan config:clear
then try to dispatch job
i want send mail in queue and have not waiting when send mail
https://laravel.com/docs/5.7/queues#connections-vs-queues
i run command to create table jobs:
php artisan queue:table
php artisan migrate
I create a job to send mail: php artisan make:job SendEmailJob
and edit code :
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 Mail;
class SendEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public $body;
public $emailto;
public function __construct($body,$email)
{
//
$this->body=$body;
$this->emailto=$email;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$email=$this->emailto;
Mail::send("body_email.confirm_order",['Body'=> $this->body], function($message) use ($email)
{
$message->from(env('MAIL_USERNAME'),"Eye glasses");
$message->subject("Confirm Email");
$message->to($email);
});
}
}
I call queue from controller:
use App\Jobs\SendEmailJob;
public function index()
{
$Body="test";
$email="daitb#vnitsolutions.com";
SendEmailJob::dispatch($Body, $email);
$calendars= AppointmentModel::GetAppointmentofDoctor($id,$datetime);
return view('frontend.appointment',["calendars"=>$calendars]);
}
add QUEUE_DRIVER=database to file .env
run command:
php artisan queue:work
If i run controller, process still waiting send mail finish and run other process.
i try change to:
SendEmailJob::dispatch($Body, $email)->delay(now()->addMinutes(3));
It not delay,it still send mail after 5s.
Why queue still waiting when send mail in laravel?
I using win 32.
My Problem fixed by change QUEUE_CONNECTION=sync to QUEUE_CONNECTION=database in .env file
I want to send many emails.
Currently I write basic code use PHPMailler to send mail using queue. It works, but everytime new queue is run, it have to connect to SMTP again, so i get bad perfomance.
I find SMTPKeepAlive property on PHPMailler documentation:
$phpMailer = New PHPMailer();
$phpMailer->SMTPKeepAlive = true;
Is it imposible and how to keep $phpMailler object for next queue? So PHPMailler have not to connect again by using previous connection.
If you are using Laravel then you have to use Laravel's feature inbuilt.
Please find below documents:
https://laravel.com/docs/5.6/mail
Please find a piece of code for send mail and adding in a queue:
use App\Mail\EmailVerifyMail;
\Mail::queue(new EmailVerifyMail($users));
EmailVerifyMail.php
<?php
namespace App\Mail;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class EmailVerifyMail extends Mailable
{
use Queueable, SerializesModels;
public $user;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$this->to($this->user)->subject(__('mail.subjects.verification_link', ['USERNAME' => $this->user->name]));
return $this->view('mails/emailVerify', ['user' => $this->user]);
}
}