1、使用以下 Artisan 命令来为指定的模块生成一个新的队列任务。如图1

图1

PS E:\wwwroot\object> php artisan module:make-job ThemeInstallation ThemeStoreDB
Created : E:/wwwroot/object/Modules/ThemeStoreDB/Jobs/ThemeInstallation.php
PS E:\wwwroot\object>

2、任务分发,推送任务到队列

use Modules\ThemeStoreDB\Jobs\ThemeInstallation as ThemeInstallationJob;

// 推送任务到队列
ThemeInstallationJob::dispatch($themeInstallationTask);

3、编辑 /Modules/ThemeStoreDB/Jobs/ThemeInstallation.php 。队列中的处理示例,主要是将表 theme_installation_task 的字段 step 的值修改为 2。

<?php

namespace Modules\ThemeStoreDB\Jobs;

use Modules\ThemeStoreDB\Entities\ThemeInstallationTask;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ThemeInstallation implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $themeInstallationTask;

    /**
     * Create a new job instance.
     *
     * @return void
     */    public function __construct(ThemeInstallationTask $themeInstallationTask)
    {
        // 队列任务构造器中接收了 Eloquent 模型,将会只序列化模型的 ID
        $this->themeInstallationTask = $themeInstallationTask;
    }

    /**
     * Execute the job.
     *
     * @return void
     */    public function handle()
    {
        $this->themeInstallationTask->step = ThemeInstallationTask::STEP_DOWNLOAD_ZIP;
        $this->themeInstallationTask->save();
    }
}

4、在命令行启动队列系统,队列在启动完成后会进入监听状态:

PS E:\wwwroot\object> php artisan queue:listen

5、调用 API ,任务分发至队列后,可以在命令行中看到监听的状态。如图2

图2

PS E:\wwwroot\object> php artisan queue:listen
[2022-05-18 14:12:39][0brUqtQG1q1J8njW3uyUnrXE16ubcCXs] Processing: Modules\ThemeStoreDB\Jobs\ThemeInstallation
[2022-05-18 14:12:39][0brUqtQG1q1J8njW3uyUnrXE16ubcCXs] Processed:  Modules\ThemeStoreDB\Jobs\ThemeInstallation

6、查看数据表 theme_installation_task 的字段 step 的值已经修改为 2。且 created_at 与 updated_at 分别为:2022-05-18 14:12:37、2022-05-18 14:12:39。修改时间较之创建时间晚了 2 秒钟。符合预期。如图3

图3

7、当 handle 方法抛出异常时,队列任务执行失败,日志信息插入至表 failed_jobs 中。期望将异常的 message 同步插入至表 theme_installation_task 的字段 message 中。如图4

图4

PS E:\wwwroot\object> php artisan queue:listen
[2022-05-18 15:49:45][XFUmrUWBn2muST8AXmRXzjVLUr72UUde] Processing: Modules\ThemeStoreDB\Jobs\ThemeInstallation
[2022-05-18 15:49:45][XFUmrUWBn2muST8AXmRXzjVLUr72UUde] Failed:     Modules\ThemeStoreDB\Jobs\ThemeInstallation

8、在任务类中定义 failed 方法。导致任务失败的 Exception 将被传递给 failed 方法。

<?php

namespace Modules\ThemeStoreDB\Jobs;

use Modules\ThemeStoreDB\Entities\ThemeInstallationTask;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ThemeInstallation implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * 任务可以尝试的最大次数。
     *
     * @var int
     */    public $tries = 1;

    /**
     * 任务可以执行的最大秒数 (超时时间)。
     *
     * @var int
     */    public $timeout = 600;

    protected $themeInstallationTask;

    /**
     * Create a new job instance.
     *
     * @return void
     */    public function __construct(ThemeInstallationTask $themeInstallationTask)
    {
        // 队列任务构造器中接收了 Eloquent 模型,将会只序列化模型的 ID
        $this->themeInstallationTask = $themeInstallationTask;
    }

    /**
     * Execute the job.
     *
     * @return void
     */    public function handle()
    {
        checkhere();
        $this->themeInstallationTask->step = ThemeInstallationTask::STEP_DOWNLOAD_ZIP;
        $this->themeInstallationTask->save();
    }

    /**
     * 任务失败的处理过程
     *
     * @param  Exception  $exception
     * @return void
     */    public function failed(Exception $exception)
    {
        $this->themeInstallationTask->message = $exception->getMessage();
        $this->themeInstallationTask->save();
    }
}

9、异常的 message 同步插入至表 theme_installation_task 的字段 message 中。符合预期。如图5

图5

永夜