Skip to content

v6.2.4

Latest

Choose a tag to compare

@deminy deminy released this 25 Oct 19:40
· 176 commits to master since this release
b78adb6

Built-in PHP library included in Swoole v6.2.4.

Changes since v6.2.3:

Added:

  • PR #185: Added \Swoole\Coroutine\Http2\MultiplexClient, an HTTP/2 client that multiplexes requests from many coroutines over one shared connection, reconnects on demand, and closes an idle connection after a configurable period (options heartbeat_check_interval and heartbeat_idle_time) (by @tw2066).
  • PR #187: \Swoole\Database\RedisConfig::withAuth() now also accepts a [username, password] array for Redis ACL authentication (by @catchem88). A class extending RedisConfig that overrides withAuth() or redeclares $auth has to widen its string type to string|array.
  • PR #190: Support the CURLOPT_PREREQFUNCTION option in the coroutine curl handler; on PHP versions without the native constants, use \Swoole\Curl\CURLOPT_PREREQFUNCTION, \Swoole\Curl\CURL_PREREQFUNC_OK and \Swoole\Curl\CURL_PREREQFUNC_ABORT (by @lazerg).
  • PR #191: Support the http2_max_headers server option, with the constant \Swoole\Constant::OPTION_HTTP2_MAX_HEADERS; it takes effect on Swoole 6.3.0 and later (by @NathanFreeman).
  • \Swoole\Database\MysqliProxy::inTransaction() and reset(), which report and forget the transaction state the proxy tracks. \Swoole\Database\MysqliPool::get() hands out a connection with that state reset.
  • \Swoole\RemoteObject\Exception::getRemoteClass() and getRemoteCode(), which give the class and the code of an exception thrown on the server.

Changed:

  • \Swoole\Server\Helper uses the \Swoole\Constant::OPTION_* constants instead of string literals in its option tables and lookups.
  • The FastCGI Params record encodes and decodes its parameters in linear time, about 2.5 and 8 times faster than before; the bytes produced and the parameters read are the same.
  • \Swoole\ArrayObject::lastIndexOf() and remove() with $loop find their keys in one array_keys() call instead of walking the array in PHP, with the same results.
  • \Swoole\StringObject::endsWith() uses str_ends_with() and no longer scans the whole string, with the same results.

Removed:

  • Dropped support for PHP below 8.2 and Swoole below 6.2.

Fixed:

  • PR #192: Report fatal \Swoole\Coroutine\Server accept failures through start() and errCode (by @binaryfire).
  • PR #193: Fixed a memory leak in \Swoole\RemoteObject\Client, present since 6.2.0, where every client was kept alive for the lifetime of the process (issue swoole/swoole-src#6191). \Swoole\RemoteObject\Client::getInstance() now returns null for a client that is gone, and a client can no longer be cloned.
  • Fixed a startup race in the default remote object server that let a coroutine see the server as ready while another one was still starting it (commit).
  • A failed reconnect left a database statement proxy wrapping false (commit).
  • \Swoole\RemoteObject\Client now throws a \Swoole\RemoteObject\Exception on a response that does not unserialize.
  • An empty FastCGI response is now reported as 502 Invalid FastCGI Response.
  • \Swoole\Coroutine\FastCGI\Client kept a connection whose response could not be parsed, and the next request sent over it read the rest of that response as its own.
  • A \Swoole\RemoteObject\Client used from several coroutines at once ended the process with a fatal "Socket has already been bound to another coroutine"; calls through one client are now serialized.
  • swoole_container_cpu_num() ignored the CPU quota of cgroup v2 containers.
  • The mysqli proxies did not reconnect after a lost connection under the default mysqli report mode of PHP 8.1+, where failures are thrown as \mysqli_sql_exception.
  • The mysqli proxies no longer reconnect inside a transaction, and report a lost connection in a method they do not retry, such as store_result(), where they returned false.
  • \Swoole\Database\MysqliStatementProxy did not re-bind the bind_result() variables correctly after a reconnect, and retried fetch() on a statement that was prepared again but never executed.
  • \Swoole\Database\MysqliStatementProxy did not recover from a second lost connection on the same statement.
  • \Swoole\Database\PDOStatementProxy turned a connection lost while reading rows into an empty result, and did not recover from a second lost connection on the same statement. It now retries execute() only, and reports a lost connection in any other method.
  • \Swoole\Database\PDOStatementProxy: after a connection lost inside a transaction started by hand, e.g. with exec('BEGIN'), execute() ran the statement again on a new connection, outside the transaction. The lost connection is now reported.
  • The database proxies recognise more lost-connection errors: SSL failures during a query, PostgreSQL's canceling statement due to conflict with recovery, and the PlanetScale PostgreSQL / pg_bouncer messages, in line with Laravel's list.
  • \Swoole\Database\RedisPool passed the connect() arguments in the wrong positions when only some of the connect timeout, retry interval and read timeout were configured.
  • \Swoole\Coroutine\Server never backed off when a coroutine could not be created for an accepted connection.
  • A FastCGI request body of "0" was dropped as empty.
  • An exception the remote object server caught became a TypeError on the client when its code was not an integer, as with a \PDOException, and so did the server's own errors such as an invalid API key. Both now arrive as a \Swoole\RemoteObject\Exception.
  • \Swoole\NameResolver\Nacos::getCluster() threw a TypeError, because Nacos reports the weight of a node as a float.
  • Several scripts under examples/ did not run: the remote object, Nacos, Consul, PDO and short name examples.
  • \Swoole\ConnectionPool::close() failed with an Error when called twice, and fill() on a closed pool made connections only to drop them.
  • \Swoole\Database\PDOProxy: query() and prepare() failed with a TypeError outside the exception error mode.
  • \Swoole\Database\PDOProxy: query(), exec() and beginTransaction() did not reconnect after a connection lost outside a transaction on PostgreSQL.
  • \Swoole\Database\PDOProxy stayed on a dead connection after a connection lost inside a transaction, and on PostgreSQL after a reconnect that failed. The next call now reconnects, and rollBack() of the transaction lost with the connection returns true.
  • \Swoole\ArrayObject and swoole_array_default_value() raised a deprecation on PHP 8.5 when given a null key, which still stands for the empty string.
  • The mysqli proxies raised a warning on prepare(query: ...), with the query passed by name, and could not prepare that statement again after a reconnect.
  • \Swoole\Database\PDOStatementProxy: after a reconnect, a statement used the value a variable had when bindParam() was called, not its present one, and no longer filled the variables of bindColumn().
  • \Swoole\Database\PDOStatementProxy::bindColumn() threw a TypeError when called without a type.
  • isset() and empty() on an offset of a \Swoole\RemoteObject always failed with a TypeError.
  • \Swoole\Database\PDOStatementProxy: after a reconnect, a parameter bound by both bindValue() and bindParam() could take the binding made first instead of the one made last.
  • Array access on a \Swoole\RemoteObject used the properties of the object on the server instead of its ArrayAccess implementation.
  • The remote object server passed null to a function called with a remote object it no longer has, where it now reports the object as not found.
  • The default remote object server did not start in a directory whose path has a space or a quote in it.
  • isset(), empty() and ?? on a property of a \Swoole\RemoteObject treated the property as unset without asking the server, and unset() did not reach the server.