我需要具备监视能力并能够取消队列中的“已运行”作业。
关于删除排队作业,有很多答案,但对于已经运行的作业却不是。
这种情况:我有一个“作业”,它由数据库中的数百行组成,需要针对Web服务一个一查询。
需要拾取每一行,针对Web服务进行查询,存储响应并更新其状态。
我已经以命令的形式工作(从/输出到控制台启动),但是现在我需要实现队列,以便允许更多用户堆积更多的作业。
到目前为止,我已经看到了Horizon(由于缺少过程控制库,因此无法在Windows上运行)。但是,在周围看到的一些演示中,我缺少(我相信)一些需要的东西:
我还考虑了将EACH REQUEST生成为新作业的选项,而不是在整个行集合中都看到“作业”(这将克服超时问题),但是这会给我一个Horizon“待处理作业”列表每个作业成千上万的记录,这会杀死浏览器(我知道Redis可以完全不发痒地处理)。此外,我想不可能取消“所有属于X标签的作业”。
我一直在考虑打一个API路由,解雇工作并将其与应用程序分离,但是我发现这需要分叉过程。
为了具有取消功能,我将使用job_id实现数据库,并且当用户点击API取消作业时,我会将其标记为“已暂停”。在每个循环中,我都会检查其状态,如果发现“停止”,则将其杀死。
如果我错过了任何一个方面,我会补充或澄清一下。
由于我是Laravel的新手,所以我在这里寻求建议:我怎么能做到这一点?
答案 0 :(得分:0)
Laravel队列具有3个重要的配置:
1. retry_after
2. timeout
3. tries
查看更多:https://laravel.com/docs/5.8/queues
动态可配置的超时(整个作业可能需要超过12个 小时,具体取决于所选作业要处理的行数)
我认为您可以在大约24小时后配置超时+ retry _。
可以取消已经运行的作业。
希望它对您有所帮助:)
答案 1 :(得分:0)
所以我终于想出了这个(有点笨拙)的解决方案:
在控制器中:
public function cancelJob()
{
$jobs = DB::table('jobs')->get();
# I could use a specific ID and user owner filter, etc.
foreach ($jobs as $job) {
DB::table('jobs')->delete($job->id);
}
# This is a file that... well, it's self explaining
touch(base_path(config('afip_client.files.halt_process_signal')));
return "Job cancelled - It will stop soon";
}
在工作类别中(在model::chunk()
函数内部)
# CHECK FOR HALT SIGNAL AND [OPTIONALLY] STOP THE PROCESS
if ($this->service->shouldHaltProcess()) {
# build stats, do some cleanup, log, etc...
$this->halted = true;
$this->service->stopProcess();
# This FALSE is what it makes the chunk() method to stop looping
return false;
}
在服务舱中:
/**
* Checks the existence of the 'Halt Process Signal' file
*
* @return bool
*/
public function shouldHaltProcess() :bool
{
return file_exists($this->config['files.halt_process_signal']);
}
/**
* Stop the batch process
*
* @return void
*/
public function stopProcess() :void
{
logger()->info("=== HALT PROCESS SIGNAL FOUND - STOPPING THE PROCESS ===");
$this->deleteHaltProcessSignalFile();
return ;
}
它看起来不太优雅,但可以。 我已经浏览了整个网络,很多人都选择了Horizon或其他不适合我的情况的工具。 如果有人有更好的方法来实现这一目标,欢迎分享。