Workerman 5 errorHandler 为啥要绑定每个TCP连接上?
问题描述
class TcpConnection {
public $errorHandler = null;
public function error(Throwable $exception): void
{
if (!$this->errorHandler) {
Worker::stopAll(250, $exception);
return;
}
try {
($this->errorHandler)($exception);
} catch (Throwable $exception) {
if ($this->eventLoop instanceof Event) {
echo $exception;
return;
}
throw $exception;
}
}
}
为什么不直接设置为全局Handler,比如:
$worker = new Worker("http://0.0.0.0:8888");
$worker->errorHandler = function($e) {
Worker::log(xxx);
}
或者这样
Worker::$errorHandler = function($e) {write log..}
class Worker {
public $errorHandler = null;
// 或者下面这样呢?
// public static $errorHandler = null;
public static function error(Throwable $exception): void
{
if (!$this->errorHandler) {
Worker::stopAll(250, $exception);
return;
}
try {
($this->errorHandler)($exception);
} catch (Throwable $exception) {
if (static::$globalEvent instanceof Event) {
echo $exception;
return;
}
throw $exception;
}
}
}
// 这样做不是更加节省内存,性能更好一些。但每个TCP都绑定errorHandler有其它原因呢?
// 如果在长连接场景,连接都不断开errorHandler会存在挺多,全局这样就只有一份。
1个回答
年代过于久远,无法发表回答
为了解耦,方便给每个连接定制化错误处理,还有方便做单元测试。
$errorHandler = 'myHanlder'; 这种不会占用多少内存。
try {
// Decode request buffer before Emitting onMessage callback.
/* @var ProtocolInterface $parser /
$parser = $this->protocol;
$request = $parser::decode($oneRequestBuffer, $this);
if (static::$enableCache && (!is_object($request) || $request instanceof Request) && $one && !isset($oneRequestBuffer[512])) {
$requests[$oneRequestBuffer] = $request;
if (count($requests) > 512) {
unset($requests[key($requests)]);
}
}
($this->onMessage)($this, $request);
} catch (Throwable $e) {
$this->error($e);
}
如果 deocde 抛出异常,worker 会被干掉,这样是不是不太好!
不是守护进程模式,直接echo $exception, 守护进程直接写入日志文件这样不是更加好?
这样退出进程然后输出到终端有什么原因?
协议解析出问题是致命问题
$worker->reloadable = false; 本身是不是无效的,亲测无效。
$worker->reloadable = true; worker 退出重启修改代码文件有效,亲测可行。
我感觉reloadable 属性设置为false没有意义呢。
我理解的原理:
master 启动时候include 所有文件,worker 继承 master 所有加载的文件,然后重新读取常驻内存。
如果不重启worker,就还是常驻内存之前的效果一样的吧!
https://www.workerman.net/doc/workerman/worker/reloadable.html 这篇文章链接reloadable = false 是不是需要改一改?
应该是没有用的,没办法更新业务代码。
“设置gateway进程的reloadable属性为false则在reload可以做到在不断开客户端连接的情况下更新业务代码。”
这句话是不是应该删除掉,好像没有用呢。
哥们是不是阅读理解有问题,
这个
reloadable
属性是用来 人工设置是否响应reload 代码,gatewayworker模式下gateway不能reload因为用户长链接这个gateway, 而bussiness需要reload,register也不需要reload。所以明白了吗如果只有一种类型的进程 这个reloadable 确实没啥用,多个不同类型的进程,有些需要reload,有些不需要懂了么。
worker收到信号就会fork_new 然后include_once,因为是刚刚fork的,所以会重新读入代码
感谢,懂了。哈哈哈
@admin 语文老师