【问题标题】:Deleting Running Jobs from Beanstalkd Queue in laravel在 laravel 中从 Beanstalkd 队列中删除正在运行的作业
【发布时间】:2014-09-26 06:12:19
【问题描述】:

这是场景,我正在使用 Beanstalkd 队列将电子邮件发送到大量电子邮件(50000+),每封电子邮件都必须有一些独特的内容,因此被解雇的作业会遍历所有地址,生成内容并发送邮件。

有时用户可能想在发送过程中取消操作,例如,在作业运行期间,邮件发送到 20000 个地址后,用户单击“停止”,这应该“删除”工作。

到目前为止,我所做的是我设法获得了正在运行的作业实例,Queue::Push 返回作业 ID,因此我将这个 ID 保存在 DB 中,当我想停止作业时,这就是我所做的试着做

$phean= Queue::getPheanstalk();

$res = $phean->peek($Job_ID); // returns a Pheanstalk_Job
$job = new \Illuminate\Queue\Jobs\BeanstalkdJob(app() , $phean, $res , 'default') ;

$res = $job->delete() // returns NOT_FOUND ??
$data = $job->getRawBody() // returns correct data, so I'm sure this is the right job instance

那么为什么我会得到 NOT_FOUND,虽然当我使用 supervisorctl tail -f 队列名 我可以看到作业仍在运行并输出内容

有什么帮助吗?如果有比尝试获取工作并以这种方式删除它更好的方法我愿意接受建议,我考虑将工作 ID 保存在数据库中(ID、状态),当我想删除它时,我会更改 ID状态,并且在作业中运行的循环中,它每次检查一次,或者可能每 10 次检查一次,如果状态等于 1,例如然后 $job->delete(),但这会很慢将在每个循环中命中数据库。

【问题讨论】:

  • 您的最后一个选项听起来不错,但我会使用缓存而不是数据库。并检查每 100 次左右的迭代。

标签: php email laravel supervisord beanstalkd


【解决方案1】:

所以你有一个主要工作,你 reserve() 并保持打开状态,在该工作中你直接创建许多电子邮件。

由于您尝试删除的作业当前已被保留,因此您无法将其删除。即使可以,Beanstalkd 将如何通知当前正在运行的作业?

相反,我会让主循环检查某个单独的控制管上的任何作业(您可以每发送 10 或 100 封电子邮件进行一次快速检查) - 只是为了请求新作业,但如果没有则不等待'那里没有任何东西。如果那里有作业,则主进程清理并退出。

另一个想法不是在主循环中实际发送电子邮件,而是将要发送的电子邮件的详细信息(每个地址一个)放入队列中。其他进程读取该大量队列并开始发送电子邮件,但同样,也读取了一个控制管(具有较高优先级的消息,该消息将在较低优先级的电子邮件/详细信息消息之前返回)。如果控制管中有任何东西,请停止发送电子邮件。控制管中的 STOP 消息至少需要与工人数量一样多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-08
    • 2013-12-28
    • 2020-11-17
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2016-03-24
    • 2020-12-23
    相关资源
    最近更新 更多