mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Merge remote-tracking branch 'upstream/master' into 1.1-db
This commit is contained in:
commit
c879b1c566
12
.travis.yml
12
.travis.yml
@ -5,17 +5,11 @@ sudo: required
|
||||
matrix:
|
||||
include:
|
||||
- php: 7.2
|
||||
env: SW_VERSION="4.3.6"
|
||||
- php: 7.2
|
||||
env: SW_VERSION="4.4.5"
|
||||
env: SW_VERSION="4.4.6"
|
||||
- php: 7.3
|
||||
env: SW_VERSION="4.3.6"
|
||||
- php: 7.3
|
||||
env: SW_VERSION="4.4.5"
|
||||
env: SW_VERSION="4.4.6"
|
||||
- php: master
|
||||
env: SW_VERSION="4.3.6"
|
||||
- php: master
|
||||
env: SW_VERSION="4.4.5"
|
||||
env: SW_VERSION="4.4.6"
|
||||
|
||||
allow_failures:
|
||||
- php: master
|
||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -45,19 +45,27 @@ return ApplicationContext::setContainer($container);
|
||||
|
||||
- [#448](https://github.com/hyperf-cloud/hyperf/pull/448) Fixed TCP Server does not works when HTTP Server or WebSocket Server exists.
|
||||
|
||||
# v1.0.14 - TBD
|
||||
# v1.0.15 - TBD
|
||||
|
||||
# v1.0.14 - 2019-09-05
|
||||
|
||||
## Added
|
||||
|
||||
- [#389](https://github.com/hyperf-cloud/hyperf/pull/389) [#419](https://github.com/hyperf-cloud/hyperf/pull/419) [#432](https://github.com/hyperf-cloud/hyperf/pull/432) [#524](https://github.com/hyperf-cloud/hyperf/pull/524) [#531](https://github.com/hyperf-cloud/hyperf/pull/531) Added snowflake component, snowflake is a distributed global unique ID generation algorithm put forward by Twitter, this component implemented this algorithm for easy to use.
|
||||
- [#525](https://github.com/hyperf-cloud/hyperf/pull/525) Added `download()` method of `Hyperf\HttpServer\Contract\ResponseInterface`.
|
||||
|
||||
## Changed
|
||||
|
||||
- [#482](https://github.com/hyperf-cloud/hyperf/pull/482) Re-generate the `fillable` argument of Model when use `refresh-fillable` option, at the same time, the command will keep the `fillable` argument as default behaviours.
|
||||
- [#501](https://github.com/hyperf-cloud/hyperf/pull/501) When the path argument of Mapping annotation is an empty string, then the path is equal to prefix of Controller annotation.
|
||||
- [#513](https://github.com/hyperf-cloud/hyperf/pull/513) Rewrite process name with `app_name`.
|
||||
- [#508](https://github.com/hyperf-cloud/hyperf/pull/508) [#526](https://github.com/hyperf-cloud/hyperf/pull/526) When execute `Hyperf\Utils\Coroutine::parentId()` static method in non-coroutine context will return null.
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#479](https://github.com/hyperf-cloud/hyperf/pull/479) Fixed typehint error when host of Elasticsearch client does not reached.
|
||||
- [#508](https://github.com/hyperf-cloud/hyperf/pull/508) Fixed return type error of `Hyperf\Utils\Coroutine::parentId()` when running in non-coroutine environment.
|
||||
- [#514](https://github.com/hyperf-cloud/hyperf/pull/514) Fixed redis auth failed when the password is an empty string.
|
||||
- [#527](https://github.com/hyperf-cloud/hyperf/pull/527) Fixed translator cannot translate repeatedly.
|
||||
|
||||
# v1.0.13 - 2019-08-28
|
||||
|
||||
|
BIN
doc/zh/imgs/snowflake.jpeg
Normal file
BIN
doc/zh/imgs/snowflake.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -1,5 +1,31 @@
|
||||
# Snowflake
|
||||
|
||||
## 算法介绍
|
||||
|
||||
`Snowflake` 是由 Twitter 提出的一个分布式全局唯一 ID 生成算法,算法生成 `ID` 的结果是一个 `64bit` 大小的长整,标准算法下它的结构如下图:
|
||||
|
||||
![snowflake](./imgs/snowflake.jpeg)
|
||||
|
||||
- `1位`,不用。
|
||||
- 二进制中最高位为符号位,我们生成的 `ID` 一般都是正整数,所以这个最高位固定是 0。
|
||||
|
||||
- `41位`,用来记录时间戳(毫秒)。
|
||||
- `41位` 可以表示 `2^41 - 1` 个数字。
|
||||
- 也就是说 `41位` 可以表示 `2^41 - 1` 个毫秒的值,转化成单位年则是 `(2^41 - 1) / (1000 * 60 * 60 * 24 * 365)` 约为 `69` 年。
|
||||
|
||||
- `10位`,用来记录工作机器 `ID`。
|
||||
- 可以部署在 `2^10` 共 `1024` 个节点,包括 `5` 位 `DatacenterId` 和 `5` 位 `WorkerId`。
|
||||
|
||||
- `12位`,序列号,用来记录同毫秒内产生的不同 `id`。
|
||||
- `12位` 可以表示的最大正整数是 `2^12 - 1` 共 `4095` 个数字,来表示同一机器同一时间截(毫秒)内产生的 `4095` 个 `ID` 序号。
|
||||
|
||||
`Snowflake` 可以保证:
|
||||
|
||||
- 所有生成的 `ID` 按时间趋势递增。
|
||||
- 整个分布式系统内不会产生重复 `ID`(因为有 `DatacenterId (5 bits)` 和 `WorkerId (5 bits)` 来做区分)。
|
||||
|
||||
Hyperf 的 [hyperf/snowflake](https://github.com/hyperf-cloud/snowflake) 组件在设计上提供了很好的可扩展性,允许您通过简单的扩展就能实现其它基于 Snowflake 的变体算法。
|
||||
|
||||
## 安装
|
||||
|
||||
```
|
||||
@ -100,4 +126,4 @@ $userId = 20190620;
|
||||
|
||||
$id = $generator->generate($userId);
|
||||
|
||||
```
|
||||
```
|
||||
|
@ -79,6 +79,7 @@
|
||||
* [定时任务](zh/crontab.md)
|
||||
* [Task 机制](zh/task.md)
|
||||
* [枚举类](zh/constants.md)
|
||||
* [Snowflake](zh/snowflake.md)
|
||||
|
||||
* 应用部署
|
||||
|
||||
|
@ -13,6 +13,7 @@ declare(strict_types=1);
|
||||
namespace Hyperf\Command;
|
||||
|
||||
use Hyperf\Utils\Contracts\Arrayable;
|
||||
use Hyperf\Utils\Coroutine;
|
||||
use Hyperf\Utils\Str;
|
||||
use Symfony\Component\Console\Command\Command as SymfonyCommand;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
@ -55,7 +56,7 @@ abstract class Command extends SymfonyCommand
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $coroutine = false;
|
||||
protected $coroutine = true;
|
||||
|
||||
/**
|
||||
* The mapping between human readable verbosity levels and Symfony's OutputInterface.
|
||||
@ -370,7 +371,7 @@ abstract class Command extends SymfonyCommand
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->coroutine) {
|
||||
if ($this->coroutine && ! Coroutine::inCoroutine()) {
|
||||
run(function () {
|
||||
call([$this, 'handle']);
|
||||
});
|
||||
|
@ -21,7 +21,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"hyperf/utils": "~1.1.0",
|
||||
"hyperf/etcd": "~1.1.0"
|
||||
},
|
||||
|
@ -20,7 +20,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"hyperf/utils": "~1.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -14,7 +14,7 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"ext-swoole": ">=4.4",
|
||||
"fig/http-message-util": "^1.1.2",
|
||||
"hyperf/contract": "~1.1.0",
|
||||
"hyperf/utils": "~1.1.0",
|
||||
|
@ -214,7 +214,7 @@ class SwooleFileStream implements StreamInterface, FileInterface
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
return $this->contents;
|
||||
return $this->getFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,7 +12,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"psr/container": "^1.0",
|
||||
"psr/log": "^1.0",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
|
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Hyperf\Snowflake;
|
||||
|
||||
class Config implements ConfigInterface
|
||||
{
|
||||
const MILLISECOND_BITS = 41;
|
||||
|
||||
const DATA_CENTER_ID_BITS = 5;
|
||||
|
||||
const WORKER_ID_BITS = 5;
|
||||
|
||||
const SEQUENCE_BITS = 12;
|
||||
|
||||
public function maxWorkerId(): int
|
||||
{
|
||||
return -1 ^ (-1 << self::WORKER_ID_BITS);
|
||||
}
|
||||
|
||||
public function maxDataCenterId(): int
|
||||
{
|
||||
return -1 ^ (-1 << self::DATA_CENTER_ID_BITS);
|
||||
}
|
||||
|
||||
public function maxSequence(): int
|
||||
{
|
||||
return -1 ^ (-1 << self::SEQUENCE_BITS);
|
||||
}
|
||||
|
||||
public function getTimeStampShift(): int
|
||||
{
|
||||
return self::SEQUENCE_BITS + self::WORKER_ID_BITS + self::DATA_CENTER_ID_BITS;
|
||||
}
|
||||
|
||||
public function getDataCenterShift(): int
|
||||
{
|
||||
return self::SEQUENCE_BITS + self::WORKER_ID_BITS;
|
||||
}
|
||||
|
||||
public function getWorkerIdShift(): int
|
||||
{
|
||||
return self::SEQUENCE_BITS;
|
||||
}
|
||||
|
||||
public function getTimeStampBits(): int
|
||||
{
|
||||
return self::MILLISECOND_BITS;
|
||||
}
|
||||
|
||||
public function getDataCenterBits(): int
|
||||
{
|
||||
return self::DATA_CENTER_ID_BITS;
|
||||
}
|
||||
|
||||
public function getWorkerBits(): int
|
||||
{
|
||||
return self::WORKER_ID_BITS;
|
||||
}
|
||||
|
||||
public function getSequenceBits(): int
|
||||
{
|
||||
return self::SEQUENCE_BITS;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Hyperf\Snowflake;
|
||||
|
||||
interface ConfigInterface
|
||||
{
|
||||
public function maxWorkerId(): int;
|
||||
|
||||
public function maxDataCenterId(): int;
|
||||
|
||||
public function maxSequence(): int;
|
||||
|
||||
public function getTimeStampShift(): int;
|
||||
|
||||
public function getDataCenterShift(): int;
|
||||
|
||||
public function getWorkerIdShift(): int;
|
||||
|
||||
public function getTimeStampBits(): int;
|
||||
|
||||
public function getDataCenterBits(): int;
|
||||
|
||||
public function getWorkerBits(): int;
|
||||
|
||||
public function getSequenceBits(): int;
|
||||
}
|
@ -22,16 +22,7 @@ class ConfigProvider
|
||||
'dependencies' => [
|
||||
IdGeneratorInterface::class => SnowflakeIdGenerator::class,
|
||||
MetaGeneratorInterface::class => MetaGeneratorFactory::class,
|
||||
ConfigInterface::class => Config::class,
|
||||
],
|
||||
'commands' => [
|
||||
],
|
||||
'listeners' => [
|
||||
],
|
||||
'scan' => [
|
||||
'paths' => [
|
||||
__DIR__,
|
||||
],
|
||||
ConfigurationInterface::class => Configuration::class,
|
||||
],
|
||||
'publish' => [
|
||||
[
|
||||
|
74
src/snowflake/src/Configuration.php
Normal file
74
src/snowflake/src/Configuration.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Hyperf\Snowflake;
|
||||
|
||||
class Configuration implements ConfigurationInterface
|
||||
{
|
||||
protected $millisecondBits = 41;
|
||||
|
||||
protected $dataCenterIdBits = 5;
|
||||
|
||||
protected $workerIdBits = 5;
|
||||
|
||||
protected $sequenceBits = 12;
|
||||
|
||||
public function maxWorkerId(): int
|
||||
{
|
||||
return -1 ^ (-1 << $this->workerIdBits);
|
||||
}
|
||||
|
||||
public function maxDataCenterId(): int
|
||||
{
|
||||
return -1 ^ (-1 << $this->dataCenterIdBits);
|
||||
}
|
||||
|
||||
public function maxSequence(): int
|
||||
{
|
||||
return -1 ^ (-1 << $this->sequenceBits);
|
||||
}
|
||||
|
||||
public function getTimestampLeftShift(): int
|
||||
{
|
||||
return $this->sequenceBits + $this->workerIdBits + $this->dataCenterIdBits;
|
||||
}
|
||||
|
||||
public function getDataCenterIdShift(): int
|
||||
{
|
||||
return $this->sequenceBits + $this->workerIdBits;
|
||||
}
|
||||
|
||||
public function getWorkerIdShift(): int
|
||||
{
|
||||
return $this->sequenceBits;
|
||||
}
|
||||
|
||||
public function getTimestampBits(): int
|
||||
{
|
||||
return $this->millisecondBits;
|
||||
}
|
||||
|
||||
public function getDataCenterIdBits(): int
|
||||
{
|
||||
return $this->dataCenterIdBits;
|
||||
}
|
||||
|
||||
public function getWorkerIdBits(): int
|
||||
{
|
||||
return $this->workerIdBits;
|
||||
}
|
||||
|
||||
public function getSequenceBits(): int
|
||||
{
|
||||
return $this->sequenceBits;
|
||||
}
|
||||
}
|
66
src/snowflake/src/ConfigurationInterface.php
Normal file
66
src/snowflake/src/ConfigurationInterface.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Hyperf\Snowflake;
|
||||
|
||||
interface ConfigurationInterface
|
||||
{
|
||||
/**
|
||||
* Get the maximum worker id bits.
|
||||
*/
|
||||
public function maxWorkerId(): int;
|
||||
|
||||
/**
|
||||
* Get the maximum data center id bits.
|
||||
*/
|
||||
public function maxDataCenterId(): int;
|
||||
|
||||
/**
|
||||
* Get the maximum sequence bits.
|
||||
*/
|
||||
public function maxSequence(): int;
|
||||
|
||||
/**
|
||||
* Get the timestamp left shift.
|
||||
*/
|
||||
public function getTimestampLeftShift(): int;
|
||||
|
||||
/**
|
||||
* Get the data center id shift.
|
||||
*/
|
||||
public function getDataCenterIdShift(): int;
|
||||
|
||||
/**
|
||||
* Get the worker id shift.
|
||||
*/
|
||||
public function getWorkerIdShift(): int;
|
||||
|
||||
/**
|
||||
* Get the timestamp bits.
|
||||
*/
|
||||
public function getTimestampBits(): int;
|
||||
|
||||
/**
|
||||
* Get the data center id bits.
|
||||
*/
|
||||
public function getDataCenterIdBits(): int;
|
||||
|
||||
/**
|
||||
* Get the worker id bits.
|
||||
*/
|
||||
public function getWorkerIdBits(): int;
|
||||
|
||||
/**
|
||||
* Get the sequence bits.
|
||||
*/
|
||||
public function getSequenceBits(): int;
|
||||
}
|
@ -20,22 +20,22 @@ abstract class IdGenerator implements IdGeneratorInterface
|
||||
protected $metaGenerator;
|
||||
|
||||
/**
|
||||
* @var ConfigInterface
|
||||
* @var ConfigurationInterface
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
public function __construct(MetaGeneratorInterface $metaGenerator)
|
||||
{
|
||||
$this->metaGenerator = $metaGenerator;
|
||||
$this->config = $metaGenerator->getConfig();
|
||||
$this->config = $metaGenerator->getConfiguration();
|
||||
}
|
||||
|
||||
public function generate(?Meta $meta = null): int
|
||||
{
|
||||
$meta = $this->meta($meta);
|
||||
|
||||
$interval = $meta->getTimeInterval() << $this->config->getTimeStampShift();
|
||||
$dataCenterId = $meta->getDataCenterId() << $this->config->getDataCenterShift();
|
||||
$interval = $meta->getTimeInterval() << $this->config->getTimestampLeftShift();
|
||||
$dataCenterId = $meta->getDataCenterId() << $this->config->getDataCenterIdShift();
|
||||
$workerId = $meta->getWorkerId() << $this->config->getWorkerIdShift();
|
||||
|
||||
return $interval | $dataCenterId | $workerId | $meta->getSequence();
|
||||
@ -43,22 +43,19 @@ abstract class IdGenerator implements IdGeneratorInterface
|
||||
|
||||
public function degenerate(int $id): Meta
|
||||
{
|
||||
$interval = $id >> $this->config->getTimeStampShift();
|
||||
$dataCenterId = $id >> $this->config->getDataCenterShift();
|
||||
$interval = $id >> $this->config->getTimestampLeftShift();
|
||||
$dataCenterId = $id >> $this->config->getDataCenterIdShift();
|
||||
$workerId = $id >> $this->config->getWorkerIdShift();
|
||||
|
||||
return new Meta(
|
||||
$interval << $this->config->getDataCenterBits() ^ $dataCenterId,
|
||||
$dataCenterId << $this->config->getWorkerBits() ^ $workerId,
|
||||
$interval << $this->config->getDataCenterIdBits() ^ $dataCenterId,
|
||||
$dataCenterId << $this->config->getWorkerIdBits() ^ $workerId,
|
||||
$workerId << $this->config->getSequenceBits() ^ $id,
|
||||
$interval + $this->metaGenerator->getBeginTimeStamp(),
|
||||
$this->metaGenerator->getBeginTimeStamp()
|
||||
$interval + $this->metaGenerator->getBeginTimestamp(),
|
||||
$this->metaGenerator->getBeginTimestamp()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MetaGeneratorInterface
|
||||
*/
|
||||
public function getMetaGenerator(): MetaGeneratorInterface
|
||||
{
|
||||
return $this->metaGenerator;
|
||||
|
@ -14,7 +14,13 @@ namespace Hyperf\Snowflake;
|
||||
|
||||
interface IdGeneratorInterface extends \Hyperf\Contract\IdGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* Generate an ID by meta, if meta is null, then use the default meta.
|
||||
*/
|
||||
public function generate(?Meta $meta = null): int;
|
||||
|
||||
/**
|
||||
* Degenerate the meta by ID.
|
||||
*/
|
||||
public function degenerate(int $id): Meta;
|
||||
}
|
||||
|
@ -14,14 +14,6 @@ namespace Hyperf\Snowflake;
|
||||
|
||||
class Meta
|
||||
{
|
||||
const MILLISECOND_BITS = 41;
|
||||
|
||||
const DATA_CENTER_ID_BITS = 5;
|
||||
|
||||
const MACHINE_ID_BITS = 5;
|
||||
|
||||
const SEQUENCE_BITS = 12;
|
||||
|
||||
/**
|
||||
* @var int [0, 31]
|
||||
*/
|
||||
@ -45,89 +37,62 @@ class Meta
|
||||
/**
|
||||
* @var int seconds or milliseconds
|
||||
*/
|
||||
protected $beginTimeStamp = 0;
|
||||
protected $beginTimestamp = 0;
|
||||
|
||||
public function __construct(int $dataCenterId, int $workerId, int $sequence, int $timestamp, int $beginTimeStamp = 1560960000)
|
||||
public function __construct(int $dataCenterId, int $workerId, int $sequence, int $timestamp, int $beginTimestamp = 1560960000)
|
||||
{
|
||||
$this->dataCenterId = $dataCenterId;
|
||||
$this->workerId = $workerId;
|
||||
$this->sequence = $sequence;
|
||||
$this->timestamp = $timestamp;
|
||||
$this->beginTimeStamp = $beginTimeStamp;
|
||||
$this->beginTimestamp = $beginTimestamp;
|
||||
}
|
||||
|
||||
public function getTimeInterval(): int
|
||||
{
|
||||
return $this->timestamp - $this->beginTimeStamp;
|
||||
return $this->timestamp - $this->beginTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDataCenterId(): int
|
||||
{
|
||||
return $this->dataCenterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getWorkerId(): int
|
||||
{
|
||||
return $this->workerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getSequence(): int
|
||||
{
|
||||
return $this->sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dataCenterId
|
||||
* @return Meta
|
||||
*/
|
||||
public function setDataCenterId(int $dataCenterId): self
|
||||
{
|
||||
$this->dataCenterId = $dataCenterId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $workerId
|
||||
* @return Meta
|
||||
*/
|
||||
public function setWorkerId(int $workerId): self
|
||||
{
|
||||
$this->workerId = $workerId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $sequence
|
||||
* @return Meta
|
||||
*/
|
||||
public function setSequence(int $sequence): self
|
||||
{
|
||||
$this->sequence = $sequence;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getBeginTimeStamp(): int
|
||||
public function getBeginTimestamp(): int
|
||||
{
|
||||
return $this->beginTimeStamp;
|
||||
return $this->beginTimestamp;
|
||||
}
|
||||
}
|
||||
|
@ -17,69 +17,69 @@ use Hyperf\Snowflake\Exception\SnowflakeException;
|
||||
abstract class MetaGenerator implements MetaGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* @var ConfigInterface
|
||||
* @var ConfigurationInterface
|
||||
*/
|
||||
protected $config;
|
||||
protected $configuration;
|
||||
|
||||
protected $sequence = 0;
|
||||
|
||||
protected $lastTimeStamp = 0;
|
||||
protected $lastTimestamp = 0;
|
||||
|
||||
protected $beginTimeStamp = 0;
|
||||
protected $beginTimestamp = 0;
|
||||
|
||||
public function __construct(ConfigInterface $config, int $beginTimeStamp)
|
||||
public function __construct(ConfigurationInterface $configuration, int $beginTimestamp)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->lastTimeStamp = $this->getTimeStamp();
|
||||
$this->beginTimeStamp = $beginTimeStamp;
|
||||
$this->configuration = $configuration;
|
||||
$this->lastTimestamp = $this->getTimestamp();
|
||||
$this->beginTimestamp = $beginTimestamp;
|
||||
}
|
||||
|
||||
public function generate(): Meta
|
||||
{
|
||||
$timestamp = $this->getTimeStamp();
|
||||
$timestamp = $this->getTimestamp();
|
||||
|
||||
if ($timestamp < $this->lastTimeStamp) {
|
||||
$this->clockMovedBackwards($timestamp, $this->lastTimeStamp);
|
||||
}
|
||||
|
||||
if ($timestamp == $this->lastTimeStamp) {
|
||||
$this->sequence = ($this->sequence + 1) % $this->config->maxSequence();
|
||||
if ($timestamp == $this->lastTimestamp) {
|
||||
$this->sequence = ($this->sequence + 1) % $this->configuration->maxSequence();
|
||||
if ($this->sequence == 0) {
|
||||
$timestamp = $this->getNextTimeStamp();
|
||||
$timestamp = $this->getNextTimestamp();
|
||||
}
|
||||
} else {
|
||||
$this->sequence = 0;
|
||||
}
|
||||
|
||||
if ($timestamp < $this->beginTimeStamp) {
|
||||
throw new SnowflakeException(sprintf('The beginTimeStamp %d is invalid, because it smaller than timestamp %d.', $this->beginTimeStamp, $timestamp));
|
||||
if ($timestamp < $this->lastTimestamp) {
|
||||
$this->clockMovedBackwards($timestamp, $this->lastTimestamp);
|
||||
}
|
||||
|
||||
$this->lastTimeStamp = $timestamp;
|
||||
if ($timestamp < $this->beginTimestamp) {
|
||||
throw new SnowflakeException(sprintf('The beginTimestamp %d is invalid, because it smaller than timestamp %d.', $this->beginTimestamp, $timestamp));
|
||||
}
|
||||
|
||||
return new Meta($this->getDataCenterId(), $this->getWorkerId(), $this->sequence, $timestamp, $this->beginTimeStamp);
|
||||
$this->lastTimestamp = $timestamp;
|
||||
|
||||
return new Meta($this->getDataCenterId(), $this->getWorkerId(), $this->sequence, $timestamp, $this->beginTimestamp);
|
||||
}
|
||||
|
||||
public function getBeginTimeStamp(): int
|
||||
public function getBeginTimestamp(): int
|
||||
{
|
||||
return $this->beginTimeStamp;
|
||||
return $this->beginTimestamp;
|
||||
}
|
||||
|
||||
public function getConfig(): ConfigInterface
|
||||
public function getConfiguration(): ConfigurationInterface
|
||||
{
|
||||
return $this->config;
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
abstract public function getDataCenterId(): int;
|
||||
|
||||
abstract public function getWorkerId(): int;
|
||||
|
||||
abstract public function getTimeStamp(): int;
|
||||
abstract public function getTimestamp(): int;
|
||||
|
||||
abstract public function getNextTimeStamp(): int;
|
||||
abstract public function getNextTimestamp(): int;
|
||||
|
||||
protected function clockMovedBackwards($timestamp, $lastTimeStamp)
|
||||
protected function clockMovedBackwards($timestamp, $lastTimestamp)
|
||||
{
|
||||
throw new SnowflakeException(sprintf('Clock moved backwards. Refusing to generate id for %d milliseconds.', $lastTimeStamp - $timestamp));
|
||||
throw new SnowflakeException(sprintf('Clock moved backwards. Refusing to generate id for %d milliseconds.', $lastTimestamp - $timestamp));
|
||||
}
|
||||
}
|
||||
|
@ -12,14 +12,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace Hyperf\Snowflake\MetaGenerator;
|
||||
|
||||
use Hyperf\Snowflake\ConfigInterface;
|
||||
use Hyperf\Snowflake\ConfigurationInterface;
|
||||
use Hyperf\Snowflake\MetaGenerator;
|
||||
|
||||
class RandomMilliSecondMetaGenerator extends MetaGenerator
|
||||
{
|
||||
public function __construct(ConfigInterface $config, int $beginTimeStamp)
|
||||
public function __construct(ConfigurationInterface $configuration, int $beginTimestamp)
|
||||
{
|
||||
parent::__construct($config, $beginTimeStamp * 1000);
|
||||
parent::__construct($configuration, $beginTimestamp * 1000);
|
||||
}
|
||||
|
||||
public function getDataCenterId(): int
|
||||
@ -32,16 +32,16 @@ class RandomMilliSecondMetaGenerator extends MetaGenerator
|
||||
return rand(0, 31);
|
||||
}
|
||||
|
||||
public function getTimeStamp(): int
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
return intval(microtime(true) * 1000);
|
||||
}
|
||||
|
||||
public function getNextTimeStamp(): int
|
||||
public function getNextTimestamp(): int
|
||||
{
|
||||
$timestamp = $this->getTimeStamp();
|
||||
while ($timestamp <= $this->lastTimeStamp) {
|
||||
$timestamp = $this->getTimeStamp();
|
||||
$timestamp = $this->getTimestamp();
|
||||
while ($timestamp <= $this->lastTimestamp) {
|
||||
$timestamp = $this->getTimestamp();
|
||||
}
|
||||
|
||||
return $timestamp;
|
||||
|
@ -12,34 +12,35 @@ declare(strict_types=1);
|
||||
|
||||
namespace Hyperf\Snowflake\MetaGenerator;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface as HyperfConfig;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Redis\RedisProxy;
|
||||
use Hyperf\Snowflake\ConfigInterface;
|
||||
use Hyperf\Snowflake\ConfigurationInterface;
|
||||
use Hyperf\Snowflake\MetaGenerator;
|
||||
|
||||
class RedisMilliSecondMetaGenerator extends MetaGenerator
|
||||
{
|
||||
const REDIS_KEY = 'hyperf:snowflake:worker';
|
||||
const DEFAULT_REDIS_KEY = 'hyperf:snowflake:workerId';
|
||||
|
||||
protected $workerId;
|
||||
|
||||
protected $dataCenterId;
|
||||
|
||||
public function __construct(HyperfConfig $hConfig, ConfigInterface $config, int $beginTimeStamp = self::DEFAULT_BEGIN_SECOND)
|
||||
public function __construct(ConfigurationInterface $configuration, int $beginTimestamp = self::DEFAULT_BEGIN_SECOND, ConfigInterface $config)
|
||||
{
|
||||
parent::__construct($config, $beginTimeStamp * 1000);
|
||||
parent::__construct($configuration, $beginTimestamp * 1000);
|
||||
|
||||
$pool = $hConfig->get('snowflake.' . static::class . '.pool', 'default');
|
||||
$pool = $config->get('snowflake.' . static::class . '.pool', 'default');
|
||||
|
||||
/** @var \Redis $redis */
|
||||
$redis = make(RedisProxy::class, [
|
||||
'pool' => $pool,
|
||||
]);
|
||||
|
||||
$id = $redis->incr(static::REDIS_KEY);
|
||||
$key = $config->get(sprintf('snowflake.%s.key', static::class), static::DEFAULT_REDIS_KEY);
|
||||
$id = $redis->incr($key);
|
||||
|
||||
$this->workerId = $id % $config->maxWorkerId();
|
||||
$this->dataCenterId = intval($id / $config->maxWorkerId()) % $config->maxDataCenterId();
|
||||
$this->workerId = $id % $configuration->maxWorkerId();
|
||||
$this->dataCenterId = intval($id / $configuration->maxWorkerId()) % $configuration->maxDataCenterId();
|
||||
}
|
||||
|
||||
public function getDataCenterId(): int
|
||||
@ -52,16 +53,16 @@ class RedisMilliSecondMetaGenerator extends MetaGenerator
|
||||
return $this->workerId;
|
||||
}
|
||||
|
||||
public function getTimeStamp(): int
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
return intval(microtime(true) * 1000);
|
||||
}
|
||||
|
||||
public function getNextTimeStamp(): int
|
||||
public function getNextTimestamp(): int
|
||||
{
|
||||
$timestamp = $this->getTimeStamp();
|
||||
while ($timestamp <= $this->lastTimeStamp) {
|
||||
$timestamp = $this->getTimeStamp();
|
||||
$timestamp = $this->getTimestamp();
|
||||
while ($timestamp <= $this->lastTimestamp) {
|
||||
$timestamp = $this->getTimestamp();
|
||||
}
|
||||
|
||||
return $timestamp;
|
||||
|
@ -12,34 +12,35 @@ declare(strict_types=1);
|
||||
|
||||
namespace Hyperf\Snowflake\MetaGenerator;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface as HyperfConfig;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Redis\RedisProxy;
|
||||
use Hyperf\Snowflake\ConfigInterface;
|
||||
use Hyperf\Snowflake\ConfigurationInterface;
|
||||
use Hyperf\Snowflake\MetaGenerator;
|
||||
|
||||
class RedisSecondMetaGenerator extends MetaGenerator
|
||||
{
|
||||
const REDIS_KEY = 'hyperf:snowflake:worker';
|
||||
const DEFAULT_REDIS_KEY = 'hyperf:snowflake:workerId';
|
||||
|
||||
protected $workerId;
|
||||
|
||||
protected $dataCenterId;
|
||||
|
||||
public function __construct(HyperfConfig $hConfig, ConfigInterface $config, int $beginTimeStamp = self::DEFAULT_BEGIN_SECOND)
|
||||
public function __construct(ConfigurationInterface $configuration, int $beginTimestamp = self::DEFAULT_BEGIN_SECOND, ConfigInterface $config)
|
||||
{
|
||||
parent::__construct($config, $beginTimeStamp);
|
||||
parent::__construct($configuration, $beginTimestamp);
|
||||
|
||||
$pool = $hConfig->get('snowflake.' . static::class . '.pool', 'default');
|
||||
$pool = $config->get('snowflake.' . static::class . '.pool', 'default');
|
||||
|
||||
/** @var \Redis $redis */
|
||||
$redis = make(RedisProxy::class, [
|
||||
'pool' => $pool,
|
||||
]);
|
||||
|
||||
$id = $redis->incr(static::REDIS_KEY);
|
||||
$key = $config->get(sprintf('snowflake.%s.key', static::class), static::DEFAULT_REDIS_KEY);
|
||||
$id = $redis->incr($key);
|
||||
|
||||
$this->workerId = $id % $config->maxWorkerId();
|
||||
$this->dataCenterId = intval($id / $config->maxWorkerId()) % $config->maxDataCenterId();
|
||||
$this->workerId = $id % $configuration->maxWorkerId();
|
||||
$this->dataCenterId = intval($id / $configuration->maxWorkerId()) % $configuration->maxDataCenterId();
|
||||
}
|
||||
|
||||
public function getDataCenterId(): int
|
||||
@ -52,17 +53,17 @@ class RedisSecondMetaGenerator extends MetaGenerator
|
||||
return $this->workerId;
|
||||
}
|
||||
|
||||
public function getTimeStamp(): int
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
public function getNextTimeStamp(): int
|
||||
public function getNextTimestamp(): int
|
||||
{
|
||||
return $this->lastTimeStamp + 1;
|
||||
return $this->lastTimestamp + 1;
|
||||
}
|
||||
|
||||
protected function clockMovedBackwards($timestamp, $lastTimeStamp)
|
||||
protected function clockMovedBackwards($timestamp, $lastTimestamp)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
namespace Hyperf\Snowflake;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Snowflake\ConfigInterface as SnowflakeConfigInterface;
|
||||
use Hyperf\Snowflake\MetaGenerator\RedisMilliSecondMetaGenerator;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
@ -25,9 +24,9 @@ class MetaGeneratorFactory
|
||||
$beginSecond = $config->get('snowflake.begin_second', MetaGeneratorInterface::DEFAULT_BEGIN_SECOND);
|
||||
|
||||
return make(RedisMilliSecondMetaGenerator::class, [
|
||||
$config,
|
||||
$container->get(SnowflakeConfigInterface::class),
|
||||
$container->get(ConfigurationInterface::class),
|
||||
$beginSecond,
|
||||
$config,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ interface MetaGeneratorInterface
|
||||
|
||||
public function generate(): Meta;
|
||||
|
||||
public function getBeginTimeStamp(): int;
|
||||
public function getBeginTimestamp(): int;
|
||||
|
||||
public function getConfig(): ConfigInterface;
|
||||
public function getConfiguration(): ConfigurationInterface;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use Hyperf\Redis\Frequency;
|
||||
use Hyperf\Redis\Pool\PoolFactory;
|
||||
use Hyperf\Redis\Pool\RedisPool;
|
||||
use Hyperf\Redis\RedisProxy;
|
||||
use Hyperf\Snowflake\Config as SnowflakeConfig;
|
||||
use Hyperf\Snowflake\Configuration as SnowflakeConfig;
|
||||
use Hyperf\Snowflake\IdGenerator\SnowflakeIdGenerator;
|
||||
use Hyperf\Snowflake\Meta;
|
||||
use Hyperf\Snowflake\MetaGenerator\RedisMilliSecondMetaGenerator;
|
||||
@ -42,14 +42,14 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
{
|
||||
$container = $this->getContainer();
|
||||
$redis = $container->make(RedisProxy::class, ['pool' => 'snowflake']);
|
||||
$redis->del(RedisMilliSecondMetaGenerator::REDIS_KEY);
|
||||
$redis->del(RedisMilliSecondMetaGenerator::DEFAULT_REDIS_KEY);
|
||||
}
|
||||
|
||||
public function testGenerateMeta()
|
||||
{
|
||||
$container = $this->getContainer();
|
||||
$config = $container->get(ConfigInterface::class);
|
||||
$metaGenerator = new RedisMilliSecondMetaGenerator($config, new SnowflakeConfig());
|
||||
$metaGenerator = new RedisMilliSecondMetaGenerator(new SnowflakeConfig(), MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $config);
|
||||
|
||||
$meta = $metaGenerator->generate();
|
||||
$this->assertInstanceOf(Meta::class, $meta);
|
||||
@ -62,7 +62,7 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
$config = new SnowflakeConfig();
|
||||
$metaGenerator = new RedisMilliSecondMetaGenerator($hConfig, $config);
|
||||
$metaGenerator = new RedisMilliSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $hConfig);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
|
||||
$id = $generator->generate();
|
||||
@ -79,7 +79,7 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
$config = new SnowflakeConfig();
|
||||
$metaGenerator = new RedisSecondMetaGenerator($hConfig, $config);
|
||||
$metaGenerator = new RedisSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $hConfig);
|
||||
$meta = $metaGenerator->generate();
|
||||
$this->assertInstanceOf(Meta::class, $meta);
|
||||
$this->assertSame(0, $meta->getDataCenterId());
|
||||
@ -91,7 +91,7 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
$config = new SnowflakeConfig();
|
||||
$metaGenerator = new RedisSecondMetaGenerator($hConfig, $config);
|
||||
$metaGenerator = new RedisSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $hConfig);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
|
||||
$id = $generator->generate();
|
||||
@ -108,7 +108,7 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
$config = new SnowflakeConfig();
|
||||
$metaGenerator = new RedisSecondMetaGenerator($hConfig, $config);
|
||||
$metaGenerator = new RedisSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $hConfig);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
|
||||
$meta = $generator->degenerate(PHP_INT_MAX);
|
||||
@ -125,7 +125,7 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
$config = new SnowflakeConfig();
|
||||
$metaGenerator = new RedisSecondMetaGenerator($hConfig, $config);
|
||||
$metaGenerator = new RedisSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $hConfig);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
$generator = new UserDefinedIdGenerator($generator);
|
||||
|
||||
|
@ -12,7 +12,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace HyperfTest\Snowflake;
|
||||
|
||||
use Hyperf\Snowflake\Config;
|
||||
use Hyperf\Snowflake\Configuration;
|
||||
use Hyperf\Snowflake\IdGenerator\SnowflakeIdGenerator;
|
||||
use Hyperf\Snowflake\Meta;
|
||||
use Hyperf\Snowflake\MetaGenerator\RandomMilliSecondMetaGenerator;
|
||||
@ -27,14 +27,14 @@ class SnowflakeGeneratorTest extends TestCase
|
||||
{
|
||||
public function testGenerateReturnInt()
|
||||
{
|
||||
$config = new Config();
|
||||
$config = new Configuration();
|
||||
$generator = new SnowflakeIdGenerator(new RandomMilliSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND));
|
||||
$this->assertTrue(is_int($generator->generate()));
|
||||
}
|
||||
|
||||
public function testDegenerateInstanceofMeta()
|
||||
{
|
||||
$config = new Config();
|
||||
$config = new Configuration();
|
||||
$generator = new SnowflakeIdGenerator(new RandomMilliSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND));
|
||||
|
||||
$id = $generator->generate();
|
||||
@ -44,7 +44,7 @@ class SnowflakeGeneratorTest extends TestCase
|
||||
|
||||
public function testGenerateAndDegenerate()
|
||||
{
|
||||
$config = new Config();
|
||||
$config = new Configuration();
|
||||
$metaGenerator = new RandomMilliSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
|
||||
@ -55,7 +55,7 @@ class SnowflakeGeneratorTest extends TestCase
|
||||
|
||||
public function testDegenerateMaxId()
|
||||
{
|
||||
$config = new Config();
|
||||
$config = new Configuration();
|
||||
$metaGenerator = new RandomMilliSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"hyperf/contract": "~1.1.0",
|
||||
"hyperf/utils": "~1.1.0",
|
||||
"psr/container": "^1.0",
|
||||
|
@ -12,7 +12,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"hyperf/contract": "~1.1.0",
|
||||
"hyperf/utils": "~1.1.0",
|
||||
"psr/container": "^1.0",
|
||||
|
@ -267,16 +267,15 @@ class Translator implements TranslatorInterface
|
||||
$parsed = $this->parseNamespacedSegments($key);
|
||||
}
|
||||
|
||||
if (is_null($parsed[0])) {
|
||||
$parsed[0] = '*';
|
||||
}
|
||||
|
||||
// Once we have the parsed array of this key's elements, such as its groups
|
||||
// and namespace, we will cache each array inside a simple list that has
|
||||
// the key and the parsed array for quick look-ups for later requests.
|
||||
$segments = $this->parsed[$key] = $parsed;
|
||||
|
||||
if (is_null($segments[0])) {
|
||||
$segments[0] = '*';
|
||||
}
|
||||
|
||||
return $segments;
|
||||
return $this->parsed[$key] = $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,7 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.4",
|
||||
"doctrine/inflector": "^1.3",
|
||||
"hyperf/contract": "~1.1.0"
|
||||
},
|
||||
|
@ -42,15 +42,16 @@ class Coroutine
|
||||
|
||||
/**
|
||||
* Returns the parent coroutine ID.
|
||||
* Returns -1 when running in non-coroutine context.
|
||||
* Returns -1 when running in the top level coroutine.
|
||||
* Returns null when running in non-coroutine context.
|
||||
*
|
||||
* @see https://github.com/swoole/swoole-src/pull/2669/files#diff-3bdf726b0ac53be7e274b60d59e6ec80R940
|
||||
*/
|
||||
public static function parentId(): int
|
||||
public static function parentId(): ?int
|
||||
{
|
||||
$cid = SwooleCoroutine::getPcid();
|
||||
if ($cid === false) {
|
||||
return -1;
|
||||
return null;
|
||||
}
|
||||
|
||||
return $cid;
|
||||
|
@ -422,12 +422,7 @@ if (! function_exists('run')) {
|
||||
|
||||
\Swoole\Runtime::enableCoroutine(true, $flags);
|
||||
|
||||
if (version_compare(swoole_version(), '4.4.0', '>=')) {
|
||||
$result = \Swoole\Coroutine\Run($callback);
|
||||
} else {
|
||||
go($callback);
|
||||
$result = true;
|
||||
}
|
||||
$result = \Swoole\Coroutine\Run($callback);
|
||||
|
||||
\Swoole\Runtime::enableCoroutine(false);
|
||||
return $result;
|
||||
|
@ -324,7 +324,7 @@ class Str
|
||||
/**
|
||||
* Replace the first occurrence of a given value in the string.
|
||||
*/
|
||||
public static function replaceFirst(string $search, string $replace, string $subject): string
|
||||
public static function replaceFirst(string $search, string $replace, string $subject): string
|
||||
{
|
||||
if ($search == '') {
|
||||
return $subject;
|
||||
@ -342,7 +342,7 @@ class Str
|
||||
/**
|
||||
* Replace the last occurrence of a given value in the string.
|
||||
*/
|
||||
public static function replaceLast(string $search, string $replace, string $subject): string
|
||||
public static function replaceLast(string $search, string $replace, string $subject): string
|
||||
{
|
||||
$position = strrpos($subject, $search);
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"hyperf/contract": "~1.1.0",
|
||||
"hyperf/http-message": "~1.1.0",
|
||||
"hyperf/utils": "~1.1.0",
|
||||
|
@ -12,7 +12,6 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"ext-swoole": ">=4.3",
|
||||
"hyperf/contract": "~1.1.0",
|
||||
"hyperf/exception-handler": "~1.1.0",
|
||||
"hyperf/http-server": "~1.1.0",
|
||||
|
Loading…
Reference in New Issue
Block a user