在laravel中从bean队列中删除正在运行的作业


Deleting Running Jobs from Beanstalkd Queue in laravel

这是一个场景,我使用Beanstalkd队列向一个巨大的电子邮件列表(50000+)发送电子邮件,每个电子邮件必须有一些独特的内容,因此触发的作业循环所有地址,生成内容并发送邮件。

有时用户可能希望在发送过程中取消操作,例如,当作业正在运行时,邮件发送到20000个地址后,用户单击"Stop",这应该"删除"作业。

我到目前为止所做的是,我设法获得运行的作业实例,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,尽管当我使用superorctl tail -f queuename我可以看到作业仍在运行,并输出内容

有什么帮助吗?如果有更好的方法比努力得到这份工作和删除这样我中肯的建议,我想拯救工作ID在数据库(ID、状态),当我想删除它我改变身份地位,而在循环运行它检查每次在工作,或者每一个10倍,如果状态= 1例如然后工作-> delete(),但这将是缓慢的,因为它将db在每个循环。

那么你有一个主作业,你reserve()并保持打开,在该作业中你直接创建许多电子邮件。

由于您要删除的作业当前是保留的,因此您不能删除它。即使可以,beanstald如何通知当前正在运行的作业呢?

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

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