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

Static Variables Persist Across Queue Tasks in Laravel 6: A Fix

Reference: https://www.shuijingwanwq.com/2022/07/15/6796/ . In Laravel 6 queue jobs, handling task failures (setting and getting static variables). However, there is a bug: if it is not reset in the next queue job, the previous value is reused. I printed the static variable self::$destination in two separate jobs. I expected the destination for job 755 to be null, but it reused the value from job 754

1. Reference: In Laravel 6 queue jobs, handling task failures (setting and getting static variables). However, there is a bug: if it is not reset in the next queue job, the previous value is reused. I printed the static variable self::$destination in two separate jobs. I expected the destination for job 755 to be null, but it reused the value from job 754. See Figure 1.

Reference: https://www.shuijingwanwq.com/2022/07/15/6796/ . In Laravel 6 queue jobs, handling task failures (setting and getting static variables). However, there is a bug: if it is not reset in the next queue job, the previous value is reused. I printed the static variable self::$destination in two separate jobs. I expected the destination for job 755 to be null, but it reused the value from job 754
Figure 1
PHP

    private static ?string $destination = null; // 解压缩 ZIP 文件后的目录

	Log::info(
		'destination',
		[
			'id' => $this->themeInstallationTask->id,
			'destination' => self::$destination
		]
	);

Plaintext

[2023-04-14 13:37:18] local.INFO: uploadThemeAssetToCdn {
    "id": 754,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/14/1681450622.2291.583840996"
} 
[2023-04-14 13:38:06] local.INFO: uploadThemeAssetToCdn {
    "id": 755,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/14/1681450622.2291.583840996"
} 

2. If the static variable is explicitly reset to null in the next queue job, it gets overwritten. I printed the static variable self::$destination in both jobs, and the results matched expectations. See Figure 2.

If the static variable is explicitly reset to null in the next queue job, it gets overwritten. I printed the static variable self::$destination in both jobs, and the results matched expectations
Figure 2
PHP

    private static ?string $destination = null; // 解压缩 ZIP 文件后的目录

	self::$destination = null;

	Log::info(
		'uploadThemeAssetToCdn',
		[
			'id' => $this->themeInstallationTask->id,
			'destination' => self::$destination
		]
	);

Plaintext

[2023-04-14 13:44:46] local.INFO: uploadThemeAssetToCdn {
    "id": 756,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/14/1681451070.5331.338264899"
} 
[2023-04-14 13:45:34] local.INFO: uploadThemeAssetToCdn {
    "id": 757,
    "destination": null
} 

3. However, referencing the implementation of exponential backoff during queue job retries in Laravel 6, trying to pass the static variable to the next queue job still causes mutual overwriting. In the handle method, I expected the value for job 760 to not be null, but it has now been overwritten by the null value from job 761. See Figure 3.

However, referencing the implementation of exponential backoff during queue job retries in Laravel 6, trying to pass the static variable to the next queue job still causes mutual overwriting. In the handle method, I expected the value for job 760 to not be null, but it has now been overwritten by the null value from job 761
Figure 3
PHP

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

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(ThemeInstallationTask $themeInstallationTask, ?string $absolutePath, ?string $destination)
    {
        // 队列任务构造器中接收了 Eloquent 模型,将会只序列化模型的 ID
        $this->themeInstallationTask = $themeInstallationTask;
        self::$absolutePath = $absolutePath;
        self::$destination = $destination;
        Log::info(
            'construct',
            [
                'id' => $this->themeInstallationTask->id,
                'destination' => self::$destination
            ]
        );
    }

    /**
     * Execute the job.
     *
     * @return void
     * @throws OverflowException
     */
    public function handle()
    {
        Log::info(
            'handle',
            [
                'id' => $this->themeInstallationTask->id,
                'destination' => self::$destination
            ]
        );
		
	}

Plaintext

PS E:\wwwroot\object> php artisan queue:work
[2023-04-14 14:06:03][ACuiiTG0Ptuo5Tl3iMCPnREKYZhGTva3] Processing: Jobs\ThemeInstalling
[2023-04-14 14:06:50][ACuiiTG0Ptuo5Tl3iMCPnREKYZhGTva3] Processed:  Jobs\ThemeInstalling
[2023-04-14 14:06:50][xcL1KIALWlYy9edrKD3GpqkWOzCbudSu] Processing: Jobs\ThemeInstalling
[2023-04-14 14:07:22][xcL1KIALWlYy9edrKD3GpqkWOzCbudSu] Processed:  Jobs\ThemeInstalling
[2023-04-14 14:07:22][Ff7Pcd8szupQYVAO2BkQhGJxyoQKrpo8] Processing: Jobs\ThemeAssetUploading
[2023-04-14 14:07:42][Ff7Pcd8szupQYVAO2BkQhGJxyoQKrpo8] Processed:  Jobs\ThemeAssetUploading
[2023-04-14 14:07:42][Nyc3IPP2mXHz3Hl2tT4RADsKNTAhxf1l] Processing: Jobs\ThemeAssetUploading
[2023-04-14 14:07:45][Nyc3IPP2mXHz3Hl2tT4RADsKNTAhxf1l] Processed:  Jobs\ThemeAssetUploading
[2023-04-14 14:07:45][gaMvLrJttc4Ws1qu2rAAsORFGAfPNZmq] Processing: Jobs\ThemeInstalled
[2023-04-14 14:07:45][gaMvLrJttc4Ws1qu2rAAsORFGAfPNZmq] Processed:  Jobs\ThemeInstalled
[2023-04-14 14:07:45][QALQV7djT9caKVH50HHZLe0x3OScalBP] Processing: Jobs\ThemeInstalled
[2023-04-14 14:07:45][QALQV7djT9caKVH50HHZLe0x3OScalBP] Processed:  Jobs\ThemeInstalled


