mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-01 19:27:39 +08:00
Fixed bug that RedisSecondMetaGenerator
will generate the same meta. (#2640)
* Fixed bug that `RedisSecondMetaGenerator` will generate the same meta. * Update RedisMetaGenerator.php * Update CHANGELOG-2.0.md
This commit is contained in:
parent
044d827d2a
commit
84e19f78de
@ -2,7 +2,7 @@
|
||||
|
||||
## Fixed
|
||||
|
||||
- [#2634](https://github.com/hyperf/hyperf/pull/2634) Fixed bug that `RedisSecondMetaGenerator` will generate the same meta.
|
||||
- [#2634](https://github.com/hyperf/hyperf/pull/2634) [#2640](https://github.com/hyperf/hyperf/pull/2640) Fixed bug that `RedisSecondMetaGenerator` will generate the same meta.
|
||||
- [#2639](https://github.com/hyperf/hyperf/pull/2639) Fixed exception will not be normalized for json-rpc.
|
||||
|
||||
# v2.0.14 - 2020-10-12
|
||||
|
@ -2,9 +2,12 @@
|
||||
<?php
|
||||
|
||||
$code = 0;
|
||||
Swoole\Coroutine::set(['exit_condition' => function(){
|
||||
return Swoole\Coroutine::stats()['coroutine_num'] === 0;
|
||||
}]);
|
||||
Swoole\Coroutine::set([
|
||||
'hook_flags' => SWOOLE_HOOK_ALL,
|
||||
'exit_condition' => function(){
|
||||
return Swoole\Coroutine::stats()['coroutine_num'] === 0;
|
||||
}
|
||||
]);
|
||||
Swoole\Coroutine\Run(function () use (&$code) {
|
||||
if (version_compare('7.1.0', PHP_VERSION, '>')) {
|
||||
fwrite(
|
||||
|
@ -42,14 +42,14 @@ abstract class MetaGenerator implements MetaGeneratorInterface
|
||||
if ($this->sequence == 0) {
|
||||
$timestamp = $this->getNextTimestamp();
|
||||
}
|
||||
} elseif ($timestamp < $this->lastTimestamp) {
|
||||
$this->clockMovedBackwards($timestamp, $this->lastTimestamp);
|
||||
$this->sequence = ($this->sequence + 1) % $this->configuration->maxSequence();
|
||||
$timestamp = $this->lastTimestamp;
|
||||
} else {
|
||||
$this->sequence = 0;
|
||||
}
|
||||
|
||||
if ($timestamp < $this->lastTimestamp) {
|
||||
$this->clockMovedBackwards($timestamp, $this->lastTimestamp);
|
||||
}
|
||||
|
||||
if ($timestamp < $this->beginTimestamp) {
|
||||
throw new SnowflakeException(sprintf('The beginTimestamp %d is invalid, because it smaller than timestamp %d.', $this->beginTimestamp, $timestamp));
|
||||
}
|
||||
|
@ -28,12 +28,11 @@ class RedisSecondMetaGenerator extends RedisMetaGenerator
|
||||
|
||||
public function getNextTimestamp(): int
|
||||
{
|
||||
$timestamp = $this->getTimestamp();
|
||||
while ($timestamp <= $this->lastTimestamp) {
|
||||
usleep(1000);
|
||||
$timestamp = $this->getTimestamp();
|
||||
}
|
||||
return $this->lastTimestamp + 1;
|
||||
}
|
||||
|
||||
return $timestamp;
|
||||
protected function clockMovedBackwards($timestamp, $lastTimestamp)
|
||||
{
|
||||
// Don't throw exception
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$this->assertSame($meta->getWorkerId(), $userId % 31);
|
||||
}
|
||||
|
||||
public function testGetNextTimestamp()
|
||||
public function testRedisSecondNextTimestamp()
|
||||
{
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
@ -147,7 +147,43 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
$time = $metaGenerator->getTimestamp();
|
||||
$nextTime = $metaGenerator->getNextTimestamp();
|
||||
$this->assertSame($time + 1, $nextTime);
|
||||
$this->assertSame(time(), $nextTime);
|
||||
}
|
||||
|
||||
public function testGenerateSameMetaForRedisSecond()
|
||||
{
|
||||
$container = $this->getContainer();
|
||||
$hConfig = $container->get(ConfigInterface::class);
|
||||
$config = new SnowflakeConfig();
|
||||
$metaGenerator = new RedisSecondMetaGenerator($config, MetaGeneratorInterface::DEFAULT_BEGIN_SECOND, $hConfig);
|
||||
$generator = new SnowflakeIdGenerator($metaGenerator);
|
||||
$result = [];
|
||||
$channel = new Channel(2);
|
||||
go(function () use (&$result, $generator, $channel) {
|
||||
try {
|
||||
for ($i = 0; $i < 4100; ++$i) {
|
||||
$result[] = $generator->generate();
|
||||
}
|
||||
} catch (\Throwable $exception) {
|
||||
} finally {
|
||||
$channel->push(true);
|
||||
}
|
||||
});
|
||||
|
||||
go(function () use (&$result, $generator, $channel) {
|
||||
try {
|
||||
for ($i = 0; $i < 900; ++$i) {
|
||||
$result[] = $generator->generate();
|
||||
}
|
||||
} catch (\Throwable $exception) {
|
||||
} finally {
|
||||
$channel->push(true);
|
||||
}
|
||||
});
|
||||
|
||||
$channel->pop(5);
|
||||
$channel->pop(5);
|
||||
|
||||
$this->assertSame(5000, count(array_unique($result)));
|
||||
}
|
||||
|
||||
protected function getContainer()
|
||||
@ -184,6 +220,8 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
]);
|
||||
|
||||
$container = Mockery::mock(Container::class);
|
||||
ApplicationContext::setContainer($container);
|
||||
|
||||
$container->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config);
|
||||
$container->shouldReceive('make')->with(Channel::class, Mockery::any())->andReturnUsing(function ($class, $args) {
|
||||
return new Channel($args['size']);
|
||||
@ -200,7 +238,6 @@ class RedisMetaGeneratorTest extends TestCase
|
||||
return new RedisProxy($factory, $args['pool']);
|
||||
});
|
||||
|
||||
ApplicationContext::setContainer($container);
|
||||
return $container;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user