-
Notifications
You must be signed in to change notification settings - Fork 12
Wait for socket to be ready before connecting on 115 #242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 13 commits
8b4d1c3
70d1397
de1515e
58af465
113ed7d
348570a
3d6e486
a8c485a
075c7d8
778d779
76e187e
dca9270
3e3c06c
e05cc7a
983dfe3
6e18e64
50fce97
237a358
513a084
79cd2fd
7b2161c
aeb1111
890dd6b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -566,13 +566,49 @@ private function sendRawRequest(string $host, int $port, string $rawRequest) | |
| throw new ConnectionFailure("Could not connect to create socket: $socketError"); | ||
| } | ||
|
|
||
| // Configure this socket and try to connect to it | ||
| // PHP 8 Socket objects need explicit non-blocking mode to prevent EINPROGRESS timeouts | ||
| socket_set_nonblock($this->socket); | ||
| socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, ['sec' => $this->connectionTimeout, 'usec' => $this->connectionTimeoutMicroseconds]); | ||
| socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => $this->readTimeout, 'usec' => $this->readTimeoutMicroseconds]); | ||
| $connectStart = microtime(true); | ||
| @socket_connect($this->socket, $host, $port); | ||
| $connectTime = (microtime(true) - $connectStart) * 1000; // Convert to milliseconds | ||
| $socketErrorCode = socket_last_error($this->socket); | ||
| if ($socketErrorCode === 115) { | ||
| $this->logger->info('Bedrock\Client - socket_connect returned error 115, continuing.'); | ||
| $this->logger->info('Bedrock\Client - socket_connect returned error 115, waiting for connection to complete.', [ | ||
| 'host' => $host, | ||
| 'connect_attempt_time_ms' => round($connectTime, 3), | ||
|
||
| 'pid' => getmypid(), | ||
|
||
| ]); | ||
|
|
||
| // Wait for the socket to be ready for writing after EINPROGRESS | ||
| $write = [$this->socket]; | ||
| $read = []; | ||
| $except = []; | ||
| $selectResult = socket_select($read, $write, $except, $this->connectionTimeout, $this->connectionTimeoutMicroseconds); | ||
|
|
||
| if ($selectResult === false) { | ||
| $socketError = socket_strerror(socket_last_error($this->socket)); | ||
| throw new ConnectionFailure("socket_select failed after EINPROGRESS for $host:$port. Error: $socketError"); | ||
| } elseif ($selectResult === 0) { | ||
| throw new ConnectionFailure("Socket not ready for writing within timeout after EINPROGRESS for $host:$port"); | ||
| } elseif (empty($write)) { | ||
| $socketErrorCode = socket_last_error($this->socket); | ||
| $socketError = socket_strerror($socketErrorCode); | ||
| throw new ConnectionFailure("Socket had error after EINPROGRESS for $host:$port. Error: $socketErrorCode $socketError"); | ||
| } | ||
|
|
||
| $selectTime = (microtime(true) - $connectStart) * 1000; // Total time from connect to ready | ||
|
||
|
|
||
| // Set socket back to blocking mode for normal operations | ||
| socket_set_block($this->socket); | ||
|
|
||
| $this->logger->info('Bedrock\Client - Socket ready for writing after EINPROGRESS.', [ | ||
| 'host' => $host, | ||
| 'total_connection_time_ms' => round($selectTime, 3), | ||
|
||
| 'select_wait_time_ms' => round($selectTime - $connectTime, 3), | ||
| 'pid' => getmypid(), | ||
|
||
| ]); | ||
| } elseif ($socketErrorCode) { | ||
| $socketError = socket_strerror($socketErrorCode); | ||
| throw new ConnectionFailure("Could not connect to Bedrock host $host:$port. Error: $socketErrorCode $socketError"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment confuses me very much (like this problem as a whole) 😅