简体   繁体   中英

Laravel, limit database queue to 1 email per minute

My application is hosted on a shared hosting platform that limits to 200 emails per hour.
My application is running database connection driver and I have 3000 jobs in the jobs table.
I would like to throttle this queue to only send 1 email every 30 secs or 1 minute to ensure I don't run issues with my hosting.

Research : I have tried delay from this tutorial , rate limiting from this question with no response , delayed jobs from this laravel documention but nothing works.

Question: Is there a way to throttle the queue in database queue connection like they do it in redis queue connection ie

// Allow only 1 email every 30 seconds
Redis::throttle('any_key')->allow(1)->every(30)->then(function () {
    Mail::to($this->email)->send(new NotificationEmail($this->data) );
    Log::info('Emailed order ' . $this->email);
}, function () {
    // Could not obtain lock; this job will be re-queued
    return $this->release(2);
});

My implementation: Delays only for the first job then sends the others with no delay

public function sendEmailNotification($email,$data)
{
    //Send email to user and to admin
    $email_job = (new ProcessEmailNotificationJob($email,$data))->delay(now()->addSeconds(30));
    
    if($this->dispatch($email_job)){
        return true;
    }
    else{
        return false;
    }
}

**ENV File: **

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=database
SESSION_DRIVER=file
SESSION_LIFETIME=120

MEMCACHED_HOST=127.0.0.1

did you run php artisan queue:listen , if yes check my below code maybe it will help

inside your controller:

$mail = (
    [
       'data' => $EmailData,
       'userName' => $userData->first_name,
       'userMail' => $userData->email,
       'subject' => $subject
    ]);
                    
SendMailJob::dispatch($mail)
    ->delay(now()->addSeconds($waitSec));
$waitSec += 30; //seconds interval

SendMailJob class

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 App\Mail\ClientRegistrationNotification;
use Mail;
class SendMailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $bulkMail, $mail;
    public function __construct($Mail)
    {
        $this->mail=$Mail;
    }

    public function handle()
    {
        try  {
                Mail::to($this->mail['userMail'])
                     ->queue(new ClientRegistrationNotification($this->mail['data'], $this->mail['userName'], $this->mail['userMail'], $this->mail['subject']));

             } catch (\Throwable $exception) {
                $this->fail();
             }
    }
}

I'm not sure if this is the best option but the only solution that worked for me was sleeping the queue for 30 seconds after dispatch ie

Dispatch Method

public function sendEmailNotification($email,$data)
{
    //Dispatch all 3000 with no delay
    if(ProcessEmailNotificationJob::dispatch($email,$data)){
        return true;
    }
    else{
        return false;
    }
}

Sleep Queue Sender

class ProcessEmailNotificationJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $email;
    private $data;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($email,$data)
    {
        //
        $this->email = $email;
        $this->data = $data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //Send the Mail and sleep for 30 Seconds before sending the next one
        sleep(30);
        Mail::to($this->email)->send(new NotificationEmail($this->data) );

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM