Laravel:检查是否有新项目添加到db表中,并为电子邮件用户安排作业
我想在我的Laravel应用程序中将新行添加到表中时触发电子邮件。然而,我想添加一个排序缓冲区,所以如果快速连续添加5行,那么只发送1封电子邮件 我选择的方法是每15分钟安排一次检查,看看是否添加了新行。如果有,那么我将排队发送电子邮件 目前我在日程安排上有个错误。我将在下面运行我的代码: 在Kernel.php中,我们在其中设置日程安排,我有:Laravel:检查是否有新项目添加到db表中,并为电子邮件用户安排作业,laravel,laravel-queue,laravel-scheduler,laravel-jobs,Laravel,Laravel Queue,Laravel Scheduler,Laravel Jobs,我想在我的Laravel应用程序中将新行添加到表中时触发电子邮件。然而,我想添加一个排序缓冲区,所以如果快速连续添加5行,那么只发送1封电子邮件 我选择的方法是每15分钟安排一次检查,看看是否添加了新行。如果有,那么我将排队发送电子邮件 目前我在日程安排上有个错误。我将在下面运行我的代码: 在Kernel.php中,我们在其中设置日程安排,我有: $schedule->job(new ProcessActivity) ->everyFifteenMin
$schedule->job(new ProcessActivity)
->everyFifteenMinutes()
->when(function () {
return \App\JobItem::whereBetween('created_at', array(Carbon::now()->subMinutes(15), Carbon::now()))->exists();
})
->onSuccess(function () {
Log::debug(
'Success'
);
})
->onFailure(function () {
Log::debug(
'Fail'
);
});
我使用它触发在以下位置找到的作业:App\Jobs\ProcessActivity.php:
public function __construct()
{
$this->jobs = \App\JobItem::whereBetween('created_at', array(Carbon::now()->subMinutes(15), Carbon::now()))->get();
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
Log::debug('Activity Job Run', ['jobs' => $this->jobs]);
$this->jobs->each(function ($item, $key) {
Log::debug('loop');
// get project
$project = $item->project;
// get project email
$user_id = $project->user_id;
$email = \App\User::find($user_id)->email;
// get project UUID
$projectUuid = $project->public_id;
// emails
$subscriberEmails = \App\ProjectSubscription::where('project_id', $project->id)->get();
// create activity email
Notification::route('mail', $subscriberEmails)->notify(new Activity($project, $projectUuid));
});
return true;
}
我已经在上面发布了我的完整代码,它还显示了我的JobItems和项目模型之间的关系。正如我在代码中所评论的那样,我不会详细说明这一点
问题
当我向JobItem表中添加新行时,我可以看到作业已被调度和处理(使用Laravel望远镜检查)
但是,我也可以在日志中看到,对于每个作业,我都会收到两条日志消息:
首先:“失败”,然后“活动作业运行””
我的电子邮件没有发送,我不确定如何确定这失败的原因
因此,似乎正在触发onFailure,并且我的ProcessActivity存在问题
如果有任何关于我哪里出错以及如何判断错误的线索,我将不胜感激。我有一个解决办法,但首先,我学到了一些阻碍我进步的东西: 我正在使用此artisan命令处理我的计划作业:
php artisan queue:work
在使用该命令时进行开发的问题是,如果有代码更改,则无法识别这些更改
因此,您可以命令+C返回控制台,并在每次代码更改时使用此命令:
php artisan queue:restart
php artisan queue:work
或者,您可以使用它,它将允许代码更改:
php artisan queue:listen
您可以想象,如果不知道这一点,您将有一个缓慢的调试过程
因此,在我的工作中加入了一个例外,我取得了一些进展。我将粘贴下面的代码以与原始代码进行比较:
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
try {
$jobs = \App\JobItem::whereBetween('created_at', array(Carbon::now()->subMinutes(20), Carbon::now()))->get();
Log::debug('Activity Job', ['jobs' => $jobs]);
// collection start
$collection = collect();
// loop jobs to get emails
foreach ($jobs as $key => $value) {
// get project UUID
$project = $value->project;
$projectUuid = $project->public_id;
// get emails subscribed to projects
$subscriberEmails = \App\ProjectSubscription::where('project_id', $project->id)->get();
// merge into a single collection via the loop
if ($key != 0) {
$merge = $collection->merge($subscriberEmails);
$collection = collect($merge);
} else {
$collection = $subscriberEmails;
}
// Log::debug('emails_project in loop', ['emails' => $subscriberEmails]);
};
// clean object with uniques only
$subscriberEmailsCleaned = $collection->unique();
// debug
Log::debug('Project Emails to Notify', ['emails' => $subscriberEmailsCleaned]);
// create activity email
Notification::route('mail', $subscriberEmailsCleaned)->notify(new Activity($project, $projectUuid));
} catch (\Exception $e) {
\Log::info($e->getMessage());
}
}
首先要注意的是,as _construct()最初运行并序列化。然后在处理作业时调用handle方法。因此,我不得不将我的雄辩的查询转移到handle方法中
我还使用了foreach而不是.each来循环并创建一个新的电子邮件集合。也许有一种更优雅的方法,但我需要创建一个电子邮件集合,这种方法允许我将循环中的变量移到外部,以便在方法中使用
你可以看到我在循环的底部合并了这些
我还添加了一些对调试有用的Log::items
不固定100%
有了这段代码,我现在可以在添加新项目时每x分钟自动安排一封电子邮件。但是,我仍然从我的Kernal.php文件的onFailure()中获取日志Fail:
->onFailure(function () {
Log::debug(
'Fail'
);
我仍然不清楚这意味着什么,我如何才能确定更多关于这一失败的信息以及这意味着什么。但是,它确实有效,因此我将谨慎地向前推进(对评论睁大一只眼,以防有人有什么想法可以帮助!)我认为您的逻辑中也存在一个问题。你每分钟都在运行时间表。这意味着已经处理的行将在接下来的19分钟内再次处理。@sachinkumar啊!我现在只是为了调试而每分钟都在运行——我会进去修改它,这样它就不会混淆了!你能计算出抛出了什么异常吗?你知道如何@kevin-我如何在onFailure()中转储异常吗?请在你的作业中放置一个try catch并记录异常:try{}catch(\exception$e){\log::info($e->getMessage());}}你启动了调度程序吗?如果调度程序正在运行,那么它也不会反映更改。