关于批次队列Bus 的回调函数callback 内部调用$this 指向内存泄漏的问题[已踩坑]

Laravel: 8.x
PHP: 7.3
OS: MAC

我现在有 job1 和job-batch 队列若干

job1有问题代码:

       Bus::batch($jobs)
            // 所有任务完成才执行的回调
            ->finally(function (Batch $batch) {

                if ($batch->finished()) {
                    dispatch(new BeforeLoanExportFinishJob($this->task->id));
                }

            })->dispatch();

job1正常代码:

$taskId = $this->task->id;

        Bus::batch($jobs)
            // 所有任务完成才执行的回调
            ->finally(function (Batch $batch) use ($taskId) {

                if ($batch->finished()) {
                    dispatch(new BeforeLoanExportFinishJob($taskId));
                }

            })->dispatch();

报错:
直接是 500 Server error ,502 bad way ,前面是服务器错误,后者大概率是内存过大,超时

根本原因来自 批次队列的 finally 回调内部调用了 $this 造成了内部循环引用,内存无法释放,这个位置大家一定要避坑,很难调试

下面放上这个issue地址:
Referencing $this within batch callback depletes memory

关于批次队列Bus 的回调函数callback 内部调用$this 指向内存泄漏的问题

job1 使用了外部传入对象

/**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Task $task)
    {
        //
        $this->task = $task;
    }

job1 内有调用了batch 队列, 再使用batch 队列回调的时候, 内部调用了this ,结果就是把外层的队列给序列化,提示的错误是pdo 无法支持序列化,就是因为再batch 的回调内使用了this

finally 回调里面如果是闭包,执行的是序列化的操作,会导致序列化失败

关于批次队列Bus 的回调函数callback 内部调用$this 指向内存泄漏的问题

local.ERROR: You cannot serialize or unserialize PDO instances {"exception":"[object] (PDOException(code: 0): You cannot serialize or unserialize PDO instances at /Users/raybon/TaiFinance/www/download-center/vendor/opis/closure/src/SerializableClosure.php:155)
[stacktrace]

使用批次队列正确的方式:

关于批次队列Bus 的回调函数callback 内部调用$this 指向内存泄漏的问题

后面使用过程中,切记 this 直接调用,会造成内存泄漏

8.x 版本 还没文档提示

关于批次队列Bus 的回调函数callback 内部调用$this 指向内存泄漏的问题

9.x 版本已经更新了提示:

关于批次队列Bus 的回调函数callback 内部调用$this 指向内存泄漏的问题

[9.x] Add note to ‘Chain Failures’ and ‘Queueing Closures’ section to not use ‘$this’ in callbacks

本作品采用《CC 协议》,转载必须注明作者和本文链接
每天一点小知识,到那都是大佬,哈哈
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!