mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-30 02:37:58 +08:00
Merge branch 'master' into 3.0-merge
# Conflicts: # .github/workflows/test-components.yml # .github/workflows/test.yml # src/amqp/src/ConnectionFactory.php
This commit is contained in:
commit
06c3f4867e
4
.github/workflows/test-components.yml
vendored
4
.github/workflows/test-components.yml
vendored
@ -6,7 +6,7 @@ on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
env:
|
||||
SW_VERSION: 'v4.8.3'
|
||||
SW_VERSION: 'v4.8.4'
|
||||
jobs:
|
||||
database:
|
||||
name: Test for Database
|
||||
@ -132,8 +132,6 @@ jobs:
|
||||
php link_env.phar show:name -N helloworld
|
||||
sudo chmod u+x link_env.phar
|
||||
./link_env.phar show:name -N helloworld
|
||||
|
||||
|
||||
container:
|
||||
name: Test for Psr Container V1.0 ~ V2.0
|
||||
runs-on: 'ubuntu-latest'
|
||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ ubuntu-latest ]
|
||||
php-version: [ '8.0', '8.1' ]
|
||||
sw-version: [ 'v4.5.11', 'v4.6.7', 'v4.7.1', 'v4.8.3', 'master' ]
|
||||
sw-version: [ 'v4.5.11', 'v4.6.7', 'v4.7.1', 'v4.8.4', 'master' ]
|
||||
exclude:
|
||||
- php-version: '8.1'
|
||||
sw-version: 'v4.5.11'
|
||||
|
@ -1,8 +1,11 @@
|
||||
# v2.2.21 - TBD
|
||||
# v2.2.22 - TBD
|
||||
|
||||
# v2.2.21 - 2021-12-20
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#4347](https://github.com/hyperf/hyperf/pull/4347) Fixed bug that amqp io has been bound to more than one coroutine when out of buffer.
|
||||
- [#4373](https://github.com/hyperf/hyperf/pull/4373) Fixed the metadata generation error caused by switching coroutine for snowflake.
|
||||
|
||||
## Added
|
||||
|
||||
@ -12,6 +15,7 @@
|
||||
## Optimized
|
||||
|
||||
- [#4350](https://github.com/hyperf/hyperf/pull/4350) Optimized the error message for `swoole.use_shortname`.
|
||||
- [#4360](https://github.com/hyperf/hyperf/pull/4360) No longer uses `Swoole\Coroutine\Client`, but uses `Swoole\Coroutine\Socket`, which is more stable and has better performance in `Hyperf\Amqp\IO\SwooleIO`.
|
||||
|
||||
# v2.2.20 - 2021-12-13
|
||||
|
||||
|
@ -1,5 +1,22 @@
|
||||
# 版本更新记录
|
||||
|
||||
# v2.2.21 - 2021-12-20
|
||||
|
||||
## 修复
|
||||
|
||||
- [#4347](https://github.com/hyperf/hyperf/pull/4347) 修复使用 `AMQP` 组件时,如果连接缓冲区溢出,会导致连接被绑定到多个协程从而报错的问题。
|
||||
- [#4373](https://github.com/hyperf/hyperf/pull/4373) 修复使用 `Snowflake` 组件时,由于 `getWorkerId()` 中存在 `IO` 操作进而导致协程切换,最终导致元数据生成重复的问题。
|
||||
|
||||
## 新增
|
||||
|
||||
- [#4344](https://github.com/hyperf/hyperf/pull/4344) 新增事件 `Hyperf\Crontab\Event\FailToExecute`,此事件会在 `Crontab` 任务执行失败时触发。
|
||||
- [#4348](https://github.com/hyperf/hyperf/pull/4348) 支持使用 `gen:*` 命令创建文件时,自动吊起对应的 `IDE`,并打开当前文件。
|
||||
|
||||
## 优化
|
||||
|
||||
- [#4350](https://github.com/hyperf/hyperf/pull/4350) 优化了未开启 `swoole.use_shortname` 时的错误信息。
|
||||
- [#4360](https://github.com/hyperf/hyperf/pull/4360) 将 `Hyperf\Amqp\IO\SwooleIO` 进行重构,使用更加稳定和高效的 `Swoole\Coroutine\Socket` 而非 `Swoole\Coroutine\Client`。
|
||||
|
||||
# v2.2.20 - 2021-12-13
|
||||
|
||||
## 修复
|
||||
|
@ -169,3 +169,15 @@ http2 => enabled
|
||||
如果没有,需要重新编译 Swoole 并增加 `--enable-http2` 参数。
|
||||
|
||||
2. 检查 [server.php](/zh-cn/config?id=serverphp-配置说明) 文件中 `open_http2_protocol` 选项是否为 `true`。
|
||||
|
||||
## Command 无法正常关闭
|
||||
|
||||
在 Command 中使用 AMQP 等多路复用技术后,会导致无法正常关闭,碰到这种情况只需要在执行逻辑最后增加以下代码即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Hyperf\Utils\Coordinator\CoordinatorManager;
|
||||
use Hyperf\Utils\Coordinator\Constants;
|
||||
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
```
|
||||
|
@ -1,5 +1,22 @@
|
||||
# 版本更新記錄
|
||||
|
||||
# v2.2.21 - 2021-12-20
|
||||
|
||||
## 修復
|
||||
|
||||
- [#4347](https://github.com/hyperf/hyperf/pull/4347) 修復使用 `AMQP` 組件時,如果連接緩衝區溢出,會導致連接被綁定到多個協程從而報錯的問題。
|
||||
- [#4373](https://github.com/hyperf/hyperf/pull/4373) 修復使用 `Snowflake` 組件時,由於 `getWorkerId()` 中存在 `IO` 操作進而導致協程切換,最終導致元數據生成重複的問題。
|
||||
|
||||
## 新增
|
||||
|
||||
- [#4344](https://github.com/hyperf/hyperf/pull/4344) 新增事件 `Hyperf\Crontab\Event\FailToExecute`,此事件會在 `Crontab` 任務執行失敗時觸發。
|
||||
- [#4348](https://github.com/hyperf/hyperf/pull/4348) 支持使用 `gen:*` 命令創建文件時,自動吊起對應的 `IDE`,並打開當前文件。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#4350](https://github.com/hyperf/hyperf/pull/4350) 優化了未開啟 `swoole.use_shortname` 時的錯誤信息。
|
||||
- [#4360](https://github.com/hyperf/hyperf/pull/4360) 將 `Hyperf\Amqp\IO\SwooleIO` 進行重構,使用更加穩定和高效的 `Swoole\Coroutine\Socket` 而非 `Swoole\Coroutine\Client`。
|
||||
|
||||
# v2.2.20 - 2021-12-13
|
||||
|
||||
## 修復
|
||||
|
@ -169,3 +169,15 @@ http2 => enabled
|
||||
如果沒有,需要重新編譯 Swoole 並增加 `--enable-http2` 參數。
|
||||
|
||||
2. 檢查 [server.php](/zh-hk/config?id=serverphp-配置説明) 文件中 `open_http2_protocol` 選項是否為 `true`。
|
||||
|
||||
## Command 無法正常關閉
|
||||
|
||||
在 Command 中使用 AMQP 等多路複用技術後,會導致無法正常關閉,碰到這種情況只需要在執行邏輯最後增加以下代碼即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Hyperf\Utils\Coordinator\CoordinatorManager;
|
||||
use Hyperf\Utils\Coordinator\Constants;
|
||||
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
```
|
||||
|
@ -1,5 +1,22 @@
|
||||
# 版本更新記錄
|
||||
|
||||
# v2.2.21 - 2021-12-20
|
||||
|
||||
## 修復
|
||||
|
||||
- [#4347](https://github.com/hyperf/hyperf/pull/4347) 修復使用 `AMQP` 元件時,如果連線緩衝區溢位,會導致連線被繫結到多個協程從而報錯的問題。
|
||||
- [#4373](https://github.com/hyperf/hyperf/pull/4373) 修復使用 `Snowflake` 元件時,由於 `getWorkerId()` 中存在 `IO` 操作進而導致協程切換,最終導致元資料生成重複的問題。
|
||||
|
||||
## 新增
|
||||
|
||||
- [#4344](https://github.com/hyperf/hyperf/pull/4344) 新增事件 `Hyperf\Crontab\Event\FailToExecute`,此事件會在 `Crontab` 任務執行失敗時觸發。
|
||||
- [#4348](https://github.com/hyperf/hyperf/pull/4348) 支援使用 `gen:*` 命令建立檔案時,自動吊起對應的 `IDE`,並開啟當前檔案。
|
||||
|
||||
## 優化
|
||||
|
||||
- [#4350](https://github.com/hyperf/hyperf/pull/4350) 優化了未開啟 `swoole.use_shortname` 時的錯誤資訊。
|
||||
- [#4360](https://github.com/hyperf/hyperf/pull/4360) 將 `Hyperf\Amqp\IO\SwooleIO` 進行重構,使用更加穩定和高效的 `Swoole\Coroutine\Socket` 而非 `Swoole\Coroutine\Client`。
|
||||
|
||||
# v2.2.20 - 2021-12-13
|
||||
|
||||
## 修復
|
||||
|
@ -169,3 +169,15 @@ http2 => enabled
|
||||
如果沒有,需要重新編譯 Swoole 並增加 `--enable-http2` 引數。
|
||||
|
||||
2. 檢查 [server.php](/zh-tw/config?id=serverphp-配置說明) 檔案中 `open_http2_protocol` 選項是否為 `true`。
|
||||
|
||||
## Command 無法正常關閉
|
||||
|
||||
在 Command 中使用 AMQP 等多路複用技術後,會導致無法正常關閉,碰到這種情況只需要在執行邏輯最後增加以下程式碼即可。
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Hyperf\Utils\Coordinator\CoordinatorManager;
|
||||
use Hyperf\Utils\Coordinator\Constants;
|
||||
|
||||
CoordinatorManager::until(Constants::WORKER_EXIT)->resume();
|
||||
```
|
||||
|
@ -27,7 +27,8 @@ class IOFactory implements IOFactoryInterface
|
||||
'Swoole' => new SwooleIO(
|
||||
$host,
|
||||
$port,
|
||||
$params->getConnectionTimeout()
|
||||
$params->getConnectionTimeout(),
|
||||
$params->getReadWriteTimeout()
|
||||
),
|
||||
default => throw new NotSupportedException()
|
||||
};
|
||||
|
@ -15,8 +15,7 @@ use PhpAmqpLib\Exception\AMQPConnectionClosedException;
|
||||
use PhpAmqpLib\Exception\AMQPRuntimeException;
|
||||
use PhpAmqpLib\Wire\AMQPWriter;
|
||||
use PhpAmqpLib\Wire\IO\AbstractIO;
|
||||
use Swoole\Coroutine\Client;
|
||||
use const SWOOLE_SOCK_TCP;
|
||||
use Swoole\Coroutine\Socket;
|
||||
|
||||
class SwooleIO extends AbstractIO
|
||||
{
|
||||
@ -32,37 +31,27 @@ class SwooleIO extends AbstractIO
|
||||
*/
|
||||
protected $port;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $connectionTimeout;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $heartbeat;
|
||||
|
||||
/**
|
||||
* @var null|Client
|
||||
* @var null|Socket
|
||||
*/
|
||||
private $sock;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $buffer = '';
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException when readWriteTimeout argument does not 2x the heartbeat
|
||||
*/
|
||||
public function __construct(
|
||||
string $host,
|
||||
int $port,
|
||||
int $connectionTimeout
|
||||
protected int $connectionTimeout,
|
||||
protected int $readWriteTimeout = 3
|
||||
) {
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->connectionTimeout = $connectionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,34 +66,21 @@ class SwooleIO extends AbstractIO
|
||||
|
||||
public function read($len)
|
||||
{
|
||||
while (true) {
|
||||
if ($len <= strlen($this->buffer)) {
|
||||
$data = substr($this->buffer, 0, $len);
|
||||
$this->buffer = substr($this->buffer, $len);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (! $this->sock->isConnected()) {
|
||||
throw new AMQPConnectionClosedException('Broken pipe or closed connection. ' . $this->sock->errMsg);
|
||||
}
|
||||
|
||||
$buffer = $this->sock->recv(-1);
|
||||
|
||||
if ($buffer === '') {
|
||||
throw new AMQPConnectionClosedException('Connection is closed. The reason is ' . $this->sock->errMsg);
|
||||
}
|
||||
|
||||
$this->buffer .= $buffer;
|
||||
$data = $this->sock->recvAll($len, $this->readWriteTimeout);
|
||||
if ($data === false || strlen($data) !== $len) {
|
||||
throw new AMQPConnectionClosedException('Read data failed, The reason is ' . $this->sock->errMsg);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function write($data)
|
||||
{
|
||||
$buffer = $this->sock->send($data);
|
||||
$len = $this->sock->sendAll($data, $this->readWriteTimeout);
|
||||
|
||||
if ($buffer === false) {
|
||||
throw new AMQPConnectionClosedException('Error sending data');
|
||||
/* @phpstan-ignore-next-line */
|
||||
if ($data === false || strlen($data) !== $len) {
|
||||
throw new AMQPConnectionClosedException('Send data failed, The reason is ' . $this->sock->errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +110,7 @@ class SwooleIO extends AbstractIO
|
||||
|
||||
protected function makeClient()
|
||||
{
|
||||
$sock = new Client(SWOOLE_SOCK_TCP);
|
||||
$sock = new Socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (! $sock->connect($this->host, $this->port, $this->connectionTimeout)) {
|
||||
throw new AMQPRuntimeException(
|
||||
sprintf('Error Connecting to server: %s ', $sock->errMsg),
|
||||
|
@ -55,8 +55,9 @@ abstract class MetaGenerator implements MetaGeneratorInterface
|
||||
}
|
||||
|
||||
$this->lastTimestamp = $timestamp;
|
||||
$sequence = $this->sequence;
|
||||
|
||||
return new Meta($this->getDataCenterId(), $this->getWorkerId(), $this->sequence, $timestamp, $this->beginTimestamp);
|
||||
return new Meta($this->getDataCenterId(), $this->getWorkerId(), $sequence, $timestamp, $this->beginTimestamp);
|
||||
}
|
||||
|
||||
public function getBeginTimestamp(): int
|
||||
|
60
src/snowflake/tests/MetaGeneratorTest.php
Normal file
60
src/snowflake/tests/MetaGeneratorTest.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace HyperfTest\Snowflake;
|
||||
|
||||
use Hyperf\Snowflake\Configuration;
|
||||
use Hyperf\Snowflake\MetaGenerator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class MetaGeneratorTest extends TestCase
|
||||
{
|
||||
public function testGenerate()
|
||||
{
|
||||
$class = new class(new Configuration(), 0) extends MetaGenerator {
|
||||
public function getDataCenterId(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getWorkerId(): int
|
||||
{
|
||||
usleep(1000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getNextTimestamp(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
$callbacks = [];
|
||||
for ($i = 0; $i < 10; ++$i) {
|
||||
$callbacks[] = static function () use ($class) {
|
||||
return $class->generate()->getSequence();
|
||||
};
|
||||
}
|
||||
|
||||
$res = parallel($callbacks);
|
||||
ksort($res);
|
||||
$this->assertSame([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], $res);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user