自定义类继承自Worker,reload失败

zhouciming

用的是workerman框架,我自定义了一个Server类(继承自Worker), 但是运行起来后,onWorkerStart和onMessage都没问题,但是用php start.php reload,脚本就卡住了,后来一检查,发现似乎是php start.php start跑完后,有进程没跑完!因为当我按Ctrl+C停止进程后,能进入处理reload的地方了,所以不知道问题在哪里,能帮忙看下吗,感激不尽。

start_xxx.php:
<?php
/**
 * Created by PhpStorm.
 * User: zcm
 * Mail: zhouciming@163.com
 * Date: 2018/10/10 下午2:16
 */

use Workerman\Worker;
use Common\Config;
use Common\MyDb;
use think\Db;
use Server\Server;

require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../autoload.php';
//
//$config = Config::get('server.global');
//print_r($config);

$worker = new Server("tcp://0.0.0.0:2345");

// 4 processes
$worker->count = 1;

// Emitted when data received
//$worker->onMessage = function($connection, $data)
//{
//  echo "in callback onMessage\n";
//  print_r($data);
//  $connection->send("hello world2256 \n");
//};
////
//$worker->onWorkerStart = function($worker)
//{
//  if(MyDb::init())
//  {
//      $rows = Db::name('users')
//          ->field('id,user_nicename')
//          ->where('id=239851')
//          ->select();
//
//      print_r($rows);
//
//      $a = MyDb::$redis->get('hello');
//      print_r($a);
//  }
//};

// run all workers
if(!defined('GLOBAL_START'))
{
    Worker::runAll();
}

Server\Server.php
<?php
/**
 * Created by PhpStorm.
 * User: zcm
 * Mail: zhouciming@163.com
 * Date: 2018/10/11 上午9:50
 */

//namespace Center\Server;
namespace Server;

use Workerman\Worker;

class Server extends Worker
{
    /**
     * 保存用户设置的 workerStart 回调
     *
     * @var callback
     */
    protected $_onWorkerStart = null;

    /**
     * 保存用户设置的 workerReload 回调
     *
     * @var callback
     */
    protected $_onWorkerReload = null;

    /**
     * 保存用户设置的 workerStop 回调
     *
     * @var callback
     */
    protected $_onWorkerStop= null;

    /**
     * 保存用户设置的 onMessage 回调
     *
     * @var callback
     */
    protected $_onMessage= null;

    public function __construct($socket_name = '', array $context_option = array())
    {
        parent::__construct($socket_name, $context_option);
        $backrace                = debug_backtrace();
        $this->_autoloadRootPath = dirname($backrace);
    }

    public function run()
    {
        // 保存用户设置的回调函数
        $this->_onWorkerStart  = $this->onWorkerStart;
        $this->_onWorkerReload = $this->onWorkerReload;
        $this->_onWorkerStop = $this->onWorkerStop;
        $this->_onMessage = $this->onMessage;

        // 设置本类的接口
        $this->onWorkerStart   = array($this, 'onWorkerStart');
        $this->onWorkerReload  = array($this, 'onWorkerReload');
        $this->onWorkerStop   = array($this, 'onWorkerStop');
        $this->onMessage   = array($this, 'onMessage');

        parent::run();
    }

    /**
     * 当进程启动时一些初始化工作
     *
     * @return void
     */
    public function onWorkerStart()
    {
        echo "in Server::onWorkerStart\n";

        if ($this->_onWorkerStart) {
            call_user_func($this->_onWorkerStart, $this);
        }
    }

    public function onWorkerStop()
    {
        echo "in Server::onWorkerStop\n";

        if ($this->_onWorkerStop) {
            call_user_func($this->_onWorkerStop, $this);
        }
    }

    public function onWorkerReload($worker)
    {
        echo "in Server::onWorkerReload\n";

//      if ($this->_onWorkerReload) {
//          call_user_func($this->_onWorkerReload, $this);
//      }

        // 防止进程立刻退出
        $worker->reloadable = false;
        // 延迟 0.05 秒退出,避免 BusinessWorker 瞬间全部退出导致没有可用的 BusinessWorker 进程
        Timer::add(0.05, array('Workerman\Worker', 'stopAll'));
        // 执行用户定义的 onWorkerReload 回调
        if ($this->_onWorkerReload) {
            call_user_func($this->_onWorkerReload, $this);
        }
    }