[2023-04-14 14:06:19] local.INFO: uploadThemeAssetToCdn {
    "id": 760,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/14/1681452363.3555.1473533151"
} 
[2023-04-14 14:06:19] local.INFO: construct {
    "id": 760,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/14/1681452363.3555.1473533151"
} 
[2023-04-14 14:06:53] local.INFO: uploadThemeAssetToCdn {
    "id": 761,
    "destination": null
} 
[2023-04-14 14:06:53] local.INFO: construct {
    "id": 761,
    "destination": null
} 
[2023-04-14 14:07:22] local.INFO: handle {
    "id": 760,
    "destination": null
} 
[2023-04-14 14:07:22] local.INFO: destination {
    "id": 760,
    "destination": null
} 
[2023-04-14 14:07:42] local.INFO: destination {
    "id": 760,
    "destination": null
} 
[2023-04-14 14:07:42] local.INFO: handle {
    "id": 761,
    "destination": null
} 
[2023-04-14 14:07:42] local.INFO: destination {
    "id": 761,
    "destination": null
} 
[2023-04-14 14:07:45] local.INFO: destination {
    "id": 761,
    "destination": null
} 

4. I ultimately decided to abandon static variables and store the corresponding values in the MySQL table records related to the queue jobs. The queue jobs no longer interfere with each other, which meets expectations. See Figure 4.

I ultimately decided to abandon static variables and store the corresponding values in the MySQL table records related to the queue jobs. The queue jobs no longer interfere with each other, which meets expectations
Figure 4
JSON

{
  "theme_download_paths": {
    "zip_path": "/theme_downloads/2023/04/17/1681696283.1861.462360447.zip",
    "destination": "/theme_downloads/2023/04/17/1681696283.1861.462360447"
  }
}

Plaintext

PS E:\wwwroot\object> php artisan queue:work
[2023-04-17 09:51:22][0Ta6TjtzacnMmI50uh9Ti3s9qfh5c5H1] Processing: Jobs\ThemeInstalling
[2023-04-17 09:52:21][0Ta6TjtzacnMmI50uh9Ti3s9qfh5c5H1] Processed:  Jobs\ThemeInstalling
[2023-04-17 09:52:21][dcjXRXkV2XgHdhQrGkYy3Yyq9vy7iiDh] Processing: Jobs\ThemeInstalling
[2023-04-17 09:52:59][dcjXRXkV2XgHdhQrGkYy3Yyq9vy7iiDh] Processed:  Jobs\ThemeInstalling
[2023-04-17 09:52:59][v8MkfSZlf6PtoXi8tqNcDb4SXCp6KTGk] Processing: Jobs\ThemeAssetUploading
[2023-04-17 09:53:02][v8MkfSZlf6PtoXi8tqNcDb4SXCp6KTGk] Processed:  Jobs\ThemeAssetUploading
[2023-04-17 09:53:02][Zv1ts0pDpCSiTVoWc9WqmszXj5QUYSF6] Processing: Jobs\ThemeAssetUploading
[2023-04-17 09:53:07][Zv1ts0pDpCSiTVoWc9WqmszXj5QUYSF6] Processed:  Jobs\ThemeAssetUploading
[2023-04-17 09:53:07][K69thLwVkwnkOccdR778hDdMBAL7U4pD] Processing: Jobs\ThemeInstalled
[2023-04-17 09:53:07][K69thLwVkwnkOccdR778hDdMBAL7U4pD] Processed:  Jobs\ThemeInstalled
[2023-04-17 09:53:07][SJPEBLJozJygXiIW9zfJNU1FSGtBmWek] Processing: Jobs\ThemeInstalled
[2023-04-17 09:53:07][SJPEBLJozJygXiIW9zfJNU1FSGtBmWek] Processed:  Jobs\ThemeInstalled

[2023-04-17 14:02:50] local.INFO: destination {
    "id": 799,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/17/1681711238.5778.1671140645"
} 
[2023-04-17 14:02:54] local.INFO: destination {
    "id": 799,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/17/1681711238.5778.1671140645"
} 
[2023-04-17 14:02:56] local.INFO: destination {
    "id": 800,
    "destination": null
} 
[2023-04-17 14:02:57] local.INFO: destination {
    "id": 800,
    "destination": null
} 
[2023-04-17 14:02:57] local.INFO: destination {
    "id": 801,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/17/1681711324.896.2108597779"
} 
[2023-04-17 14:02:59] local.INFO: destination {
    "id": 801,
    "destination": "E:\\wwwroot\\object\\storage\\app/theme_downloads/2023/04/17/1681711324.896.2108597779"
} 

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

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

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

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

关于我  ·  GitHub  ·  邮件联系