Skip to content

Commit

Permalink
Merge pull request #19 from cclilshy/main
Browse files Browse the repository at this point in the history
Update: adjust for ripple compatibility
  • Loading branch information
chaz6chez authored Oct 14, 2024
2 parents 839ece9 + da8a5c1 commit 628bc93
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 25 deletions.
47 changes: 28 additions & 19 deletions src/Utils/Coroutine/Handlers/RippleCoroutine.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,66 @@

namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers;

use function Co\async;

use Closure;
use Psc\Core\Coroutine\Promise;
use Revolt\EventLoop\Suspension;

class RippleCoroutine implements CoroutineInterface
{
/**
* @var null|Promise
* @var \Revolt\EventLoop\Suspension
*/
protected ?Promise $_promise = null;
protected Suspension $suspension;

/** @inheritdoc
* @param \Closure $func
*/
public function __construct(\Closure $func)
public function __construct(Closure $func)
{
$this->_promise = $promise = $this->_async(function () use (&$promise, $func) {
$this->_async(function (Closure $resolve, Closure $reject) use ($func) {
$this->suspension = \Co\getSuspension();

try {
call_user_func($func, spl_object_hash($this->_promise));
$result = call_user_func(
$func,
spl_object_hash($this->origin())
);

$resolve($result);
} catch (\Throwable $exception) {
$reject($exception);
} finally {
// 移除协程promise
$this->_promise = null;
unset($this->promise);
}
});
}

/** @inheritdoc */
/** @inheritdoc */
public function __destruct()
{
$this->_promise = null;
}

/** @inheritdoc */
public function origin(): ?Promise
/** @inheritdoc */
public function origin(): Suspension
{
return $this->_promise;
return $this->suspension;
}

/** @inheritdoc */
/** @inheritdoc */
public function id(): ?string
{
return $this->_promise ? spl_object_hash($this->_promise) : null;
return spl_object_hash($this->origin());
}

/**
* @codeCoverageIgnore 用于测试mock,忽略覆盖
*
* @param \Closure $closure
* @return mixed
*
* @return \Psc\Core\Coroutine\Promise
*/
protected function _async(\Closure $closure)
protected function _async(Closure $closure): Promise
{
return async($closure);
return \Co\async($closure);
}
}
12 changes: 6 additions & 6 deletions tests/UtilsCase/Coroutine/RippleCoroutineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function testConstruct()

// mock async
$callback = null;
$promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise');
$promiseMock = Mockery::mock('Revolt\EventLoop\Suspension');
$coroutine = Mockery::mock(RippleCoroutine::class)->makePartial();
$coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async')
->andReturnUsing(function ($closure) use (&$callback, $promiseMock) {
Expand All @@ -40,7 +40,7 @@ public function testConstruct()
$constructor->invoke($coroutine, $func);

$this->assertFalse($executed);
$this->assertInstanceOf('Psc\Core\Coroutine\Promise', $coroutine->origin());
$this->assertInstanceOf('Revolt\EventLoop\Suspension', $coroutine->origin());
$this->assertIsString($getId = $coroutine->id());
$this->assertEquals(spl_object_hash($promiseMock), $coroutine->id());
$this->assertNull($id);
Expand All @@ -63,7 +63,7 @@ public function testDestruct()

// mock async
$callback = null;
$promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise');
$promiseMock = Mockery::mock('Revolt\EventLoop\Suspension');
$coroutine = Mockery::mock(RippleCoroutine::class)->makePartial();
$coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async')
->andReturnUsing(function ($closure) use (&$callback, $promiseMock) {
Expand Down Expand Up @@ -91,7 +91,7 @@ public function testOrigin()
};
// mock async
$callback = null;
$promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise');
$promiseMock = Mockery::mock('Revolt\EventLoop\Suspension');
$coroutine = Mockery::mock(RippleCoroutine::class)->makePartial();
$coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async')
->andReturnUsing(function ($closure) use (&$callback, $promiseMock) {
Expand All @@ -103,7 +103,7 @@ public function testOrigin()
$constructor = new \ReflectionMethod(RippleCoroutine::class, '__construct');
$constructor->invoke($coroutine, $func);

$this->assertInstanceOf('Psc\Core\Coroutine\Promise', $coroutine->origin());
$this->assertInstanceOf('Revolt\EventLoop\Suspension', $coroutine->origin());
// 模拟构造后协程执行callback
call_user_func($callback);

Expand All @@ -117,7 +117,7 @@ public function testId()
};
// mock async
$callback = null;
$promiseMock = Mockery::mock('Psc\Core\Coroutine\Promise');
$promiseMock = Mockery::mock('Revolt\EventLoop\Suspension');
$coroutine = Mockery::mock(RippleCoroutine::class)->makePartial();
$coroutine->shouldAllowMockingProtectedMethods()->shouldReceive('_async')
->andReturnUsing(function ($closure) use (&$callback, $promiseMock) {
Expand Down

0 comments on commit 628bc93

Please sign in to comment.