Skip to content

Commit

Permalink
SwooleWaitGroup使用默认waitGroup实现
Browse files Browse the repository at this point in the history
  • Loading branch information
chaz6chez committed Oct 25, 2024
1 parent 032a612 commit f319a56
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 41 deletions.
31 changes: 10 additions & 21 deletions src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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));
}
}
35 changes: 24 additions & 11 deletions src/Utils/WaitGroup/Handlers/SwooleWaitGroup.php.backup
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
}
}
}
79 changes: 70 additions & 9 deletions tests/UtilsCase/WaitGroup/SwooleWaitGroupTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,111 @@

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

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

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

0 comments on commit f319a56

Please sign in to comment.