    public function onMessage($connection, $data)
    {
        echo "in Server::onMessage\n";

        print_r($data);

        if ($this->_onMessage) {
            call_user_func($this->_onMessage, $connection, $data);
        }
    }
}

Server.php参考Gateway类改的!
 
我经过断点调试,已经跑完了Worker::run(),static::$globalEvent->loop();

这句话也跑了!然后我就知道去哪里了,应该是进入正常的事件循环吧,可是为何reload无法得到处理呢?还请大神解答下, Thank you!

2471 2 0
2个回答

walkor

不要继承Worker,因为有可能改变了它的某些行为导致不可预知的结果。
你可以在Worker的继承上包装一层,而不是继承它

  • zhouciming 2018-10-12

    你是指自己写个类,弄个成员变量是Worker,然后再使用!?
    但是我看你的Gateway也是继承自Worker,而且是ok的!
    另外,我看了自己5年前的代码(Workerman版本3.2.2),也是自定义了一个类,继承自Worker,使用完全没问题,用reload也是完全正常的,你可以帮我跑下那个Server吗,试试为什么start后似乎没跑完,卡在哪了?万分感激!

  • walkor 2018-10-12

    发一个完整的压缩包上来吧

  • zhouciming 2018-10-12

    我在给您整理压缩包时,又试了下reload,发现并不是没用,而是我的phpstorm开启了调试,卡在断点那了,我观察不够仔细,抱歉!
    去除断点后,已经可以正常处理reload, stop等了!

  • walkor 2018-10-12

    好吧

  • zhouciming 2018-10-12

    @1:楼下的问题,请帮忙看下,谢谢

zhouciming
public function run()
    {
        // 保存用户设置的回调函数
        $this->_onWorkerStart  = $this->onWorkerStart;
        $this->_onWorkerReload = $this->onWorkerReload;
        $this->_onWorkerStop = $this->onWorkerStop;
        $this->_onMessage = $this->onMessage;

        // 关联基类成员至本类接口
        $this->onWorkerStart   = array($this, 'onWorkerStart');
        $this->onWorkerReload  = array($this, 'onWorkerReload');
        $this->onWorkerStop   = array($this, 'onWorkerStop');
        $this->onMessage   = array($this, 'onMessage');

        parent::run();
    }

    /**
     * 当进程启动时一些初始化工作
     *
     * @return void
     */
    public function onWorkerStart()
    {
        echo "in Server::onWorkerStart22244\n";

        if ($this->_onWorkerStart) {
            call_user_func($this->_onWorkerStart, $this);
        }
    }

    public function onWorkerStop()
    {
        echo "in Server::onWorkerStop\n";

        if ($this->_onWorkerStop) {
            call_user_func($this->_onWorkerStop, $this);
        }
    }

    public function onWorkerReload($worker)
    {
        echo "in Server::onWorkerReload" . $worker->reloadable . PHP_EOL;

        // 防止进程立刻退出
        $worker->reloadable = false;
        // 延迟 0.05 秒退出,避免 BusinessWorker 瞬间全部退出导致没有可用的 BusinessWorker 进程
        Timer::add(0.05, array('Workerman\Worker', 'stopAll'));
        // 执行用户定义的 onWorkerReload 回调
        if ($this->_onWorkerReload) {
            call_user_func($this->_onWorkerReload, $this);
        }
    }

    public function onMessage($connection, $data)
    {
        echo "in Server::onMessage\n";

        print_r($data);

        if ($this->_onMessage) {
            call_user_func($this->_onMessage, $connection, $data);
        }
    }

想请问下,我这里添加的这几个接口实现会改变worker的原始行为吗?请帮忙检查下,特别是onWorkerReload的实现,那样写合理吗,我是参考gatewayworker中BusinessWorker的实现写的!如果没什么问题,我将会在这个框架上增加代码!

  • 暂无评论
年代过于久远,无法发表回答
🔝