Skip to content

Commit

Permalink
Add checkPortAvailable and move __construct to front #1069
Browse files Browse the repository at this point in the history
  • Loading branch information
walkor committed Nov 9, 2024
1 parent fe10fdb commit fd270bf
Showing 1 changed file with 63 additions and 51 deletions.
114 changes: 63 additions & 51 deletions src/Worker.php
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,29 @@ class Worker
*/
protected ?string $workerId = null;

/**
* Constructor.
*
* @param string|null $socketName
* @param array $socketContext
*/
public function __construct(?string $socketName = null, array $socketContext = [])
{
// Save all worker instances.
$this->workerId = spl_object_hash($this);
$this->context = new stdClass();
static::$workers[$this->workerId] = $this;
static::$pidMap[$this->workerId] = [];

// Context for socket.
if ($socketName) {
$this->socketName = $socketName;
$socketContext['socket']['backlog'] ??= static::DEFAULT_BACKLOG;
$this->socketContext = stream_context_create($socketContext);
}

}

/**
* Run all worker instances.
*
Expand All @@ -543,9 +566,10 @@ public static function runAll(): void
{
try {
static::checkSapiEnv();
self::initStdOut();
static::initStdOut();
static::init();
static::parseCommand();
static::checkPortAvailable();
static::lock();
static::daemonize();
static::initWorkers();
Expand Down Expand Up @@ -625,7 +649,7 @@ protected static function checkSapiEnv(): void
*
* @return void
*/
private static function initStdOut(): void
protected static function initStdOut(): void
{
$defaultStream = fn () => defined('STDOUT') ? STDOUT : (@fopen('php://stdout', 'w') ?: fopen('php://output', 'w'));
static::$outputStream ??= $defaultStream(); //@phpstan-ignore-line
Expand Down Expand Up @@ -2021,6 +2045,7 @@ public static function getGracefulStop(): bool
}

/**
*
* Write statistics data to disk.
*
* @return void
Expand Down Expand Up @@ -2275,51 +2300,6 @@ public static function safeEcho(string $msg, bool $decorated = false): void
restore_error_handler();
}

/**
* Constructor.
*
* @param string|null $socketName
* @param array $socketContext
*/
public function __construct(?string $socketName = null, array $socketContext = [])
{
// Save all worker instances.
$this->workerId = spl_object_hash($this);
$this->context = new stdClass();
static::$workers[$this->workerId] = $this;
static::$pidMap[$this->workerId] = [];

// Context for socket.
if ($socketName) {
$this->socketName = $socketName;
$socketContext['socket']['backlog'] ??= static::DEFAULT_BACKLOG;
$this->socketContext = stream_context_create($socketContext);
}

// Try to turn reusePort on.
/*if (\DIRECTORY_SEPARATOR === '/' // if linux
&& $socketName
&& \version_compare(php_uname('r'), '3.9', 'ge') // if kernel >=3.9
&& \strtolower(\php_uname('s')) !== 'darwin' // if not Mac OS
&& strpos($socketName,'unix') !== 0 // if not unix socket
&& strpos($socketName,'udp') !== 0) { // if not udp socket
$address = \parse_url($socketName);
if (isset($address['host']) && isset($address['port'])) {
try {
\set_error_handler(static fn (): bool => true);
// If address not in use, turn reusePort on automatically.
$server = stream_socket_server("tcp://{$address['host']}:{$address['port']}");
if ($server) {
$this->reusePort = true;
fclose($server);
}
\restore_error_handler();
} catch (\Throwable $e) {}
}
}*/
}

/**
* Listen.
*/
Expand All @@ -2335,17 +2315,17 @@ public function listen(): void

// Flag.
$flags = $this->transport === 'udp' ? STREAM_SERVER_BIND : STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
$errno = 0;
$errmsg = '';
$errNo = 0;
$errMsg = '';
// SO_REUSEPORT.
if ($this->reusePort) {
stream_context_set_option($this->socketContext, 'socket', 'so_reuseport', 1);
}

// Create an Internet or Unix domain server socket.
$this->mainSocket = stream_socket_server($localSocket, $errno, $errmsg, $flags, $this->socketContext);
$this->mainSocket = stream_socket_server($localSocket, $errNo, $errMsg, $flags, $this->socketContext);
if (!$this->mainSocket) {
throw new RuntimeException($errmsg);
throw new RuntimeException($errMsg);
}

if ($this->transport === 'ssl') {
Expand Down Expand Up @@ -2392,6 +2372,38 @@ public function unlisten(): void
}
}

/**
* Check port available.
*
* @return void
*/
protected static function checkPortAvailable(): void
{
foreach (static::$workers as $worker) {
$socketName = $worker->getSocketName();
if (DIRECTORY_SEPARATOR === '/' // if linux
&& static::$status === static::STATUS_STARTING // only for starting status
&& $worker->transport === 'tcp' // if tcp socket
&& !str_starts_with($socketName, 'unix') // if not unix socket
&& !str_starts_with($socketName, 'udp')) { // if not udp socket

$address = parse_url($socketName);
if (isset($address['host']) && isset($address['port'])) {
$address = "tcp://{$address['host']}:{$address['port']}";
$server = null;
set_error_handler(function ($code, $msg) {
throw new RuntimeException($msg);
});
$server = stream_socket_server($address, $code, $msg);
if ($server) {
fclose($server);
}
restore_error_handler();
}
}
}
}

/**
* Parse local socket address.
*/
Expand Down

0 comments on commit fd270bf

Please sign in to comment.