首页 > 解决方案 > Laravel:在全球范围内设置/模拟应用程序时间以进行开发

问题描述

在我的应用程序中,用户有他们可以发送到的电子邮件列表。他们的帐户设置了他们希望自动发送电子邮件的时间和他们所在的时区。

我想测试我的队列何时触发的某些场景,因为每个用户的发送时间可能会有很大差异。

我想用碳在全球范围内设定一个假时间。

public/index.php中,我尝试设置:

$time = Carbon::create('2020-09-16 00:00:00');
        Carbon::setTestNow($time);

但我的应用程序不受影响。

有没有一种全球性的方法来设置假时间?


下面的原始问题:

在我的应用程序中,用户有他们可以发送到的电子邮件列表。他们的帐户设置了他们希望自动发送电子邮件的时间和他们所在的时区。

我有一个命令会触发发送电子邮件的事件。

在侦听器内部,该handle方法如下所示:

public function handle(ReviewRequested $event)
    {
        
        $time = Carbon::create(2020, 9, 15, 0);
        Carbon::setTestNow($time);  

        $reviewRequest = $event->reviewRequest;
        Log::info('email sending at ' . $reviewRequest->sent_at . ' and current time is ' . Carbon::now());
        Mail::to($reviewRequest->customer->email)
            ->later($reviewRequest->sent_at, new ReviewRequestMailer($reviewRequest));

    }

请注意,我正在用 Carbon 伪造时间并将其设置为午夜。在此示例中,电子邮件应在上午 9 点发送。记录的信息如下:

local.INFO: email sending at 2020-09-15 09:00:00 and current time is 2020-09-15 00:00:00

所以当前时间是上午 12 点,我正在排队等待上午 9 点发送。

只要我运行php artisan queue:work,待处理的作业(电子邮件)就会立即运行并发送。为什么会这样?他们应该一直排队到上午 9 点。

也许排队正在使用系统时间并且不关心我在 Carbon 中设置的内容?我该如何解决这个问题?

编辑:我忘了提到我正在使用 Redis

标签: laravel

解决方案


检查您在.env文件中使用的队列驱动程序。QUEUE_CONNECTION=sync不允许任何延迟(同步代表同步)。

解决此问题的最快方法是执行以下操作:

  • 将驱动程序更改为数据库QUEUE_CONNECTION=database
  • 清除缓存的配置php artisan config:clear
  • 发布作业表的迁移php artisan queue:table
  • 迁移这个新表php artisan migrate

完成这些步骤后,您现在可以在运行队列时延迟执行php artisan queue:work


推荐阅读