x分钟后如何重试作业?

时间:2018-07-27 08:03:48

标签: laravel laravel-5 laravel-jobs

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

<?php

namespace Froakie\Listeners;

use Froakie\Components\Locks\LocksFactory;
use Froakie\Components\CRM\CrmFactory;
use Froakie\Events\NewLeadDataIncoming;
use Froakie\Services\LeadsService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

/**
 * Class CreateLead
 *
 * @package Froakie\Listeners
 * @author Miguel Borges <miguel.borges@edirectinsure.com>
 */
class CreateOrUpdateLead implements ShouldQueue
{
    use InteractsWithQueue;

    const LOCKS_PREFIX = 'lead_event_lock_';

    /**
     * @var \Froakie\Services\LeadsService
     */
    protected $leadsService;

    /**
     * Create the event listener.
     *
     * @param \Froakie\Services\LeadsService $leadsService
     */
    public function __construct(LeadsService $leadsService)
    {
        $this->leadsService = $leadsService;
    }

    /**
     * Handle the event.
     *
     * @param \Froakie\Events\NewLeadDataIncoming $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);
    }
}

1 个答案:

答案 0 :(得分:3)

我将创建一个任务调度程序条目,该条目将扫描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();
}