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

Investigating Incomplete Queue Task Execution in Laravel

Simulation scenario one confirmed that after interrupting the queue task, the subsequent process of the program would no longer execute when it reached the step to sync the theme assets to the CDN. Its final behavior was consistent with step one. Then, I started php artisan queue:work again and confirmed that the queue task had been lost

1. Install a theme that is implemented based on queues. The code is as follows:

PHP

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // 判断 原始主题ID 是否为空,为空则为安装主题,否则为复制主题
        if (empty($this->themeInstallationTask->themeInstallation->original_theme_id)) {
            // 下载 ZIP
            $downloadZipRes = $this->downloadZip();

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

            // 执行安装命令
            self::$destination = $downloadZipRes['destination'];
            $this->execInstallationCommand($this->themeInstallationTask->themeInstallation->theme_id);

        } else {
            // 复制主题文件
            $this->copyThemeAsset();
        }

        // 同步主题的素材至CDN
        $this->syncThemeAssetCdn($this->themeInstallationTask->themeInstallation->theme_id);

        $this->themeInstallationTask->themeInstallation->processing = ThemeInstallation::PROCESSING_FALSE;
        $this->themeInstallationTask->themeInstallation->processing_failed = ThemeInstallation::PROCESSING_FAILED_FALSE;

        $this->themeInstallationTask->themeInstallationVersionPreset->processing = ThemeInstallationVersionPreset::PROCESSING_FALSE;
        $this->themeInstallationTask->themeInstallationVersionPreset->processing_failed = ThemeInstallationVersionPreset::PROCESSING_FAILED_FALSE;

        $this->themeInstallationTask->processing = ThemeInstallationTask::PROCESSING_FALSE;
        $this->themeInstallationTask->processing_failed = ThemeInstallationTask::PROCESSING_FAILED_FALSE;

        $this->themeInstallationTask->push();

        event(new ThemeCreated($this->themeInstallationTask->themeInstallation->theme));

    }

2. Based on the preliminary analysis, when executing the step to sync the theme assets to the CDN, the program execution seemed to suddenly interrupt. The observed behavior is shown in Figure 1.

Based on the preliminary analysis, when executing the step to sync the theme assets to the CDN, the program execution seemed to suddenly interrupt. The observed behavior.
Figure 1

3. It felt as if the container restarted when executing the step to sync the theme assets to the CDN, which in turn caused the program execution to interrupt. I decided to simulate this in the local environment by adding sleep(60) when executing the step to sync the theme assets to the CDN.

PHP

    /**
     * 同步主题的素材至CDN
     *
     * @param string $themeId 主题 ID
     * @return void
     */
    private function syncThemeAssetCdn($themeId)
    {
        $this->themeInstallationTask->step = ThemeInstallationTask::STEP_SYNC_THEME_ASSET_CDN;
        $this->themeInstallationTask->save();

        // 程序开始的地方

        app(ExecCommandHandler::class)->syncThemeAssetCdn($themeId);

        sleep(60);

        // 程序结束的地方,中途未抛出异常
    }

4. The process for simulation scenario one is: when execution reaches sleep(60), interrupt the queue task and manually stop the queue worker. See Figure 2.

The process for simulation scenario one is: when execution reaches sleep(60), interrupt the queue task and manually stop the queue worker
Figure 2
Plaintext

PS E:\wwwroot\object> php artisan queue:work
[2022-08-04 13:57:07][tnFIT28iqbv67GpZ2xwzP6hRFEaJJ6vh] Processing: Modules\ThemeStoreDB\Jobs\ThemeInstallationJob
PS E:\wwwroot\object>

5. Simulation scenario one confirmed that after interrupting the queue task, the subsequent process of the program would no longer execute when it reached the step to sync the theme assets to the CDN. Its final behavior was consistent with step one. Then, I started php artisan queue:work again and confirmed that the queue task had been lost. See Figure 3.

Simulation scenario one confirmed that after interrupting the queue task, the subsequent process of the program would no longer execute when it reached the step to sync the theme assets to the CDN. Its final behavior was consistent with step one. Then, I started php artisan queue:work again and confirmed that the queue task had been lost
Figure 3

6. The process for simulation scenario two is: when execution reaches sleep(60), manually stop the PHP program. See Figure 4.

The process for simulation scenario two is: when execution reaches sleep(60), manually stop the PHP program
Figure 4
Plaintext

PS C:\Windows\system32> php-cgi.exe -b 127.0.0.1:9001-c C:/php-7.4.27/php.ini
PS C:\Windows\system32>

7. Simulation scenario two confirmed that after stopping the PHP program, the subsequent process of the program would no longer execute when it reached the step to sync the theme assets to the CDN. Its final behavior was consistent with step one. However, if php artisan queue:work remained running at this time, the queue task could still finish executing after the PHP program was started again.

8. The temporary workaround for this issue is to dispatch a new queue task. I will find a way to thoroughly resolve it later.

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

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

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

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

关于我  ·  GitHub  ·  邮件联系