Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| daa89f3794 | |||
| 60670f7f97 | |||
| 3a0c5f6d70 | |||
| ef312c2aa4 | |||
| a0eb46cf4e | |||
| fbd3799081 | |||
| 97a3335217 | |||
| 1790d01730 | |||
| 8a4b62b2d8 | |||
| 526256302d | |||
| 95254ac300 | |||
| fdf7757b6a | |||
| 6e4a045c7d | |||
| 03d16d8157 | |||
| c8041cc09e | |||
| 976f67a838 | |||
| c7e0cd4948 | |||
| 3fc1b16f33 | |||
| 103b757a05 | |||
| b52270ff25 | |||
| c0aa9acb19 |
+9
-6
@@ -4,6 +4,7 @@ defined('APP_PATH') or define('APP_PATH', realpath(__DIR__ . '/../../'));
|
|||||||
|
|
||||||
|
|
||||||
use JetBrains\PhpStorm\Pure;
|
use JetBrains\PhpStorm\Pure;
|
||||||
|
use Kiri\Abstracts\Kernel;
|
||||||
use Kiri\Application;
|
use Kiri\Application;
|
||||||
use Kiri\Config\ConfigProvider;
|
use Kiri\Config\ConfigProvider;
|
||||||
use Kiri\Core\ArrayAccess;
|
use Kiri\Core\ArrayAccess;
|
||||||
@@ -28,16 +29,16 @@ interface Arrayable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!function_exists('json_validator')) {
|
if (!function_exists('json_validate')) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $data
|
* @param string $data
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function json_validator(string $data): bool
|
function json_validate(string $data): bool
|
||||||
{
|
{
|
||||||
return is_null(json_decode($data));
|
return is_array(json_decode($data, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -46,12 +47,14 @@ if (!function_exists('json_validator')) {
|
|||||||
if (!function_exists('application')) {
|
if (!function_exists('application')) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param Kernel $Kernel
|
||||||
* @return Application
|
* @return Application
|
||||||
* @throws
|
|
||||||
*/
|
*/
|
||||||
function application(): Application
|
function application(Kernel $Kernel): Application
|
||||||
{
|
{
|
||||||
return Kiri::getDi()->get(Application::class);
|
$application = Kiri::getDi()->get(Application::class);
|
||||||
|
$application->commands($Kernel);
|
||||||
|
return $application;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Kiri\Actor;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use JsonSerializable;
|
|
||||||
use Swoole\Coroutine;
|
|
||||||
use Swoole\Coroutine\Channel;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Actor
|
|
||||||
*/
|
|
||||||
abstract class Actor implements ActorInterface, JsonSerializable
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Channel
|
|
||||||
*/
|
|
||||||
private Channel $channel;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private bool $isShutdown = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private int $messageId = -1;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private int $coroutineId = -1;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ActorState
|
|
||||||
*/
|
|
||||||
private ActorState $state;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var float
|
|
||||||
*/
|
|
||||||
private float $startTime = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private int $refreshInterval = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return ActorState
|
|
||||||
*/
|
|
||||||
public function getState(): ActorState
|
|
||||||
{
|
|
||||||
return $this->state;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ActorState $state
|
|
||||||
*/
|
|
||||||
public function setState(ActorState $state): void
|
|
||||||
{
|
|
||||||
$this->state = $state;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function getRunTime(): float
|
|
||||||
{
|
|
||||||
return microtime(true) - $this->startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $uniqueId
|
|
||||||
*/
|
|
||||||
private function __construct(readonly public string $uniqueId)
|
|
||||||
{
|
|
||||||
$this->channel = new Channel(99);
|
|
||||||
$this->startTime = microtime(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function init(): void
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isShutdown(): bool
|
|
||||||
{
|
|
||||||
return $this->isShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $id
|
|
||||||
* @return static
|
|
||||||
*/
|
|
||||||
public static function newActor($id): static
|
|
||||||
{
|
|
||||||
$actor = new static($id);
|
|
||||||
$actor->listen();
|
|
||||||
return $actor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function listen(): void
|
|
||||||
{
|
|
||||||
Coroutine::create(function (Actor $actor) {
|
|
||||||
$actor->coroutineId = Coroutine::getCid();
|
|
||||||
$this->run();
|
|
||||||
}, $this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName(): string
|
|
||||||
{
|
|
||||||
return $this->uniqueId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $response
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function write(mixed $response): bool
|
|
||||||
{
|
|
||||||
return $this->channel->push($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function shutdown(): void
|
|
||||||
{
|
|
||||||
$this->isShutdown = true;
|
|
||||||
Coroutine::cancel($this->coroutineId);
|
|
||||||
if ($this->messageId > -1) {
|
|
||||||
Coroutine::cancel($this->messageId);
|
|
||||||
}
|
|
||||||
$this->channel->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function onUpdate(): void
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function run(): void
|
|
||||||
{
|
|
||||||
if ($this->refreshInterval < 1) {
|
|
||||||
throw new Exception('Refresh interval must be greater than 1');
|
|
||||||
}
|
|
||||||
$this->setState(ActorState::BUSY);
|
|
||||||
$this->init();
|
|
||||||
$this->messageId = Coroutine::create(fn() => $this->loop());
|
|
||||||
$this->interval();
|
|
||||||
$this->setState(ActorState::IDLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function interval(): void
|
|
||||||
{
|
|
||||||
if ($this->isShutdown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->onUpdate();
|
|
||||||
} catch (\Throwable $exception) {
|
|
||||||
error($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
Coroutine::sleep($this->refreshInterval / 1000);
|
|
||||||
|
|
||||||
$this->interval();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function loop(): bool
|
|
||||||
{
|
|
||||||
if ($this->messageId == -1) {
|
|
||||||
$this->messageId = Coroutine::getCid();
|
|
||||||
}
|
|
||||||
if ($this->channel->errCode == SWOOLE_CHANNEL_CLOSED) {
|
|
||||||
$this->channel = new Channel(99);
|
|
||||||
}
|
|
||||||
$message = $this->channel->pop();
|
|
||||||
$this->process($message);
|
|
||||||
if ($this->isShutdown()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return $this->loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Kiri\Actor;
|
|
||||||
|
|
||||||
interface ActorInterface
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ActorMessage $message
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function process(ActorMessage $message): void;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Kiri\Actor;
|
|
||||||
|
|
||||||
use Swoole\Coroutine;
|
|
||||||
|
|
||||||
class ActorManager
|
|
||||||
{
|
|
||||||
|
|
||||||
/** @var array<string, ActorInterface> */
|
|
||||||
private array $nodes = [];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Actor $actor
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function addActor(ActorInterface $actor): void
|
|
||||||
{
|
|
||||||
$this->nodes[$actor->uniqueId] = $actor;
|
|
||||||
Coroutine::create(function (Actor $actor) {
|
|
||||||
$actor->run();
|
|
||||||
}, $actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $name
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function closeActor($name): void
|
|
||||||
{
|
|
||||||
$node = $this->nodes[$name] ?? null;
|
|
||||||
if (is_null($node)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach ($node as $actor) {
|
|
||||||
$actor->shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $name
|
|
||||||
* @param $message
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function write($name, $message): bool
|
|
||||||
{
|
|
||||||
$actor = $this->nodes[$name] ?? null;
|
|
||||||
if (is_null($actor)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return $actor->write($message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $name
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function lists($name): array
|
|
||||||
{
|
|
||||||
$array = [];
|
|
||||||
foreach ($this->nodes[$name] as $actor) {
|
|
||||||
$array[] = [
|
|
||||||
'id' => $actor->getName(),
|
|
||||||
'state' => $actor->getState()->name,
|
|
||||||
'runTime' => $actor->getRunTime()
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $uniqueId
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasActor(string $uniqueId): bool
|
|
||||||
{
|
|
||||||
return isset($this->nodes[$uniqueId]) && $this->nodes[$uniqueId] instanceof ActorInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array|null $data
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function exec(?array $data): void
|
|
||||||
{
|
|
||||||
if (is_null($data)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function clean(): void
|
|
||||||
{
|
|
||||||
foreach ($this->nodes as $actor) {
|
|
||||||
$actor->shutdown();
|
|
||||||
}
|
|
||||||
$this->nodes = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Kiri\Actor;
|
|
||||||
|
|
||||||
use JetBrains\PhpStorm\ArrayShape;
|
|
||||||
|
|
||||||
class ActorMessage implements \JsonSerializable
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private int $userId;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private string $event;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private array $body;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $userId
|
|
||||||
* @param string $event
|
|
||||||
* @param array $body
|
|
||||||
*/
|
|
||||||
public function __construct(int $userId, string $event, array $body)
|
|
||||||
{
|
|
||||||
$this->userId = $userId;
|
|
||||||
$this->event = $event;
|
|
||||||
$this->body = $body;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId(): int
|
|
||||||
{
|
|
||||||
return $this->userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getEvent(): string
|
|
||||||
{
|
|
||||||
return $this->event;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getBody(): array
|
|
||||||
{
|
|
||||||
return $this->body;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
#[ArrayShape(['userId' => "int", 'event' => "string", 'body' => "array"])]
|
|
||||||
public function jsonSerialize(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'userId' => $this->userId,
|
|
||||||
'event' => $this->event,
|
|
||||||
'body' => $this->body
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Kiri\Actor;
|
|
||||||
|
|
||||||
use Kiri\Server\Abstracts\BaseProcess;
|
|
||||||
use Swoole\Coroutine;
|
|
||||||
use Swoole\Process;
|
|
||||||
|
|
||||||
class ActorProcess extends BaseProcess
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
protected bool $enable_coroutine = true;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName(): string
|
|
||||||
{
|
|
||||||
// TODO: Change the autogenerated stub
|
|
||||||
return '[' . \config('id', 'system-service') . '].Actor Manager';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function process(?Process $process): void
|
|
||||||
{
|
|
||||||
// TODO: Implement process() method.
|
|
||||||
while ($this->isStop() === false) {
|
|
||||||
$read = $process->read();
|
|
||||||
|
|
||||||
ActorManager::exec(json_decode($read, true));
|
|
||||||
|
|
||||||
Coroutine::sleep(1000 / 120);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function onSigterm(): static
|
|
||||||
{
|
|
||||||
// TODO: Implement onSigterm() method.
|
|
||||||
Coroutine::create(function () {
|
|
||||||
$sign = Coroutine::waitSignal(SIGINT | SIGTERM);
|
|
||||||
if ($sign) {
|
|
||||||
$this->onShutdown(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Kiri\Actor;
|
|
||||||
|
|
||||||
enum ActorState
|
|
||||||
{
|
|
||||||
case IDLE;
|
|
||||||
case BUSY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
case CREATE;
|
|
||||||
case MESSAGE;
|
|
||||||
case SHUTDOWN;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -14,11 +14,16 @@ use Exception;
|
|||||||
use JetBrains\PhpStorm\Pure;
|
use JetBrains\PhpStorm\Pure;
|
||||||
use Kiri;
|
use Kiri;
|
||||||
use Kiri\Error\StdoutLogger;
|
use Kiri\Error\StdoutLogger;
|
||||||
use ReflectionException;
|
use Kiri\Events\EventDispatch;
|
||||||
|
use Kiri\Events\EventProvider;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Component
|
* Class Component
|
||||||
* @package Kiri\Base
|
* @package Kiri\Base
|
||||||
|
* @property ContainerInterface $container
|
||||||
|
* @property EventDispatch $dispatch
|
||||||
|
* @property EventProvider $provider
|
||||||
*/
|
*/
|
||||||
class Component implements Configure
|
class Component implements Configure
|
||||||
{
|
{
|
||||||
@@ -96,4 +101,29 @@ class Component implements Configure
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return EventDispatch
|
||||||
|
*/
|
||||||
|
public function getDispatch(): EventDispatch
|
||||||
|
{
|
||||||
|
return Kiri::getDi()->get(EventDispatch::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return EventProvider
|
||||||
|
*/
|
||||||
|
public function getProvider(): EventProvider
|
||||||
|
{
|
||||||
|
return Kiri::getDi()->get(EventProvider::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ContainerInterface
|
||||||
|
*/
|
||||||
|
public function getContainer(): ContainerInterface
|
||||||
|
{
|
||||||
|
return Kiri::getDi();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,24 +4,11 @@ declare(strict_types=1);
|
|||||||
namespace Kiri\Abstracts;
|
namespace Kiri\Abstracts;
|
||||||
|
|
||||||
|
|
||||||
use Kiri;
|
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Providers
|
* Class Providers
|
||||||
* @package Kiri\Abstracts
|
* @package Kiri\Abstracts
|
||||||
* @property-read ContainerInterface $container
|
|
||||||
*/
|
*/
|
||||||
abstract class Providers extends Component implements Provider
|
abstract class Providers extends Component implements Provider
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return ContainerInterface
|
|
||||||
*/
|
|
||||||
public function getContainer(): ContainerInterface
|
|
||||||
{
|
|
||||||
return Kiri::getDi();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,12 @@ declare(strict_types=1);
|
|||||||
namespace Kiri;
|
namespace Kiri;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Kiri;
|
use Kiri;
|
||||||
use Kiri\Abstracts\{BaseApplication, Kernel};
|
use Kiri\Abstracts\{BaseApplication, Kernel};
|
||||||
use Kiri\Di\Scanner;
|
use Kiri\Di\Scanner;
|
||||||
use Kiri\Error\ErrorHandler;
|
use Kiri\Error\ErrorHandler;
|
||||||
use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute};
|
use Kiri\Events\{OnAfterCommandExecute, OnBeforeCommandExecute};
|
||||||
use Psr\Container\ContainerExceptionInterface;
|
|
||||||
use Psr\Container\NotFoundExceptionInterface;
|
|
||||||
use ReflectionException;
|
|
||||||
use Symfony\Component\Console\{Application as ConsoleApplication,
|
use Symfony\Component\Console\{Application as ConsoleApplication,
|
||||||
Exception\ExceptionInterface,
|
|
||||||
Input\ArgvInput,
|
Input\ArgvInput,
|
||||||
Output\ConsoleOutput,
|
Output\ConsoleOutput,
|
||||||
Output\OutputInterface
|
Output\OutputInterface
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class Coordinator
|
|||||||
|
|
||||||
const string WORKER_START = 'worker:start';
|
const string WORKER_START = 'worker:start';
|
||||||
|
|
||||||
private bool $waite = false;
|
private bool $waite = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,10 +17,9 @@ class Coordinator
|
|||||||
*/
|
*/
|
||||||
public function yield(): void
|
public function yield(): void
|
||||||
{
|
{
|
||||||
if ($this->waite === false) {
|
while ($this->waite) {
|
||||||
return;
|
usleep(1000);
|
||||||
}
|
}
|
||||||
$this->yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,13 +34,6 @@ class ErrorHandler extends Component implements ErrorInterface
|
|||||||
public string $category = 'app';
|
public string $category = 'app';
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ContainerInterface
|
|
||||||
*/
|
|
||||||
#[Container(ContainerInterface::class)]
|
|
||||||
public ContainerInterface $container;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array|Closure|null $callback
|
* @param array|Closure|null $callback
|
||||||
* @return void
|
* @return void
|
||||||
@@ -51,7 +44,7 @@ class ErrorHandler extends Component implements ErrorInterface
|
|||||||
if (empty($callback)) {
|
if (empty($callback)) {
|
||||||
$callback = [$this, 'exceptionHandler'];
|
$callback = [$this, 'exceptionHandler'];
|
||||||
} else if (is_array($callback) && is_string($callback[0])) {
|
} else if (is_array($callback) && is_string($callback[0])) {
|
||||||
$callback[0] = $this->container->get($callback[0]);
|
$callback[0] = \Kiri::getDi()->get($callback[0]);
|
||||||
}
|
}
|
||||||
set_exception_handler($callback);
|
set_exception_handler($callback);
|
||||||
}
|
}
|
||||||
@@ -67,7 +60,7 @@ class ErrorHandler extends Component implements ErrorInterface
|
|||||||
if (empty($callback)) {
|
if (empty($callback)) {
|
||||||
$callback = [$this, 'errorHandler'];
|
$callback = [$this, 'errorHandler'];
|
||||||
} else if (is_array($callback) && is_string($callback[0])) {
|
} else if (is_array($callback) && is_string($callback[0])) {
|
||||||
$callback[0] = $this->container->get($callback[0]);
|
$callback[0] = \Kiri::getDi()->get($callback[0]);
|
||||||
}
|
}
|
||||||
set_error_handler($callback);
|
set_error_handler($callback);
|
||||||
}
|
}
|
||||||
@@ -83,7 +76,7 @@ class ErrorHandler extends Component implements ErrorInterface
|
|||||||
if (empty($callback)) {
|
if (empty($callback)) {
|
||||||
$callback = [$this, 'shutdown'];
|
$callback = [$this, 'shutdown'];
|
||||||
} else if (is_array($callback) && is_string($callback[0])) {
|
} else if (is_array($callback) && is_string($callback[0])) {
|
||||||
$callback[0] = $this->container->get($callback[0]);
|
$callback[0] = \Kiri::getDi()->get($callback[0]);
|
||||||
}
|
}
|
||||||
register_shutdown_function($callback);
|
register_shutdown_function($callback);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,16 @@ class StdoutLogger extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $message
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function println(string $message): void
|
||||||
|
{
|
||||||
|
file_put_contents('php://output', '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL, FILE_APPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param array $arguments
|
* @param array $arguments
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use Kiri;
|
|||||||
use Kiri\Exception\RedisConnectException;
|
use Kiri\Exception\RedisConnectException;
|
||||||
use Kiri\Pool\Pool;
|
use Kiri\Pool\Pool;
|
||||||
use RedisException;
|
use RedisException;
|
||||||
|
use wchat\common\Result;
|
||||||
use function config;
|
use function config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,7 +134,7 @@ SCRIPT;
|
|||||||
*/
|
*/
|
||||||
public function destroy(): void
|
public function destroy(): void
|
||||||
{
|
{
|
||||||
$this->pool()->close($this->host);
|
$this->pool()->close($this->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ SCRIPT;
|
|||||||
return trigger_print_error(throwable($throwable));
|
return trigger_print_error(throwable($throwable));
|
||||||
} finally {
|
} finally {
|
||||||
if ($client->ping('h') == 'h') {
|
if ($client->ping('h') == 'h') {
|
||||||
$this->pool()->push($this->host, $client);
|
$this->pool()->push($this->getName(), $client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +165,7 @@ SCRIPT;
|
|||||||
*/
|
*/
|
||||||
private function getClient(): \Redis
|
private function getClient(): \Redis
|
||||||
{
|
{
|
||||||
return $this->pool()->get($this->host);
|
return $this->pool()->get($this->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -175,13 +176,22 @@ SCRIPT;
|
|||||||
protected function pool(): Pool
|
protected function pool(): Pool
|
||||||
{
|
{
|
||||||
$pool = Kiri::getPool();
|
$pool = Kiri::getPool();
|
||||||
if (!$pool->hasChannel($this->host)) {
|
if (!$pool->hasChannel($this->getName())) {
|
||||||
$pool->created($this->host, $this->pool['max'], [$this, 'connect']);
|
$pool->created($this->getName(), $this->pool['max'], [$this, 'connect']);
|
||||||
}
|
}
|
||||||
return $pool;
|
return $pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getName(): string
|
||||||
|
{
|
||||||
|
return 'redis.' . $this->host;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Redis
|
* @return \Redis
|
||||||
* @throws
|
* @throws
|
||||||
|
|||||||
@@ -1 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
use Swoole\Timer;
|
||||||
|
use Swoole\WebSocket\Server;
|
||||||
|
|
||||||
|
$client = new Server("0.0.0.0", 9511);
|
||||||
|
$client->addProcess(new Swoole\Process(function (\Swoole\Process $server) use ($client) {
|
||||||
|
while (true) {
|
||||||
|
echo json_encode($client->stats(), JSON_UNESCAPED_UNICODE) . PHP_EOL;
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
$client->on('open', function (Server $server) {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$client->on('message', function (Server $server, $frame) {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$client->on('close', function (Server $server, $fd) {
|
||||||
|
|
||||||
|
});
|
||||||
|
$client->start();
|
||||||
@@ -1 +1,51 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
ini_set('memory_limit','64GB');
|
||||||
|
|
||||||
|
use Swoole\Coroutine;
|
||||||
|
use Swoole\Coroutine\Http\Client;
|
||||||
|
use function Swoole\Coroutine\run;
|
||||||
|
|
||||||
|
function faker($page = 0)
|
||||||
|
{
|
||||||
|
$client = new Client('openapi.stupideyes.com', 443, true);
|
||||||
|
$client->get('/faker?offset=' . $page);
|
||||||
|
$client->close();
|
||||||
|
|
||||||
|
return json_decode($client->getBody(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
run(function () {
|
||||||
|
$offset = 1;
|
||||||
|
|
||||||
|
$success = 0;
|
||||||
|
for ($i = 1; $i <= 10000; $i++) {
|
||||||
|
$faker = faker($offset);
|
||||||
|
$offset++;
|
||||||
|
go(function () use ($faker, $offset, &$success) {
|
||||||
|
$socket = new Swoole\Coroutine\Http\Client('43.248.128.57', 14101);
|
||||||
|
$socket->upgrade("/ws?access_token=" . $faker['params']['token']);
|
||||||
|
if ($socket->connected) {
|
||||||
|
$success += 1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
$socket->recv();
|
||||||
|
// $socket->push('hello');
|
||||||
|
// var_dump($socket->recv());
|
||||||
|
|
||||||
|
Coroutine::sleep(0.1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$success -= 1;
|
||||||
|
|
||||||
|
echo 'websocket fail: ' . socket_strerror($socket->errCode) . PHP_EOL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Coroutine::sleep(0.1);
|
||||||
|
|
||||||
|
var_dump($success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user