Merge remote-tracking branch 'upstream/master' into 1.1-db

This commit is contained in:
李铭昕 2019-09-09 20:03:47 +08:00
commit c879b1c566
36 changed files with 304 additions and 295 deletions

View File

@ -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

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -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);
```
```

View File

@ -79,6 +79,7 @@
* [定时任务](zh/crontab.md)
* [Task 机制](zh/task.md)
* [枚举类](zh/constants.md)
* [Snowflake](zh/snowflake.md)
* 应用部署

View File

@ -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']);
});

View File

@ -21,7 +21,6 @@
},
"require": {
"php": ">=7.2",
"ext-swoole": ">=4.3",
"hyperf/utils": "~1.1.0",
"hyperf/etcd": "~1.1.0"
},

View File

@ -20,7 +20,6 @@
},
"require": {
"php": ">=7.2",
"ext-swoole": ">=4.3",
"hyperf/utils": "~1.1.0"
},
"require-dev": {

View File

@ -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",

View File

@ -214,7 +214,7 @@ class SwooleFileStream implements StreamInterface, FileInterface
*/
public function getContents()
{
return $this->contents;
return $this->getFilename();
}
/**

View File

@ -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",

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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' => [
[

View 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;
}
}

View 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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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));
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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)
{
}
}

View File

@ -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,
]);
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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",

View File

@ -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",

View File

@ -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;
}
/**

View File

@ -12,6 +12,7 @@
},
"require": {
"php": ">=7.2",
"ext-swoole": ">=4.4",
"doctrine/inflector": "^1.3",
"hyperf/contract": "~1.1.0"
},

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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",

View File

@ -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",