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;
}
}
}
為什么不直接設(shè)置為全局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;
}
}
}
// 這樣做不是更加節(jié)省內(nèi)存,性能更好一些。但每個(gè)TCP都綁定errorHandler有其它原因呢?
// 如果在長(zhǎng)連接場(chǎng)景,連接都不斷開errorHandler會(huì)存在挺多,全局這樣就只有一份。
為了解耦,方便給每個(gè)連接定制化錯(cuò)誤處理,還有方便做單元測(cè)試。
$errorHandler = 'myHanlder'; 這種不會(huì)占用多少內(nèi)存。
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 會(huì)被干掉,這樣是不是不太好!
不是守護(hù)進(jìn)程模式,直接echo $exception, 守護(hù)進(jìn)程直接寫入日志文件這樣不是更加好?
這樣退出進(jìn)程然后輸出到終端有什么原因?
$worker->reloadable = false; 本身是不是無(wú)效的,親測(cè)無(wú)效。
$worker->reloadable = true; worker 退出重啟修改代碼文件有效,親測(cè)可行。
我感覺(jué)reloadable 屬性設(shè)置為false沒(méi)有意義呢。
我理解的原理:
master 啟動(dòng)時(shí)候include 所有文件,worker 繼承 master 所有加載的文件,然后重新讀取常駐內(nèi)存。
如果不重啟worker,就還是常駐內(nèi)存之前的效果一樣的吧!
http://www.wtbis.cn/doc/workerman/worker/reloadable.html 這篇文章鏈接reloadable = false 是不是需要改一改?
應(yīng)該是沒(méi)有用的,沒(méi)辦法更新業(yè)務(wù)代碼。
“設(shè)置gateway進(jìn)程的reloadable屬性為false則在reload可以做到在不斷開客戶端連接的情況下更新業(yè)務(wù)代碼。”
這句話是不是應(yīng)該刪除掉,好像沒(méi)有用呢。
哥們是不是閱讀理解有問(wèn)題,
執(zhí)行php start.php reload時(shí)會(huì)向所有子進(jìn)程發(fā)送reload信號(hào)(SIGUSR1)。
這個(gè)reloadable
屬性是用來(lái) 人工設(shè)置是否響應(yīng)reload 代碼,gatewayworker模式下gateway不能reload因?yàn)橛脩糸L(zhǎng)鏈接這個(gè)gateway, 而bussiness需要reload,register也不需要reload。所以明白了嗎
如果只有一種類型的進(jìn)程 這個(gè)reloadable 確實(shí)沒(méi)啥用,多個(gè)不同類型的進(jìn)程,有些需要reload,有些不需要懂了么。
worker收到信號(hào)就會(huì)fork_new 然后include_once,因?yàn)槭莿倓俧ork的,所以會(huì)重新讀入代碼
// $worker->reloadable = false;
// 開始沒(méi)有明白這么做為了什么,感謝你的提醒,他就是為了執(zhí)行下onWorkerReload() 業(yè)務(wù),其它啥也沒(méi)做。
foreach ($workerPidArray as $pid) {
// Send reload signal to a worker process which reloadable is false.
posix_kill($pid, $sig);
}