Skip to content

Commit

Permalink
feat: coroutine统一化实现
Browse files Browse the repository at this point in the history
  • Loading branch information
chaz6chez committed Sep 30, 2024
1 parent 27eb5fb commit 615a236
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 0 deletions.
72 changes: 72 additions & 0 deletions src/Utils/Coroutine/Coroutine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/**
* @author workbunny/Chaz6chez
* @email [email protected]
*/
declare(strict_types=1);

namespace Workbunny\WebmanCoroutine\Utils\Coroutine;

use Workbunny\WebmanCoroutine\Factory;
use Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers\CoroutineInterface;
use Workbunny\WebmanCoroutine\Utils\RegisterMethods;
use Workbunny\WebmanCoroutine\Utils\WaitGroup\Handlers\DefaultWaitGroup;
use Workbunny\WebmanCoroutine\Utils\WaitGroup\Handlers\RippleWaitGroup;
use Workbunny\WebmanCoroutine\Utils\WaitGroup\Handlers\SwooleWaitGroup;
use Workbunny\WebmanCoroutine\Utils\WaitGroup\Handlers\SwowWaitGroup;

class Coroutine
{
use RegisterMethods;

/**
* @var CoroutineInterface
*/
protected CoroutineInterface $_interface;

/**
* @var string[]
*/
protected static array $_handlers = [
Factory::WORKERMAN_SWOW => SwowWaitGroup::class,
Factory::WORKBUNNY_SWOW => SwowWaitGroup::class,
Factory::WORKERMAN_SWOOLE => SwooleWaitGroup::class,
Factory::WORKBUNNY_SWOOLE => SwooleWaitGroup::class,
Factory::RIPPLE_FIBER => RippleWaitGroup::class,
];

/**
* 构造方法
*/
public function __construct()
{
$this->_interface = new (self::$_handlers[Factory::getCurrentEventLoop()] ?? DefaultWaitGroup::class)();
}

/** @inheritdoc */
public static function registerVerify(mixed $value): false|string
{
return is_a($value, CoroutineInterface::class) ? CoroutineInterface::class : false;
}

/** @inheritdoc */
public static function unregisterExecute(string $key): bool
{
return true;
}

/**
* 代理调用WaitGroupInterface方法
*
* @param string $name
* @param array $arguments
* @return mixed
*/
public function __call(string $name, array $arguments): mixed
{
if (!method_exists($this->_interface, $name)) {
throw new \BadMethodCallException("Method $name not exists. ");
}
return $this->_interface->$name(...$arguments);
}
}
37 changes: 37 additions & 0 deletions src/Utils/Coroutine/Handlers/CoroutineInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* @author workbunny/Chaz6chez
* @email [email protected]
*/
declare(strict_types=1);

namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers;

interface CoroutineInterface
{
/**
* 初始化
*/
public function __construct();

/**
* 销毁
*/
public function __destruct();

/**
* 创建一个协程
*
* @param \Closure $func
* @return string 协程id
*/
public function create(\Closure $func): string;

/**
* 获取协程对象,部分实现不支持
*
* @param string $id
* @return mixed null:不存在 false:不支持
*/
public function query(string $id): mixed;
}
34 changes: 34 additions & 0 deletions src/Utils/Coroutine/Handlers/DefaultCoroutine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
/**
* @author workbunny/Chaz6chez
* @email [email protected]
*/
declare(strict_types=1);

namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers;

class DefaultCoroutine implements CoroutineInterface
{
/** @inheritdoc */
public function __construct()
{
}

/** @inheritdoc */
public function __destruct()
{
}

/** @inheritdoc */
public function create(\Closure $func): string
{
call_user_func($func);
return 'coroutine_id';
}

/** @inheritdoc */
public function query(string $id): bool
{
return false;
}
}
45 changes: 45 additions & 0 deletions src/Utils/Coroutine/Handlers/RippleCoroutine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* @author workbunny/Chaz6chez
* @email [email protected]
*/
declare(strict_types=1);

namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers;

class RippleCoroutine implements CoroutineInterface
{
/**
* @var array
*/
protected array $_promise;

/** @inheritdoc */
public function __construct()
{
$this->_promise = [];
}

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

/** @inheritdoc */
public function create(\Closure $func): string
{
$promise = \Co\async(function () use (&$promise, $func) {
call_user_func($func);
// 移除协程id及promise
unset($this->_promise[spl_object_hash($promise)]);
});
return spl_object_hash($promise);
}

/** @inheritdoc */
public function query(string $id): mixed
{
return $this->_promise[$id] ?? null;
}
}
47 changes: 47 additions & 0 deletions src/Utils/Coroutine/Handlers/SwooleCoroutine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* @author workbunny/Chaz6chez
* @email [email protected]
*/
declare(strict_types=1);

namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers;

use Swoole\Coroutine;

class SwooleCoroutine implements CoroutineInterface
{
/**
* @var array
*/
protected array $_promise;

/** @inheritdoc */
public function __construct()
{
$this->_promise = [];
}

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

/** @inheritdoc */
public function create(\Closure $func): string
{
while (1) {
if ($coroutine = Coroutine::create($func)) {
break;
}
}
return (string)$coroutine;
}

/** @inheritdoc */
public function query(string $id): bool
{
return false;
}
}
43 changes: 43 additions & 0 deletions src/Utils/Coroutine/Handlers/SwowCoroutine.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* @author workbunny/Chaz6chez
* @email [email protected]
*/
declare(strict_types=1);

namespace Workbunny\WebmanCoroutine\Utils\Coroutine\Handlers;

use Swow\Coroutine;

class SwowCoroutine implements CoroutineInterface
{
/**
* @var array
*/
protected array $_promise;

/** @inheritdoc */
public function __construct()
{
$this->_promise = [];
}

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

/** @inheritdoc */
public function create(\Closure $func): string
{
$coroutine = Coroutine::run($func);
return (string)$coroutine->getId();
}

/** @inheritdoc */
public function query(string $id): ?Coroutine
{
return Coroutine::get((int)$id);
}
}

0 comments on commit 615a236

Please sign in to comment.