Laravel 队列 - 记住属性状态?

问题描述 投票:0回答:2

如果作业失败,它将被推回队列。有没有办法在再次处理作业时记住作业类中属性的值?

例如:

class MailJob extends Job
{
    public $tries = 3;

    public $status;


    public function __construct()
    {
        $this->status = false; // set to false
    }


    /**
     * Execute the job.
     */
    public function handle()
    {
        $this->status = true;
        // Assume job has failed, it went back to the Queue.
        // status should be true when this job start processing again
    }
}
php laravel laravel-5 laravel-5.4
2个回答
2
投票

如果你想在同一时刻再次重新运行失败的进程。你可以做这样的事情。

此处对象在重新运行作业时位于内存中,因此数据可用。

我还没有通过运行来验证它,但希望它能工作

class MailJob extends Job{
public $tries = 3;
public $status;


public function __construct()
{
    $this->status = false; // set to false
}


/**
 * Execute the job.
 */
public function handle()
{
    $this->status = true;
    // Assume job has failed, it went back to the Queue.
    // status should be true when this job start processing again

    $failed = processFailedisConfirm();

    if $failed == true && $this->tries > -1 {
         $this->tries = $this->tries - 1;
         $this->handel();
    }
}}

processFailedisConfirm 的示例可以是

public function processFailedisConfirm(){

     // Core Process to be done in the Job
     $state = (Do Some Api Call); // Here just example, you may send email
                                  // Or can do the core Job Process
                                  // And depending on the Response of the 
                                  // Process return true or false

     // Is Job failed or not ?
     if ( $state == "200" ){
     return false; // Job is not failed
     } else {
     return true; // Job is failed
}

进程逻辑失败与否取决于您正在执行的操作。当我进行 api 调用时,如果我得到 200 的响应,我的过程就成功了。 否则过程失败。 这只是一个例子,不同 api 的成功响应可能与 api 设计者的设计不同。


0
投票

不幸的是,Laravel 不会在其失败之前重新序列化处于其状态的作业以重新排队。

这意味着,当作业从

queue:retry
第二次运行时,您在作业构造函数之外设置的任何属性都不会在作业上恢复。

您可以通过创建一个设置属性的排队作业来自己测试,然后抛出异常。在随后的尝试中,该属性仍等于其默认值。

在下面的示例中,通过

queue:work
运行队列工作程序将导致作业被尝试两次。在第二次尝试(尝试)时,
$this->prop
的值仍然是
false
,即使它在第一次尝试时被设置为
true

namespace App;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class TestJob implements ShouldQueue
{
    use InteractsWithQueue;

    public $prop = false;

    public $tries = 2;

    public function handle(): void
    {
        if ($this->attempts() === 1) {
            $this->prop = true;
        } else {
            dd($this->prop);
        }

        throw new \Exception();
    }
}

您将不得不使用缓存,或与数据库交互以保存作业状态。

如果使用缓存,您可以使用作业的 ID 作为该特定作业的唯一缓存键:

public function handle(): void
{
    // Generate the value (on first run) or retrieve the value (on subsequent runs).
    $value = Cache::rememberForever($this->job->getJobId(), function () {
        return 'some-value'; 
    });

    // Process the job...

    // Remove the value from the cache.
    Cache::forget($this->job->getJobId());
}

在作业的后续尝试和重试中,缓存的值将被检索,允许您检索第一次运行的值,而不是再次检索它。

© www.soinside.com 2019 - 2024. All rights reserved.