Как ограничить количество проверочных писем в очереди и уведомлений о сбросе пароля в laravel 5.7 - PullRequest
0 голосов
/ 05 октября 2018

Issue

Используя Laravel 5.7 с Redis, я получил уведомления о подтверждении электронной почты и сбросе пароля в очередь, используя метод, описанный в ответе Стивена Мудере в Как отправить ссылку для сброса пароля по электронной почте, используяочередь в laravel 5 , но я не могу понять, как ограничить скорость этих конкретных уведомлений в очереди.Поскольку мое приложение будет отправлять электронные письма по разным причинам (не только для этих двух целей), а мой почтовый сервер ограничен скоростью до 30 электронных писем в минуту, мне нужно ограничить скорость всего в очереди «электронной почты».

Справочная информация

В соответствии с очередью Laravel Документация кажется довольно простым сделать это в классе задания в методе handle, используя

Redis::throttle('key')->allow(10)->every(60)->then(function () {
  // Job logic...
}, function () {
  // Could not obtain lock...

  return $this->release(10);
});

Проблема в том, что я использую не класс работы, а уведомление.Например, для сброса пароля я создал следующий

ResetPassword Class
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;

class ResetPassword extends ResetPasswordNotification implements ShouldQueue
{
    use Queueable;
}

, который вызывается из модели пользователя с использованием:

public function sendPasswordResetNotification($token)
{
        $this->notify(new ResetPasswordNotification($token));
}

Подход

У меня естьпопытался решить эту проблему, изменив функцию sendPasswordResetNotification в модели User:

public function sendPasswordResetNotification($token)
{
    Redis::throttle('email')->allow(2)->every(60)->then(function () use($token) {
        $this->notify(new ResetPasswordNotification($token));
    }, function () {
        // Could not obtain lock...

        return $this->release(10);
    });
}

Обратите внимание, что значения для дросселя искусственно занижены для целей тестирования.Кажется, это работает частично.В приведенном выше примере, если я попытаюсь выполнить две последовательные перезагрузки пароля, электронные письма будут помещены в очередь и отправлены.Когда я пытаюсь отправить третье письмо (превышающее установленное ограничение 2 в минуту), я получаю исключение BadMethodCallException, "Call to undefined method App\User::release()".Я понимаю, что это связано с тем, что в модели User нет метода выпуска, но возникает проблема, заключающаяся в том, что я точно не знаю, где и как использовать логику регулирования.Есть ли способ изменить это, чтобы работать, или мне нужно использовать совершенно другой подход к отправке этих сообщений?

Обновление: альтернативный подход, который не удается по другой причине

Я переключился сиспользуя уведомление об использовании Job, чтобы я мог использовать Redis :: throttle в соответствии с документацией.Чтобы настроить задание для очереди сообщений, я использовал подход из Как поставить в очередь Laravel 5.7 «проверка электронной почты» отправка электронной почты .Это отлично работало для отправки писем в очереди.Затем я попытался ограничить работу, идущую в очередь.Вот мой полный подход:

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Support\Facades\Redis;

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

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Redis::throttle('email')->allow(2)->every(60)->then(function () {
            $this->user->notify(new VerifyEmail);
        }, function() {
           return $this->release(10);
        });
    }
}

Они идут в очередь, но затем терпят неудачу.В трассировке стека есть следующее: Symfony\Component\Debug\Exception\FatalThrowableError: Class 'App\Jobs\Redis' not found in /home/vagrant/code/myapp/app/Jobs/QueuedVerifyEmail.php:27

Я не могу понять, почему он ищет фасад Redis в App \ Jobs, когда у меня есть оператор использования для определения правильного местоположения.

1 Ответ

0 голосов
/ 08 октября 2018

У меня все заработало

Решение в разделе "Обновление: альтернативный подход" сработало.Я не уверен, почему это не сработало (возможно, что-то было кэшировано?), Но теперь кажется, что оно работает правильно.

...