From f319a560fb53530245d48ddf3f561501608b83de Mon Sep 17 00:00:00 2001 From: chaz6chez Date: Fri, 25 Oct 2024 19:06:37 +0800 Subject: [PATCH] =?UTF-8?q?SwooleWaitGroup=E4=BD=BF=E7=94=A8=E9=BB=98?= =?UTF-8?q?=E8=AE=A4waitGroup=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WaitGroup/Handlers/SwooleWaitGroup.php | 31 +++----- .../Handlers/SwooleWaitGroup.php.backup | 35 +++++--- .../WaitGroup/SwooleWaitGroupTest.php | 79 ++++++++++++++++--- 3 files changed, 104 insertions(+), 41 deletions(-) diff --git a/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php b/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php index 3fa58f9..0e277d1 100644 --- a/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php +++ b/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php @@ -7,15 +7,17 @@ namespace Workbunny\WebmanCoroutine\Utils\WaitGroup\Handlers; +use Swoole\Coroutine\WaitGroup; + class SwooleWaitGroup implements WaitGroupInterface { - /** @var int */ - protected int $_count; + /** @var WaitGroup */ + protected WaitGroup $_waitGroup; /** @inheritdoc */ public function __construct() { - $this->_count = 0; + $this->_waitGroup = new WaitGroup(); } /** @inheritdoc */ @@ -28,45 +30,32 @@ public function __destruct() $this->done(); } } - } finally { - $this->_count = 0; - } + } catch (\Throwable) {} } /** @inheritdoc */ public function add(int $delta = 1): bool { - $this->_count++; - + $this->_waitGroup->add($delta); return true; } /** @inheritdoc */ public function done(): bool { - $this->_count--; - + $this->_waitGroup->done(); return true; } /** @inheritdoc */ public function count(): int { - return $this->_count; + return $this->_waitGroup->count(); } /** @inheritdoc */ public function wait(int|float $timeout = -1): void { - $time = microtime(true); - while (1) { - if ($timeout > 0 and microtime(true) - $time >= $timeout) { - return; - } - if ($this->_count <= 0) { - return; - } - usleep(max((int) ($timeout * 1000 * 1000), 0)); - } + $this->_waitGroup->wait(max($timeout, $timeout > 0 ? 0.001 : -1)); } } diff --git a/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php.backup b/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php.backup index 4cb66b9..ea01709 100644 --- a/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php.backup +++ b/src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php.backup @@ -7,17 +7,15 @@ declare(strict_types=1); namespace Workbunny\WebmanCoroutine\Utils\WaitGroup\Handlers; -use Swoole\Coroutine\WaitGroup; - class SwooleWaitGroup implements WaitGroupInterface { - /** @var WaitGroup */ - protected WaitGroup $_waitGroup; + /** @var int */ + protected int $_count; /** @inheritdoc */ public function __construct() { - $this->_waitGroup = new WaitGroup(); + $this->_count = 0; } /** @inheritdoc */ @@ -30,32 +28,47 @@ class SwooleWaitGroup implements WaitGroupInterface $this->done(); } } - } catch (\Throwable) {} + } finally { + $this->_count = 0; + } } /** @inheritdoc */ public function add(int $delta = 1): bool { - $this->_waitGroup->add($delta); + $this->_count++; + return true; } /** @inheritdoc */ public function done(): bool { - $this->_waitGroup->done(); + $this->_count--; + return true; } /** @inheritdoc */ public function count(): int { - return $this->_waitGroup->count(); + return $this->_count; } /** @inheritdoc */ - public function wait(int $timeout = -1): void + public function wait(int|float $timeout = -1): void { - $this->_waitGroup->wait($timeout > 0 ? (int)($timeout * 1000) : $timeout); + $starTime = microtime(true); + $endTime = $starTime + max($timeout, 0); + while (1) { + $now = microtime(true); + if ($endTime !== $starTime and $now >= $endTime) { + return; + } + if ($this->_count <= 0) { + return; + } + usleep(0); + } } } diff --git a/tests/UtilsCase/WaitGroup/SwooleWaitGroupTest.php b/tests/UtilsCase/WaitGroup/SwooleWaitGroupTest.php index 970bd6e..56bbbca 100644 --- a/tests/UtilsCase/WaitGroup/SwooleWaitGroupTest.php +++ b/tests/UtilsCase/WaitGroup/SwooleWaitGroupTest.php @@ -10,22 +10,58 @@ class SwooleWaitGroupTest extends TestCase { + protected int $_count = 0; protected function tearDown(): void { parent::tearDown(); Mockery::close(); + $this->_count = 0; } public function testAdd() { + $swooleMock = Mockery::mock('alias:Swoole\Coroutine\WaitGroup'); + $swooleMock->shouldReceive('add')->with(1)->andReturnUsing(function ($delta) { + // 模拟增加计数 + $this->_count += $delta; + }); + $swooleMock->shouldReceive('count')->andReturnUsing(function () { + // 模拟增加计数 + return $this->_count; + }); + $wg = new SwooleWaitGroup(); + $reflection = new \ReflectionClass($wg); + $property = $reflection->getProperty('_waitGroup'); + $property->setAccessible(true); + $property->setValue($wg, $swooleMock); + $this->assertTrue($wg->add()); $this->assertEquals(1, $wg->count()); } public function testDone() { + $swooleMock = Mockery::mock('alias:Swoole\Coroutine\WaitGroup'); + $swooleMock->shouldReceive('add')->with(1)->andReturnUsing(function ($delta) { + // 模拟增加计数 + $this->_count += $delta; + }); + $swooleMock->shouldReceive('done')->andReturnUsing(function () { + // 模拟减少计数 + $this->_count--; + }); + $swooleMock->shouldReceive('count')->andReturnUsing(function () { + // 模拟增加计数 + return $this->_count; + }); + $wg = new SwooleWaitGroup(); + $reflection = new \ReflectionClass($wg); + $property = $reflection->getProperty('_waitGroup'); + $property->setAccessible(true); + $property->setValue($wg, $swooleMock); + $wg->add(); $this->assertTrue($wg->done()); $this->assertEquals(0, $wg->count()); @@ -33,7 +69,21 @@ public function testDone() public function testCount() { + $swooleMock = Mockery::mock('alias:Swoole\Coroutine\WaitGroup'); + $swooleMock->shouldReceive('add')->with(1)->andReturnUsing(function ($delta) { + // 模拟增加计数 + $this->_count += $delta; + }); + $swooleMock->shouldReceive('count')->andReturnUsing(function () { + // 模拟增加计数 + return $this->_count; + }); $wg = new SwooleWaitGroup(); + $reflection = new \ReflectionClass($wg); + $property = $reflection->getProperty('_waitGroup'); + $property->setAccessible(true); + $property->setValue($wg, $swooleMock); + $this->assertEquals(0, $wg->count()); $wg->add(); $this->assertEquals(1, $wg->count()); @@ -41,19 +91,30 @@ public function testCount() public function testWait() { - $wg = new SwooleWaitGroup(); - $wg->add(); + $swooleMock = Mockery::mock('alias:Swoole\Coroutine\WaitGroup'); + $swooleMock->shouldReceive('add')->with(1)->andReturnUsing(function ($delta) { + // 模拟增加计数 + $this->_count += $delta; + }); + $swooleMock->shouldReceive('done')->andReturnUsing(function () { + // 模拟减少计数 + $this->_count--; + }); + $swooleMock->shouldReceive('count')->andReturnUsing(function () { + // 模拟增加计数 + return $this->_count; + }); + $swooleMock->shouldReceive('wait')->with(-1)->andReturnNull(); - // 使用 Mockery 模拟 sleep() - $coMock = Mockery::mock('alias:sleep'); - $coMock->shouldReceive('sleep')->andReturnNull(); + $wg = new SwooleWaitGroup(); + $reflection = new \ReflectionClass($wg); + $property = $reflection->getProperty('_waitGroup'); + $property->setAccessible(true); + $property->setValue($wg, $swooleMock); + $wg->add(); $wg->done(); $wg->wait(); $this->assertEquals(0, $wg->count()); - - $wg->add(); - $wg->wait(1); - $this->assertEquals(1, $wg->count()); } }