引入laravel時,發(fā)現(xiàn)用debug模式啟動正常,用demon模式啟動則出現(xiàn)異常。
經(jīng)過排查發(fā)現(xiàn)laravel在命令行啟動時,保存了stdout的handle
當(dāng)workerman以demon模式啟動時,會關(guān)閉stdout的handle,并重定向到文件中。
/**
* Redirect standard input and output.
*
* @param bool $throwException
* @return void
* @throws Exception
*/
public static function resetStd(bool $throwException = true): void
{
if (!static::$daemonize || DIRECTORY_SEPARATOR !== '/' || static::$hasResetStd) {
return;
}
global $STDOUT, $STDERR;
$handle = fopen(static::$stdoutFile, "a");
if ($handle) {
unset($handle);
set_error_handler(function () {
});
if ($STDOUT) {
fclose($STDOUT);
}
if ($STDERR) {
fclose($STDERR);
}
if (is_resource(STDOUT)) {
fclose(STDOUT);
}
if (is_resource(STDERR)) {
fclose(STDERR);
}
$STDOUT = fopen(static::$stdoutFile, "a");
$STDERR = fopen(static::$stdoutFile, "a");
// Fix standard output cannot redirect of PHP 8.1.8's bug
if (function_exists('posix_isatty') && posix_isatty(2)) {
ob_start(function ($string) {
file_put_contents(static::$stdoutFile, $string, FILE_APPEND);
}, 1);
}
// change output stream
static::$outputStream = null;
static::outputStream($STDOUT);
restore_error_handler();
//mark as reset
static::$hasResetStd = true;
return;
}
if ($throwException) {
throw new RuntimeException('Can not open stdoutFile ' . static::$stdoutFile);
}
}
增加一個開關(guān),
如果有需要,在任何程序啟動前,完成std的重定向。然后在workerman啟動時不再重置
已經(jīng)提交PR,請老大審閱
https://github.com/walkor/workerman/pull/924
如果不關(guān)閉STDOUT,終端關(guān)閉后打印數(shù)據(jù)可能會導(dǎo)致進(jìn)程退出。
會關(guān)閉STDOUT,只不過增加一個開關(guān)判斷,如果已經(jīng)關(guān)閉過就不再關(guān)閉一次。這樣我可以在程序開始的時候就先手動調(diào)用resetStd(), 完成stdout重定向。后續(xù) worker::startAll()的時候就不會再次關(guān)閉了。
明白,如果添加功能很謹(jǐn)慎,是否可以考慮將 worker 類的一些方法改為public呢?比如worker::startAll()里面的方法,這樣可以自己控制其中的順序。
或者增加marco功能實現(xiàn),方便擴展功能來實現(xiàn)自定義。
直接關(guān)閉STDOUT對其他框架侵入很大,尤其是Symfony\Component\Console 庫,大量依賴了STDOUT的句柄實例,任何修復(fù)和兼容方式都是很不友好的硬編碼,除非能控制是否關(guān)閉STDOUT