没有不值得去解决的问题,也没有不值得去学习的技术!

Handling Task Failure in Laravel 6 Queue Jobs: Setting and Getting Static Variables

当解压缩失败:Call to undefined function Modules\ThemeStoreDB\Handlers\checkhere() 时,也需要删除掉对应的 zip 文件,就需要在 failed(Exception $exception) 方法中实现。但是,需要获取到 zip 文件的绝对路径。 暂未实现。查看未删除的 zip 文件。

1. In a queue job, I need to first download a zip file and then extract it. Now, after the extraction succeeds, the downloaded zip file needs to be deleted. This has been implemented.

PHP

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
            // 下载 ZIP
            $downloadZipRes = $this->downloadZip();

            // 解压缩 ZIP
            $this->unzip($downloadZipRes['destination'], $downloadZipRes['absolutePath']);

    }

    /**
     * 解压缩 ZIP
     *
     * @param string $destination 解压缩至的本地目标路径
     * @param string $absolutePath 待解压缩的文件的绝对路径
     * @return void
     */
    private function unzip($destination, $absolutePath)
    {
        $this->themeInstallationTask->step = ThemeInstallationTask::STEP_UNZIP;
        $this->themeInstallationTask->save();

        app(ZipHandler::class)->unzip($destination, $absolutePath);

        // 删除 ZIP
        Storage::disk('local')->delete(substr($absolutePath, strlen(storage_path('app') . '/')));
    }

    /**
     * 解压缩 ZIP
     * @param string $destination 解压缩至的本地目标路径
     * @param string $entrie 待解压缩的文件的绝对路径
     * @return void
     */
    public function unzip($destination, $entrie)
    {
        checkhere();
        if ($this->zipArchive->open($entrie) === TRUE) {
            $this->zipArchive->extractTo($destination);
            $this->zipArchive->close();
        } else {
            abort(500, 'Unzip failed.');
        }
    }

2. When the extraction fails: Call to undefined function Modules\ThemeStoreDB\Handlers\checkhere(), the corresponding zip file also needs to be deleted, which must be implemented in the failed(Exception $exception) method. However, I need to obtain the absolute path of the zip file. This is not yet implemented. View the undeleted zip file. As shown in Figure 1.

When the extraction fails: Call to undefined function Modules\ThemeStoreDB\Handlers\checkhere(), the corresponding zip file also needs to be deleted, which must be implemented in the failed(Exception $exception) method. However, I need to obtain the absolute path of the zip file. This is not yet implemented. View the undeleted zip file.
Figure 1

3. In the table: failed_jobs, view the value of the field: payload.

JSON

{
  "displayName": "Modules\\ThemeStoreDB\\Jobs\\ThemeInstallationJob",
  "job": "Illuminate\\Queue\\CallQueuedHandler@call",
  "maxTries": 1,
  "delay": null,
  "timeout": 600,
  "timeoutAt": null,
  "data": {
    "commandName": "Modules\\ThemeStoreDB\\Jobs\\ThemeInstallationJob",
    "command": "O:46:\"Modules\\ThemeStoreDB\\Jobs\\ThemeInstallationJob\":11:{s:5:\"tries\";i:1;s:7:\"timeout\";i:600;s:24:\"\u0000*\u0000themeInstallationTask\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":4:{s:5:\"class\";s:51:\"Modules\\ThemeStoreDB\\Entities\\ThemeInstallationTask\";s:2:\"id\";i:22;s:9:\"relations\";a:0:{}s:10:\"connection\";s:5:\"mysql\";}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";N;s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:5:\"delay\";N;s:10:\"middleware\";a:0:{}s:7:\"chained\";a:0:{}}"
  },
  "telescope_uuid": "96a60a99-dbb8-40a4-8054-2694435b46be",
  "tenant_name": "chengdu-wangqiang-object-local",
  "id": "lX7QOFkBy5VwjNBSx5OekUISzvXU7ess",
  "attempts": 0
}

4. To obtain the absolute path of the zip file, one approach is to store it in a MySQL table, and another is to assign it to a Job object property. I decide to use the second approach.

PHP


    private $absolutePath; // 待解压缩的 ZIP 文件的绝对路径
    private $destination; // 解压缩 ZIP 文件后的目录

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
            // 下载 ZIP
            $downloadZipRes = $this->downloadZip();

            // 解压缩 ZIP
            $this->absolutePath = $downloadZipRes['absolutePath'];
            $this->unzip($downloadZipRes['destination']);



    }

    /**
     * 任务失败的处理过程
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception)
    {

        if (isset($this->absolutePath)) {
            // 删除 ZIP
            Storage::disk('local')->delete(substr($this->absolutePath, strlen(storage_path('app') . '/')));
        }

    }

5. However, after the extraction fails, the zip file is not deleted because $this->absolutePath is null. It has a value in the handle() method, but it is null in failed().

6. I decide to change absolutePath to a static variable. Its value in failed() is: E:\wwwroot\object\storage\app/theme_downloads/2022/06/29/1656468032.6555.1798260415.zip

PHP


    private static $absolutePath; // 待解压缩的 ZIP 文件的绝对路径
    private static $destination; // 解压缩 ZIP 文件后的目录

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
            // 下载 ZIP
            $downloadZipRes = $this->downloadZip();

            // 解压缩 ZIP
            self::$absolutePath = $downloadZipRes['absolutePath'];
            $this->unzip($downloadZipRes['destination']);



    }

    /**
     * 任务失败的处理过程
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception)
    {

        if (isset(self::$absolutePath)) {
            // 删除 ZIP
            Storage::disk('local')->delete(substr(self::$absolutePath, strlen(storage_path('app') . '/')));
        }

    }

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系