如何在x分钟后重试作业



失败后,我需要在7分钟后重试作业。我尝试使用$this->release(7);,但有时作业运行次数超过1次。

<?php
namespace FroakieListeners;
use FroakieComponentsLocksLocksFactory;
use FroakieComponentsCRMCrmFactory;
use FroakieEventsNewLeadDataIncoming;
use FroakieServicesLeadsService;
use IlluminateContractsQueueShouldQueue;
use IlluminateQueueInteractsWithQueue;
/**
* Class CreateLead
*
* @package FroakieListeners
* @author Miguel Borges <miguel.borges@edirectinsure.com>
*/
class CreateOrUpdateLead implements ShouldQueue
{
use InteractsWithQueue;
const LOCKS_PREFIX = 'lead_event_lock_';
/**
* @var FroakieServicesLeadsService
*/
protected $leadsService;
/**
* Create the event listener.
*
* @param FroakieServicesLeadsService $leadsService
*/
public function __construct(LeadsService $leadsService)
{
$this->leadsService = $leadsService;
}
/**
* Handle the event.
*
* @param FroakieEventsNewLeadDataIncoming $event
* @throws Exception
*/
public function handle(NewLeadDataIncoming $event)
{
app('log')->debug('CreateOrUpdateLead listener has catch a NewLeadDataIncoming', ['event' => $event]);
$lead = $this->leadsService->getLeadById($event->leadId);
LocksFactory::getInstance()->getMutexAdapter(self::LOCKS_PREFIX . $lead->getId(), null, 60)
->synchronized(function () use ($lead, $event) {
if (!$lead->isCreated()) {
$lead->setCreated(true)->save();
try {
$lead->crm_id = CrmFactory::getInstance()->getCRMLeadAdapter($lead->getCrm())
->createLead($event->leadDto);
$lead->save();
app('log')->info("A new lead has been created in {$lead->getCrm()}", [
'reference' => $lead->getReference(),
'crm_id' => $lead->getCrmId()
]);
return;
} catch (Exception $exception) {
$lead->setCreated(false)->save();
throw $exception;
}
}
});
if (null !== $lead->getCrmId()) {
CrmFactory::getInstance()->getCRMLeadAdapter($lead->getCrm())
->updateLead($lead->getCrmId(), $event->leadDto);
app('log')->info("A lead has been updated in {$lead->getCrm()}", [
'reference' => $lead->getReference(),
'crm_id' => $lead->getCrmId()
]);
return;
}
$this->release(7);
}
}

我将创建一个任务调度程序条目,用于扫描failed_jobs表并根据failed_at列重试作业:

protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
$jobs = DB::table('failed_jobs')->where('failed_at', '<=', now()->subMinutes(7))->get();
foreach ($jobs as $job) {
Artisan::call('queue:retry', [
'id' => $job->id
]);
}
})->everyMinute();
}

最新更新