(Laravel 5) 监控并可选择取消队列中已经 运行 的作业
(Laravel 5) Monitor and optionally cancel an ALREADY RUNNING job on queue
我需要实现监视和取消队列中已经 运行 作业的能力。
有很多关于删除 QUEUED 作业的答案,但没有关于已经 运行 的答案。
情况是这样的:我有一个 "job",它由数据库中的数百行组成,需要针对 Web 服务逐一查询。
需要提取每一行,针对 Web 服务进行查询,存储响应并更新其状态。
我已经将其用作命令(从控制台启动/输出到控制台),但现在我需要实施队列以允许从更多用户那里堆积更多作业。
到目前为止,我已经看到了 Horizon(由于缺少进程控制库,它无法在 Windows 上运行)。但是,在周围看到的一些演示中,它缺少(我相信)我需要的一些东西:
- 可动态配置的超时(整个作业可能需要 12 小时以上,具体取决于所选作业要处理的行数)
- 能够取消已经 运行 的工作。
我还考虑了将 EACH REQUEST 生成为新作业的选项,而不是将 "job" 视为整个行集合(这将克服超时问题),但这会给我一个 Horizon "pending jobs" 每个作业包含数十万条记录的列表,这会杀死浏览器(我知道 Redis 可以毫不费力地处理这个问题)。此外,我想取消 "all jobs belonging to X tag".
是不可能的
我一直在考虑点击 API 路线,解雇作业并将其与应用程序分离,但我发现这需要分叉流程。
为了能够取消,我会用 job_id 实现一个数据库,当用户点击 API 取消作业时,我会将其标记为 "halted" .在每个循环中,我都会检查它的状态,如果它找到 "halted" 然后自杀。
如果我遗漏了任何方面,请大声疾呼,我会添加或澄清。
所以我在这里寻求建议,因为我是 Laravel 的新手:我怎样才能做到这一点?
Laravel 队列有 3 个重要配置:
1. retry_after
2. timeout
3. tries
查看更多:https://laravel.com/docs/5.8/queues
Dynamically configurable timeout (the whole job may take more than 12
hours, depending on the number of rows to process on the selected job)
我想你可以配置超时 + retry_after 大约 24 小时。
Ability to CANCEL an ALREADY RUNNING job.
- 删除作业中的作业table
- 通过服务器中的进程 ID 删除进程
希望对你有帮助:)
所以我终于想出了这个(有点笨拙)的解决方案:
在控制器中:
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('files.halt_process_signal')));
return "Job cancelled - It will stop soon";
}
工作中 class(在 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;
}
服役中class:
/**
* 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 或其他不适合我的工具。
如果谁有更好的实现方式,欢迎分享。
我需要实现监视和取消队列中已经 运行 作业的能力。
有很多关于删除 QUEUED 作业的答案,但没有关于已经 运行 的答案。
情况是这样的:我有一个 "job",它由数据库中的数百行组成,需要针对 Web 服务逐一查询。
需要提取每一行,针对 Web 服务进行查询,存储响应并更新其状态。
我已经将其用作命令(从控制台启动/输出到控制台),但现在我需要实施队列以允许从更多用户那里堆积更多作业。
到目前为止,我已经看到了 Horizon(由于缺少进程控制库,它无法在 Windows 上运行)。但是,在周围看到的一些演示中,它缺少(我相信)我需要的一些东西:
- 可动态配置的超时(整个作业可能需要 12 小时以上,具体取决于所选作业要处理的行数)
- 能够取消已经 运行 的工作。
我还考虑了将 EACH REQUEST 生成为新作业的选项,而不是将 "job" 视为整个行集合(这将克服超时问题),但这会给我一个 Horizon "pending jobs" 每个作业包含数十万条记录的列表,这会杀死浏览器(我知道 Redis 可以毫不费力地处理这个问题)。此外,我想取消 "all jobs belonging to X tag".
是不可能的我一直在考虑点击 API 路线,解雇作业并将其与应用程序分离,但我发现这需要分叉流程。
为了能够取消,我会用 job_id 实现一个数据库,当用户点击 API 取消作业时,我会将其标记为 "halted" .在每个循环中,我都会检查它的状态,如果它找到 "halted" 然后自杀。
如果我遗漏了任何方面,请大声疾呼,我会添加或澄清。
所以我在这里寻求建议,因为我是 Laravel 的新手:我怎样才能做到这一点?
Laravel 队列有 3 个重要配置:
1. retry_after
2. timeout
3. tries
查看更多:https://laravel.com/docs/5.8/queues
Dynamically configurable timeout (the whole job may take more than 12 hours, depending on the number of rows to process on the selected job)
我想你可以配置超时 + retry_after 大约 24 小时。
Ability to CANCEL an ALREADY RUNNING job.
- 删除作业中的作业table
- 通过服务器中的进程 ID 删除进程
希望对你有帮助:)
所以我终于想出了这个(有点笨拙)的解决方案:
在控制器中:
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('files.halt_process_signal')));
return "Job cancelled - It will stop soon";
}
工作中 class(在 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;
}
服役中class:
/**
* 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 或其他不适合我的工具。 如果谁有更好的实现方式,欢迎分享。