mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Merge branch 'master' into utils
This commit is contained in:
commit
cb096e8a04
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,6 +1,15 @@
|
||||
# v1.1.27 - TBD
|
||||
|
||||
- [#1589](https://github.com/hyperf/hyperf/pull/1589) Fixed file locks not safe in coroutines.
|
||||
## Added
|
||||
|
||||
- [#1575](https://github.com/hyperf/hyperf/pull/1575) Added document of property with relation, scope and attributes.
|
||||
- [#1586](https://github.com/hyperf/hyperf/pull/1586) Added conflict of symfony/event-dispatcher which < 4.3.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#1553](https://github.com/hyperf/hyperf/pull/1553) Fixed the rpc client do not work, when jsonrpc server register the same service to consul with jsonrpc and jsonrpc-http protocol.
|
||||
- [#1589](https://github.com/hyperf/hyperf/pull/1589) Fixed unsafe file locks in coroutines.
|
||||
- [#1607](https://github.com/hyperf/hyperf/pull/1607) Fixed bug that the return value of function `go` is not adaptive with `swoole`.
|
||||
|
||||
# v1.1.26 - 2020-04-16
|
||||
|
||||
|
15
README-CN.md
15
README-CN.md
@ -82,6 +82,21 @@ Hyperf 还提供了 `基于 PSR-11 的依赖注入容器`、`注解`、`AOP 面
|
||||
</table>
|
||||
<!--gold end-->
|
||||
|
||||
# 性能
|
||||
|
||||
### 阿里云 8 核 16G
|
||||
命令: `wrk -c 1024 -t 8 http://127.0.0.1:9501/`
|
||||
```bash
|
||||
Running 10s test @ http://127.0.0.1:9501/
|
||||
8 threads and 1024 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 10.08ms 6.82ms 56.66ms 70.19%
|
||||
Req/Sec 13.17k 5.94k 33.06k 84.12%
|
||||
1049478 requests in 10.10s, 190.16MB read
|
||||
Requests/sec: 103921.49
|
||||
Transfer/sec: 18.83MB
|
||||
```
|
||||
|
||||
# 开源协议
|
||||
|
||||
Hyperf 是一个基于 [MIT 协议](https://github.com/hyperf/hyperf/blob/master/LICENSE) 开源的软件。
|
||||
|
15
README.md
15
README.md
@ -70,6 +70,21 @@ Support this project with your organization or company. Your logo will show up h
|
||||
</table>
|
||||
<!--gold end-->
|
||||
|
||||
# Performance
|
||||
|
||||
### Aliyun 8 cores 16G ram
|
||||
command: `wrk -c 1024 -t 8 http://127.0.0.1:9501/`
|
||||
```bash
|
||||
Running 10s test @ http://127.0.0.1:9501/
|
||||
8 threads and 1024 connections
|
||||
Thread Stats Avg Stdev Max +/- Stdev
|
||||
Latency 10.08ms 6.82ms 56.66ms 70.19%
|
||||
Req/Sec 13.17k 5.94k 33.06k 84.12%
|
||||
1049478 requests in 10.10s, 190.16MB read
|
||||
Requests/sec: 103921.49
|
||||
Transfer/sec: 18.83MB
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
The Hyperf framework is open-source software licensed under the MIT license.
|
||||
|
@ -73,6 +73,7 @@
|
||||
"swoole/ide-helper": "dev-master",
|
||||
"sy-records/think-template": "^2.0",
|
||||
"symfony/console": "^4.2",
|
||||
"symfony/event-dispatcher": "^4.3",
|
||||
"symfony/finder": "^4.1",
|
||||
"symfony/property-access": "^4.3",
|
||||
"symfony/serializer": "^4.3",
|
||||
@ -135,6 +136,9 @@
|
||||
"hyperf/websocket-server": "self.version"
|
||||
},
|
||||
"suggest": {},
|
||||
"conflict": {
|
||||
"symfony/event-dispatcher": "<4.3"
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/config/src/Functions.php",
|
||||
|
@ -47,7 +47,7 @@ return [
|
||||
'login_response' => null,
|
||||
'locale' => 'en_US',
|
||||
'connection_timeout' => 3.0,
|
||||
'read_write_timeout' => 3.0,
|
||||
'read_write_timeout' => 6.0,
|
||||
'context' => null,
|
||||
'keepalive' => false,
|
||||
'heartbeat' => 3,
|
||||
|
@ -39,14 +39,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
class IndexController
|
||||
class IndexController extends AbstractController
|
||||
{
|
||||
public function example(\League\Flysystem\Filesystem $filesystem)
|
||||
{
|
||||
// Process Upload
|
||||
$file = $this->request->file('upload');
|
||||
$stream = fopen($file->getRealPath(), 'r+');
|
||||
$filesystem->writeStream(
|
||||
'uploads/'.$file->getClientFilename(),
|
||||
$stream
|
||||
);
|
||||
fclose($stream);
|
||||
|
||||
// Write Files
|
||||
$filesystem->write('path/to/file.txt', 'contents');
|
||||
|
||||
// Write Use writeStream
|
||||
// Add local file
|
||||
$stream = fopen('local/path/to/file.txt', 'r+');
|
||||
$result = $filesystem->writeStream('path/to/file.txt', $stream);
|
||||
if (is_resource($stream)) {
|
||||
@ -122,7 +131,8 @@ return [
|
||||
|
||||
1. S3 存储请确认安装 `hyperf/guzzle` 组件以提供协程化支持。阿里云、七牛云存储请[开启 Curl Hook](/zh-cn/coroutine?id=swoole-runtime-hook-level)来使用协程。因 Curl Hook 的参数支持性问题,请使用 Swoole 4.4.13 以上版本。
|
||||
2. minIO, ceph radosgw 等私有对象存储方案均支持 S3 协议,可以使用 S3 适配器。
|
||||
3. 以阿里云 OSS 为例,1 核 1 进程读操作性能对比:
|
||||
3. 使用Local驱动时,根目录是配置好的地址,而不是操作系统的根目录。例如,Local驱动 `root` 设置为 `/var/www`, 则本地磁盘上的 `/var/www/public/file.txt` 通过 flysystem API 访问时应使用 `/public/file.txt` 或 `public/file.txt` 。
|
||||
4. 以阿里云 OSS 为例,1 核 1 进程读操作性能对比:
|
||||
|
||||
```bash
|
||||
ab -k -c 10 -n 1000 http://127.0.0.1:9501/
|
||||
|
@ -62,30 +62,6 @@ vendor/bin/init-proxy.sh && composer test
|
||||
vendor/bin/init-proxy.sh && php bin/hyperf.php start
|
||||
```
|
||||
|
||||
## PHP7.3 下预先生成代理的脚本 执行失败
|
||||
|
||||
`php bin/hyperf.php di:init-proxy` 脚本在 `PHP7.3` 的 `Docker` 打包时,会因为返回码是 `1` 而失败。
|
||||
|
||||
> 具体原因还在定位中
|
||||
|
||||
以下通过重写 `init-proxy.sh` 脚本绕过这个问题。
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
php /opt/www/bin/hyperf.php di:init-proxy
|
||||
|
||||
echo Started.
|
||||
```
|
||||
|
||||
对应的 `Dockerfile` 修改以下代码,省略无用的代码展示。
|
||||
|
||||
```dockerfile
|
||||
RUN composer install --no-dev \
|
||||
&& composer dump-autoload -o \
|
||||
&& ./init-proxy.sh
|
||||
```
|
||||
|
||||
## 异步队列消息丢失
|
||||
|
||||
如果在使用 `async-queue` 组件时,发现 `handle` 中的方法没有执行,请先检查以下几种情况:
|
||||
@ -97,3 +73,27 @@ RUN composer install --no-dev \
|
||||
|
||||
1. killall php
|
||||
2. 修改 `async-queue` 配置 `channel`
|
||||
|
||||
## 1.1.24 - 1.1.26 版本 SymfonyEventDispatcher 报错
|
||||
|
||||
因为 `symfony/console` 默认使用的 `^4.2` 版本,而 `symfony/event-dispatcher` 的 `^4.3` 版本与 `<4.3` 版本不兼容。
|
||||
|
||||
`hyperf/framework` 默认推荐使用 `^4.3` 版本的 `symfony/event-dispatcher`,就有一定概率导致实现上的冲突。
|
||||
|
||||
如果有类似的情况出现,可以尝试以下操作
|
||||
|
||||
```
|
||||
rm -rf vendor
|
||||
rm -rf composer.lock
|
||||
composer require "symfony/event-dispatcher:^4.3"
|
||||
```
|
||||
|
||||
1.1.27 版本中,会在 `composer.json` 中添加以下配置,来处理这个问题。
|
||||
|
||||
```
|
||||
"conflict": {
|
||||
"symfony/event-dispatcher": "<4.3"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
```
|
||||
curl -sSL https://get.daocloud.io/docker | sh
|
||||
# curl -sSL https://get.docker.com/ | sh
|
||||
```
|
||||
|
||||
修改文件 `/lib/systemd/system/docker.service`,允许使用 `TCP` 连接 `Docker`
|
||||
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
||||
return [
|
||||
'default' => [
|
||||
'host' => env('AMQP_HOST', 'localhost'),
|
||||
'port' => env('AMQP_PORT', 5672),
|
||||
'port' => (int) env('AMQP_PORT', 5672),
|
||||
'user' => env('AMQP_USER', 'guest'),
|
||||
'password' => env('AMQP_PASSWORD', 'guest'),
|
||||
'vhost' => env('AMQP_VHOST', '/'),
|
||||
|
@ -30,7 +30,7 @@
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/dbal": "Required to rename columns (^2.6).",
|
||||
"nikic/php-parser": "Required to use ModelCommand (^4.1)."
|
||||
"roave/better-reflection": "Required to use ModelCommand (^4.0)."
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
@ -12,13 +12,51 @@ declare(strict_types=1);
|
||||
namespace Hyperf\Database\Commands\Ast;
|
||||
|
||||
use Hyperf\Database\Commands\ModelOption;
|
||||
use Hyperf\Database\Model\Builder;
|
||||
use Hyperf\Database\Model\Collection;
|
||||
use Hyperf\Database\Model\Model;
|
||||
use Hyperf\Database\Model\Relations\BelongsTo;
|
||||
use Hyperf\Database\Model\Relations\BelongsToMany;
|
||||
use Hyperf\Database\Model\Relations\HasMany;
|
||||
use Hyperf\Database\Model\Relations\HasManyThrough;
|
||||
use Hyperf\Database\Model\Relations\HasOne;
|
||||
use Hyperf\Database\Model\Relations\HasOneThrough;
|
||||
use Hyperf\Database\Model\Relations\MorphMany;
|
||||
use Hyperf\Database\Model\Relations\MorphOne;
|
||||
use Hyperf\Database\Model\Relations\MorphTo;
|
||||
use Hyperf\Database\Model\Relations\MorphToMany;
|
||||
use Hyperf\Database\Model\Relations\Relation;
|
||||
use Hyperf\Utils\Str;
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Roave\BetterReflection\BetterReflection;
|
||||
use Roave\BetterReflection\Reflection\ReflectionClass;
|
||||
use Roave\BetterReflection\Reflection\ReflectionMethod;
|
||||
use Roave\BetterReflection\Reflector\ClassReflector;
|
||||
use Roave\BetterReflection\TypesFinder\FindReturnType;
|
||||
|
||||
class ModelUpdateVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
const RELATION_METHODS = [
|
||||
'hasMany' => HasMany::class,
|
||||
'hasManyThrough' => HasManyThrough::class,
|
||||
'hasOneThrough' => HasOneThrough::class,
|
||||
'belongsToMany' => BelongsToMany::class,
|
||||
'hasOne' => HasOne::class,
|
||||
'belongsTo' => BelongsTo::class,
|
||||
'morphOne' => MorphOne::class,
|
||||
'morphTo' => MorphTo::class,
|
||||
'morphMany' => MorphMany::class,
|
||||
'morphToMany' => MorphToMany::class,
|
||||
'morphedByMany' => MorphToMany::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $class;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@ -29,31 +67,48 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
||||
*/
|
||||
protected $option;
|
||||
|
||||
public function __construct($columns = [], ModelOption $option)
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $methods = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $properties = [];
|
||||
|
||||
/**
|
||||
* @deprecated v2.0
|
||||
* @var ClassReflector
|
||||
*/
|
||||
protected static $reflector;
|
||||
|
||||
/**
|
||||
* @deprecated v2.0
|
||||
* @var FindReturnType
|
||||
*/
|
||||
protected static $return;
|
||||
|
||||
public function __construct($class, $columns, ModelOption $option)
|
||||
{
|
||||
$this->class = $class;
|
||||
$this->columns = $columns;
|
||||
$this->option = $option;
|
||||
$this->initPropertiesFromMethods();
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node)
|
||||
{
|
||||
switch ($node) {
|
||||
case $node instanceof Node\Stmt\PropertyProperty:
|
||||
if ($node->name == 'fillable' && $this->option->isRefreshFillable()) {
|
||||
if ((string) $node->name === 'fillable' && $this->option->isRefreshFillable()) {
|
||||
$node = $this->rewriteFillable($node);
|
||||
} elseif ($node->name == 'casts') {
|
||||
} elseif ((string) $node->name === 'casts') {
|
||||
$node = $this->rewriteCasts($node);
|
||||
}
|
||||
|
||||
return $node;
|
||||
case $node instanceof Node\Stmt\Class_:
|
||||
$doc = '/**' . PHP_EOL;
|
||||
foreach ($this->columns as $column) {
|
||||
[$name, $type, $comment] = $this->getProperty($column);
|
||||
$doc .= sprintf(' * @property %s $%s %s', $type, $name, $comment) . PHP_EOL;
|
||||
}
|
||||
$doc .= ' */';
|
||||
$node->setDocComment(new Doc($doc));
|
||||
$node->setDocComment(new Doc($this->parseProperty()));
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
@ -91,6 +146,147 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
||||
return $node;
|
||||
}
|
||||
|
||||
protected function parseProperty(): string
|
||||
{
|
||||
$doc = '/**' . PHP_EOL;
|
||||
foreach ($this->columns as $column) {
|
||||
[$name, $type, $comment] = $this->getProperty($column);
|
||||
$doc .= sprintf(' * @property %s $%s %s', $type, $name, $comment) . PHP_EOL;
|
||||
}
|
||||
foreach ($this->properties as $name => $property) {
|
||||
if ($property['read'] && $property['write']) {
|
||||
$doc .= sprintf(' * @property %s $%s', $property['type'], $name) . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
if ($property['read']) {
|
||||
$doc .= sprintf(' * @property-read %s $%s', $property['type'], $name) . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
if ($property['write']) {
|
||||
$doc .= sprintf(' * @property-write %s $%s', $property['type'], $name) . PHP_EOL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$doc .= ' */';
|
||||
return $doc;
|
||||
}
|
||||
|
||||
protected function initPropertiesFromMethods()
|
||||
{
|
||||
/** @var ReflectionClass $reflection */
|
||||
$reflection = self::getReflector()->reflect($this->class);
|
||||
$methods = $reflection->getImmediateMethods();
|
||||
$namespace = $reflection->getDeclaringNamespaceAst();
|
||||
if (empty($methods)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sort($methods);
|
||||
/** @var ReflectionMethod $method */
|
||||
foreach ($methods as $method) {
|
||||
if (Str::startsWith($method->getName(), 'get') && Str::endsWith($method->getName(), 'Attribute')) {
|
||||
// Magic get<name>Attribute
|
||||
$name = Str::snake(substr($method->getName(), 3, -9));
|
||||
if (! empty($name)) {
|
||||
$type = self::getReturnFinder()->__invoke($method, $namespace);
|
||||
$this->setProperty($name, $type, true, null);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Str::startsWith($method->getName(), 'set') && Str::endsWith($method->getName(), 'Attribute')) {
|
||||
// Magic set<name>Attribute
|
||||
$name = Str::snake(substr($method->getName(), 3, -9));
|
||||
if (! empty($name)) {
|
||||
$this->setProperty($name, null, null, true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Str::startsWith($method->getName(), 'scope') && $method->getName() !== 'scopeQuery') {
|
||||
$name = Str::camel(substr($method->getName(), 5));
|
||||
if (! empty($name)) {
|
||||
$args = $method->getParameters();
|
||||
// Remove the first ($query) argument
|
||||
array_shift($args);
|
||||
$this->setMethod($name, [Builder::class, $method->getDeclaringClass()->getName()], $args);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($method->getNumberOfParameters() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$return = $method->getReturnStatementsAst();
|
||||
// Magic Relation
|
||||
if (count($return) === 1 && $return[0] instanceof Node\Stmt\Return_) {
|
||||
$expr = $return[0]->expr;
|
||||
if (
|
||||
$expr instanceof Node\Expr\MethodCall
|
||||
&& $expr->name instanceof Node\Identifier
|
||||
&& is_string($expr->name->name)
|
||||
&& isset($expr->args[0])
|
||||
&& $expr->args[0] instanceof Node\Arg
|
||||
) {
|
||||
$name = $expr->name->name;
|
||||
if (array_key_exists($name, self::RELATION_METHODS)) {
|
||||
if ($expr->args[0]->value instanceof Node\Expr\ClassConstFetch) {
|
||||
$related = $expr->args[0]->value->class->toCodeString();
|
||||
} else {
|
||||
$related = (string) ($expr->args[0]->value);
|
||||
}
|
||||
|
||||
if (strpos($name, 'Many') !== false) {
|
||||
// Collection or array of models (because Collection is Arrayable)
|
||||
$this->setProperty($method->getName(), [$this->getCollectionClass($related), $related . '[]'], true);
|
||||
} elseif ($name === 'morphTo') {
|
||||
// Model isn't specified because relation is polymorphic
|
||||
$this->setProperty($method->getName(), [Model::class], true);
|
||||
} else {
|
||||
// Single model is returned
|
||||
$this->setProperty($method->getName(), [$related], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function setProperty(string $name, array $type = null, bool $read = null, bool $write = null, string $comment = '', bool $nullable = false)
|
||||
{
|
||||
if (! isset($this->properties[$name])) {
|
||||
$this->properties[$name] = [];
|
||||
$this->properties[$name]['type'] = 'mixed';
|
||||
$this->properties[$name]['read'] = false;
|
||||
$this->properties[$name]['write'] = false;
|
||||
$this->properties[$name]['comment'] = (string) $comment;
|
||||
}
|
||||
if ($type !== null) {
|
||||
if ($nullable) {
|
||||
$type[] = 'null';
|
||||
}
|
||||
$this->properties[$name]['type'] = implode('|', array_unique($type));
|
||||
}
|
||||
if ($read !== null) {
|
||||
$this->properties[$name]['read'] = $read;
|
||||
}
|
||||
if ($write !== null) {
|
||||
$this->properties[$name]['write'] = $write;
|
||||
}
|
||||
}
|
||||
|
||||
protected function setMethod(string $name, array $type = [], array $arguments = [])
|
||||
{
|
||||
$methods = array_change_key_case($this->methods, CASE_LOWER);
|
||||
|
||||
if (! isset($methods[strtolower($name)])) {
|
||||
$this->methods[$name] = [];
|
||||
$this->methods[$name]['type'] = implode('|', $type);
|
||||
$this->methods[$name]['arguments'] = $arguments;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getProperty($column): array
|
||||
{
|
||||
$name = $this->option->isCamelCase() ? Str::camel($column['column_name']) : $column['column_name'];
|
||||
@ -142,4 +338,35 @@ class ModelUpdateVisitor extends NodeVisitorAbstract
|
||||
|
||||
return $cast;
|
||||
}
|
||||
|
||||
protected function getCollectionClass($className): string
|
||||
{
|
||||
// Return something in the very very unlikely scenario the model doesn't
|
||||
// have a newCollection() method.
|
||||
if (! method_exists($className, 'newCollection')) {
|
||||
return Collection::class;
|
||||
}
|
||||
|
||||
/** @var Model $model */
|
||||
$model = new $className();
|
||||
return '\\' . get_class($model->newCollection());
|
||||
}
|
||||
|
||||
protected static function getReturnFinder(): FindReturnType
|
||||
{
|
||||
if (static::$return instanceof FindReturnType) {
|
||||
return static::$return;
|
||||
}
|
||||
|
||||
return static::$return = new FindReturnType();
|
||||
}
|
||||
|
||||
protected static function getReflector(): ClassReflector
|
||||
{
|
||||
if (self::$reflector instanceof ClassReflector) {
|
||||
return self::$reflector;
|
||||
}
|
||||
|
||||
return self::$reflector = (new BetterReflection())->classReflector();
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ class ModelCommand extends Command
|
||||
$stms = $this->astParser->parse(file_get_contents($path));
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor(make(ModelUpdateVisitor::class, [
|
||||
'class' => $class,
|
||||
'columns' => $columns,
|
||||
'option' => $option,
|
||||
]));
|
||||
|
@ -101,15 +101,16 @@ class RoutesCommand extends HyperfCommand
|
||||
} else {
|
||||
$action = $handler->callback;
|
||||
}
|
||||
if (isset($data[$uri])) {
|
||||
$data[$uri]['method'][] = $method;
|
||||
$unique = "{$serverName}|{$action}";
|
||||
if (isset($data[$unique])) {
|
||||
$data[$unique]['method'][] = $method;
|
||||
} else {
|
||||
// method,uri,name,action,middleware
|
||||
$registedMiddlewares = MiddlewareManager::get($serverName, $uri, $method);
|
||||
$middlewares = $this->config->get('middlewares.' . $serverName, []);
|
||||
|
||||
$middlewares = array_merge($middlewares, $registedMiddlewares);
|
||||
$data[$uri] = [
|
||||
$data[$unique] = [
|
||||
'server' => $serverName,
|
||||
'method' => [$method],
|
||||
'uri' => $uri,
|
||||
|
@ -40,6 +40,9 @@
|
||||
"hyperf/command": "Required to use Command annotation.",
|
||||
"symfony/event-dispatcher": "Required to use symfony event dispatcher (^4.3)."
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/event-dispatcher": "<4.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Hyperf\\Framework\\": "src/"
|
||||
|
@ -230,14 +230,14 @@ abstract class AbstractServiceClient
|
||||
$services = $health->service($this->serviceName)->json();
|
||||
$nodes = [];
|
||||
foreach ($services as $node) {
|
||||
$passing = true;
|
||||
$passing = false;
|
||||
$service = $node['Service'] ?? [];
|
||||
$checks = $node['Checks'] ?? [];
|
||||
|
||||
foreach ($checks as $check) {
|
||||
$status = $check['Status'] ?? false;
|
||||
if ($status !== 'passing') {
|
||||
$passing = false;
|
||||
if ($status === 'passing' && $this->protocol === $service['Meta']['Protocol']) {
|
||||
$passing = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,16 +279,24 @@ if (! function_exists('call')) {
|
||||
}
|
||||
|
||||
if (! function_exists('go')) {
|
||||
/**
|
||||
* @return bool|int
|
||||
*/
|
||||
function go(callable $callable)
|
||||
{
|
||||
Coroutine::create($callable);
|
||||
$id = Coroutine::create($callable);
|
||||
return $id > 0 ? $id : false;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('co')) {
|
||||
/**
|
||||
* @return bool|int
|
||||
*/
|
||||
function co(callable $callable)
|
||||
{
|
||||
Coroutine::create($callable);
|
||||
$id = Coroutine::create($callable);
|
||||
return $id > 0 ? $id : false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,17 @@ class FunctionTest extends TestCase
|
||||
$this->assertSame(2, $result);
|
||||
}
|
||||
|
||||
public function testReturnOfGo()
|
||||
{
|
||||
$uniqid = uniqid();
|
||||
$id = go(function () use (&$uniqid) {
|
||||
$uniqid = 'Hyperf';
|
||||
});
|
||||
|
||||
$this->assertTrue(is_int($id));
|
||||
$this->assertSame('Hyperf', $uniqid);
|
||||
}
|
||||
|
||||
public function testDataGet()
|
||||
{
|
||||
$data = ['id' => 1];
|
||||
|
Loading…
Reference in New Issue
Block a user