6.0任务调度回调onSuccess方法在加入runInBackground后台执行后可能存在BUG
1.我现在把所有的调度任务写入到了数据库,代码执行正常,直到我加入了个runInBackground后,一切变得异常起来,我发现回调只是一个回调,没有其他的卵用,不能传递任务执行过程中产生的参数,可能我的表述有问题,请大家看代码和输出
$objSchedule = new \App\Models\Schedule();
$objSchedules = $objSchedule->where('status',1)->get(); //里面的就一条 ls 执行服务器的ls操作
$objSchedules->each(function ($item) use ($schedule) {
//1.生成日志名
$file_name = bin2hex(random_bytes(6)).'.log';
Log::info($file_name);
//2.执行命令
$event = $schedule->exec($item->command)->name($item->name);
//3.记录开始执行
$event->before(function ()use ($file_name){
Log::info("开始执行".$file_name);
});
//4.回调函数
$event->onSuccess(function ()use ($file_name){
Log::info("成功");
Log::info($file_name);
});
});
以上代码的输出
[2023-09-15 15:26:03] local.INFO: 20db2771b605.log
[2023-09-15 15:26:03] local.INFO: 开始执行20db2771b605.log
[2023-09-15 15:26:03] local.INFO: 成功
[2023-09-15 15:26:03] local.INFO: 20db2771b605.log
十分正常。
但是我加入后台运行后,诡异的事情就发生了,
//2.执行命令
$event = $schedule->exec($item->command)->name($item->name)->runInBackground();
看下输出
[2023-09-15 15:33:17] local.INFO: 1571f11fd425.log
[2023-09-15 15:33:17] local.INFO: 开始执行1571f11fd425.log
[2023-09-15 15:33:18] local.INFO: c743ebaeb21d.log
[2023-09-15 15:33:18] local.INFO: 成功
[2023-09-15 15:33:18] local.INFO: c743ebaeb21d.log
很明显前面2个是一块的 后面3个是一块的 。 应该是回调的时候
有进来执行了一遍
Log::info($file_name);
紧接着又调用
Log::info(“成功”);
Log::info($file_name);
当然记录的文件也是第一次输出的1571f11fd425,应该是前面写道属性中了。
那么 这么做的问题是 比如 我们想保存这个运行的情况到数据库中,最后通过回调来更改运行成功还是失败,就导致没办法传递数据给回调。如:
//1.生成日志名
$file_name = bin2hex(random_bytes(6)).'.log';
Log::info($file_name);
//2.执行命令
$event = $schedule->exec($item->command)->name($item->name)->runInBackground();
//3.记录开始执行
$event->before(function ()use ($file_name,$item){
$objScheduleLog = new ScheduleLog();
$objScheduleLog->log_path = $file_name;
$objScheduleLog->schedule_id = $item->id;
$objScheduleLog->save();
$log_id = $objScheduleLog->id; //现在问题来了 如何把这个id传递到这个onSuccess呢
//$this->log_id = $log_id;?这样肯定不行,因为加了后台运行后,相当于重新进入这个循环体一遍,导致没有这个属性
});
//4.回调函数
$event->onSuccess(function ()use ($file_name){
// 哎 我如何获取这个log_id呢 我想改自己成功还是失败啊
Log::info("成功");
Log::info($file_name);
});
现在想通过回调函数来更改 这个log日志的执行状态,但是通过上面的测试,这是重新进来执行的所以没办法获取到这个ID,是不是一个问题? 这应该是BUG把 我个人觉得是哈。
按照前面的想法,实践了一下,确实是可以,但是需要注意:
Event::createMutexNameUsing
和everyTenSeconds
只有在最新的 Laravel 10 才有。工作原理很简单 ,就是利用了
schedule:finish
,在后台任务完成时,Laravel 内部会调用 schedule:finish,并且调用当前任务的 mutexName 来生成任务的 id, 传递给这个命令,在这个命令中确定要去调取哪些 finish 的方法。需要注意的点就是当调用的命令是
schedule:finish
就不应该给生成的 mutexName 添加任务 ID,这样才能正确匹配。此方法相当于间接的改变了 Laravel 内部的实现,需要自行评估是否合理。