pinguo / php-msf

PHP微服务框架即Micro Service Framework For PHP
GNU General Public License v2.0
1.75k stars 317 forks source link

关于对象的生命周期问题? #93

Closed wuchuguang closed 7 years ago

wuchuguang commented 7 years ago
class Test extens Controller{
     private $server;
     public function __construct($controllerName, $methodName){
            parent::__construct($controllerName, $methodName);
            $this->server = $this->server ?? $this->getObject(Server::class);
     }
}
class Server extens Core{
    private $mode;
    public function __construct(){
          $this->model = $this->getObject(MyModel::class);
    }
   public function destroy()
    {
        parent::destroy(); // TODO: Change the autogenerated stub
        $this->model = null;
        echo "destory\n";
    }
    public function __destruct()
    {
        echo "__destruct\n";
    }
}

多worker时=4, 前4次请求会Test 调用:?? $this->getObject(Server::class);//因为每个worker都会初始一次server 这4次请求是很正常的。 第5次请求时,?? $this->getObject(Server::class);不会调用了。因为private $server被前4次设值了。

导至Server的construct不会调用到。 那么为什么前4次明明private $server是非public的,而它的Server实例下的destroy会被调用到。 而且destruct析构函数也调用了。

第五次没有?? $this->getObject(Server::class);,那$server中的$model就不会this->getObject(MyModel::class);//那这时的$model一直是null了。。。

wuchuguang commented 7 years ago

如果这不是个bug.那我们只有放弃了。。。msf

xudianyang commented 7 years ago

1.这个问题我完全理解,示例代码中$server通过对象池生成了,对象池策略默认是要自动走归还和释放逻辑; 2.那么为什么前4次明明private $server是非public的,而它的Server实例下的destroy会被调用到。不管属于是public,private,destory方法和析构一定会调用,而这里destory方法里面显示$this->model = null 3.第五次没有执行构造方法,是因为你$server本身是private的,的确不为null,所以就没有去对象池获取对象;

总结一下,还是对对象池策略没有理解清楚。

解决方案,不要在private修饰$server和$mode,不理解你为什么要这么用?

wuchuguang commented 7 years ago

@xudianyang 想充份压炸对象池提供的服务。 后面我想了想,跟你第二条的一样。 因为对象池没有办法存对象关联(关系),所以无法感知$server这个对象不该回收(调用destory). runkit支持7.1了,如果想达到我心想的,估计可以试试这个.

wuchuguang commented 7 years ago

还有个问题,private/protected不会自动处理的属性,是否必需 destory(){ xxx= null;//或unset($this->xxx) } 手动消毁,才不会导致后面对象池错乱/溢出呢。。。 因为新的__construct又会this->getObject();//出来。还是说这里会get原来的呢?